Files
sa-lessons/modules/module9/sections/06-coding-standards-tools.md
Alexander Abakumov 15e744da49 Initial commit: Complete Software Architecture course with 11 modules
- Added comprehensive course structure with 11 modules
- Included theoretical content, practical examples, and tasks
- Multi-language code examples (Java, Rust, Node.js, Python)
- Detailed analysis of architectural approaches and trade-offs
- Complete caching strategies documentation
- Architecture examples from real-world systems (Twitter, Netflix, Uber)
- Structured navigation and learning path
- Ready for educational use
2025-09-09 22:08:07 +03:00

13 KiB

Стандарты кодирования и инструменты

Навигация


Общие принципы

1. Читаемость

  • Код должен быть понятен без комментариев
  • Использование осмысленных имен
  • Правильная структура и форматирование

2. Поддерживаемость

  • Модульная структура
  • Слабая связанность
  • Высокая когезия

3. Производительность

  • Эффективные алгоритмы
  • Оптимальное использование ресурсов
  • Профилирование и оптимизация

Стандарты кодирования

1. Именование

Java

// Классы - PascalCase
public class UserService {
    
    // Константы - UPPER_SNAKE_CASE
    private static final String DEFAULT_ROLE = "USER";
    
    // Поля - camelCase
    private String userName;
    private int userAge;
    
    // Методы - camelCase
    public void createUser(String userName, int userAge) {
        // Локальные переменные - camelCase
        String userRole = DEFAULT_ROLE;
        
        // Временные переменные - короткие имена
        for (int i = 0; i < users.size(); i++) {
            User user = users.get(i);
            processUser(user);
        }
    }
    
    // Булевы методы - is/has/can
    public boolean isUserActive() {
        return userStatus == UserStatus.ACTIVE;
    }
    
    public boolean hasPermission(String permission) {
        return userPermissions.contains(permission);
    }
}

Python

# Модули и пакеты - snake_case
import user_service
from models.user import User

# Классы - PascalCase
class UserService:
    
    # Константы - UPPER_SNAKE_CASE
    DEFAULT_ROLE = "USER"
    
    # Методы и переменные - snake_case
    def create_user(self, user_name: str, user_age: int) -> User:
        # Локальные переменные - snake_case
        user_role = self.DEFAULT_ROLE
        
        # Временные переменные - короткие имена
        for i, user in enumerate(self.users):
            self.process_user(user)
        
        return User(user_name, user_age, user_role)
    
    # Булевы методы - is/has/can
    def is_user_active(self) -> bool:
        return self.user_status == UserStatus.ACTIVE
    
    def has_permission(self, permission: str) -> bool:
        return permission in self.user_permissions

JavaScript/TypeScript

// Файлы - kebab-case
// user-service.ts

// Классы - PascalCase
class UserService {
    
    // Константы - UPPER_SNAKE_CASE
    private static readonly DEFAULT_ROLE = 'USER';
    
    // Методы и переменные - camelCase
    public createUser(userName: string, userAge: number): User {
        // Локальные переменные - camelCase
        const userRole = UserService.DEFAULT_ROLE;
        
        // Временные переменные - короткие имена
        for (let i = 0; i < this.users.length; i++) {
            const user = this.users[i];
            this.processUser(user);
        }
        
        return new User(userName, userAge, userRole);
    }
    
    // Булевы методы - is/has/can
    public isUserActive(): boolean {
        return this.userStatus === UserStatus.ACTIVE;
    }
    
    public hasPermission(permission: string): boolean {
        return this.userPermissions.includes(permission);
    }
}

2. Структура файлов

Java

src/
├── main/
│   ├── java/
│   │   └── com/
│   │       └── company/
│   │           └── project/
│   │               ├── controller/
│   │               │   └── UserController.java
│   │               ├── service/
│   │               │   └── UserService.java
│   │               ├── repository/
│   │               │   └── UserRepository.java
│   │               ├── model/
│   │               │   └── User.java
│   │               └── config/
│   │                   └── DatabaseConfig.java
│   └── resources/
│       ├── application.yml
│       └── logback-spring.xml
└── test/
    └── java/
        └── com/
            └── company/
                └── project/
                    ├── controller/
                    │   └── UserControllerTest.java
                    └── service/
                        └── UserServiceTest.java

Python

project/
├── src/
│   └── project/
│       ├── __init__.py
│       ├── controllers/
│       │   ├── __init__.py
│       │   └── user_controller.py
│       ├── services/
│       │   ├── __init__.py
│       │   └── user_service.py
│       ├── repositories/
│       │   ├── __init__.py
│       │   └── user_repository.py
│       ├── models/
│       │   ├── __init__.py
│       │   └── user.py
│       └── config/
│           ├── __init__.py
│           └── database.py
├── tests/
│   ├── __init__.py
│   ├── test_controllers/
│   │   └── test_user_controller.py
│   └── test_services/
│       └── test_user_service.py
├── requirements.txt
└── setup.py

3. Комментарии

Java

/**
 * Сервис для управления пользователями
 * 
 * @author John Doe
 * @version 1.0
 * @since 2024-01-01
 */
@Service
public class UserService {
    
    /**
     * Создает нового пользователя
     * 
     * @param userName имя пользователя
     * @param userAge возраст пользователя
     * @return созданный пользователь
     * @throws IllegalArgumentException если имя пользователя пустое
     */
    public User createUser(String userName, int userAge) {
        if (userName == null || userName.trim().isEmpty()) {
            throw new IllegalArgumentException("User name cannot be empty");
        }
        
        // Создаем пользователя с дефолтной ролью
        User user = new User(userName, userAge, DEFAULT_ROLE);
        
        // Сохраняем в базе данных
        return userRepository.save(user);
    }
    
    /**
     * Проверяет, активен ли пользователь
     * 
     * @return true если пользователь активен, false иначе
     */
    public boolean isUserActive() {
        return userStatus == UserStatus.ACTIVE;
    }
}

Python

"""
Сервис для управления пользователями

Автор: John Doe
Версия: 1.0
Дата: 2024-01-01
"""

class UserService:
    """Сервис для управления пользователями"""
    
    def create_user(self, user_name: str, user_age: int) -> User:
        """
        Создает нового пользователя
        
        Args:
            user_name: имя пользователя
            user_age: возраст пользователя
            
        Returns:
            созданный пользователь
            
        Raises:
            ValueError: если имя пользователя пустое
        """
        if not user_name or not user_name.strip():
            raise ValueError("User name cannot be empty")
        
        # Создаем пользователя с дефолтной ролью
        user = User(user_name, user_age, self.DEFAULT_ROLE)
        
        # Сохраняем в базе данных
        return self.user_repository.save(user)
    
    def is_user_active(self) -> bool:
        """
        Проверяет, активен ли пользователь
        
        Returns:
            True если пользователь активен, False иначе
        """
        return self.user_status == UserStatus.ACTIVE

Инструменты

1. Форматирование кода

Java - Spotless

// build.gradle
plugins {
    id "com.diffplug.spotless" version "6.19.0"
}

spotless {
    java {
        googleJavaFormat()
        removeUnusedImports()
        trimTrailingWhitespace()
        endWithNewline()
    }
}

Python - Black

# pyproject.toml
[tool.black]
line-length = 88
target-version = ['py38']
include = '\.pyi?$'
extend-exclude = '''
/(
  # directories
  \.eggs
  | \.git
  | \.hg
  | \.mypy_cache
  | \.tox
  | \.venv
  | build
  | dist
)/
'''

JavaScript/TypeScript - Prettier

// .prettierrc
{
  "semi": true,
  "trailingComma": "es5",
  "singleQuote": true,
  "printWidth": 80,
  "tabWidth": 2,
  "useTabs": false
}

2. Линтеры

Java - Checkstyle

<!-- checkstyle.xml -->
<?xml version="1.0"?>
<!DOCTYPE module PUBLIC
    "-//Checkstyle//DTD Checkstyle Configuration 1.3//EN"
    "https://checkstyle.org/dtds/configuration_1_3.dtd">

<module name="Checker">
    <module name="TreeWalker">
        <module name="OuterTypeFilename"/>
        <module name="IllegalTokenText">
            <property name="tokens" value="STRING_LITERAL, CHAR_LITERAL"/>
            <property name="format" value="\\u00(09|0(a|A)|0(c|C)|0(d|D)|22|27|5(C|c))"/>
            <property name="message" value="Consider using special escape sequence instead of octal value or Unicode escaped value."/>
        </module>
        <module name="AvoidEscapedUnicodeCharacters">
            <property name="allowEscapesForControlCharacters" value="true"/>
            <property name="allowByTailComment" value="true"/>
            <property name="allowNonPrintableEscapes" value="true"/>
        </module>
        <module name="AvoidStarImport"/>
        <module name="IllegalImport"/>
        <module name="RedundantImport"/>
        <module name="UnusedImports">
            <property name="processJavadoc" value="false"/>
        </module>
    </module>
</module>

Python - flake8

# .flake8
[flake8]
max-line-length = 88
extend-ignore = E203, W503
exclude =
    .git,
    __pycache__,
    .venv,
    .eggs,
    *.egg,
    build,
    dist

JavaScript/TypeScript - ESLint

// .eslintrc.json
{
  "extends": [
    "eslint:recommended",
    "@typescript-eslint/recommended"
  ],
  "parser": "@typescript-eslint/parser",
  "plugins": ["@typescript-eslint"],
  "rules": {
    "no-console": "warn",
    "no-unused-vars": "error",
    "@typescript-eslint/no-explicit-any": "warn",
    "prefer-const": "error"
  }
}

3. Type Checkers

Python - mypy

# mypy.ini
[mypy]
python_version = 3.8
warn_return_any = True
warn_unused_configs = True
disallow_untyped_defs = True
disallow_incomplete_defs = True
check_untyped_defs = True
disallow_untyped_decorators = True
no_implicit_optional = True
warn_redundant_casts = True
warn_unused_ignores = True
warn_no_return = True
warn_unreachable = True
strict_equality = True

TypeScript - tsc

// tsconfig.json
{
  "compilerOptions": {
    "target": "ES2020",
    "module": "commonjs",
    "lib": ["ES2020"],
    "outDir": "./dist",
    "rootDir": "./src",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,
    "noImplicitAny": true,
    "noImplicitReturns": true,
    "noImplicitThis": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules", "dist"]
}

4. Pre-commit Hooks

# .pre-commit-config.yaml
repos:
  - repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v4.4.0
    hooks:
      - id: trailing-whitespace
      - id: end-of-file-fixer
      - id: check-yaml
      - id: check-added-large-files

  - repo: https://github.com/psf/black
    rev: 23.3.0
    hooks:
      - id: black
        language_version: python3

  - repo: https://github.com/pycqa/flake8
    rev: 6.0.0
    hooks:
      - id: flake8

  - repo: https://github.com/pre-commit/mirrors-mypy
    rev: v1.3.0
    hooks:
      - id: mypy
        additional_dependencies: [types-requests]

  - repo: https://github.com/pre-commit/mirrors-eslint
    rev: v8.42.0
    hooks:
      - id: eslint
        files: \.(js|ts)$
        types: [file]

Best Practices

1. Консистентность

  • Единые стандарты в команде
  • Автоматизация форматирования
  • Регулярные ревью

2. Читаемость

  • Осмысленные имена
  • Правильная структура
  • Минимум комментариев

3. Поддерживаемость

  • Модульная архитектура
  • Слабая связанность
  • Высокая когезия

4. Производительность

  • Эффективные алгоритмы
  • Профилирование
  • Оптимизация