# Стандарты кодирования и инструменты ## Навигация - [🏠 Главная страница курса](../../../README.md) - [📚 Модуль 9](../README.md) --- ## Общие принципы ### 1. Читаемость - Код должен быть понятен без комментариев - Использование осмысленных имен - Правильная структура и форматирование ### 2. Поддерживаемость - Модульная структура - Слабая связанность - Высокая когезия ### 3. Производительность - Эффективные алгоритмы - Оптимальное использование ресурсов - Профилирование и оптимизация ## Стандарты кодирования ### 1. Именование #### Java ```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 ```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 ```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 ```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 ```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 ```gradle // build.gradle plugins { id "com.diffplug.spotless" version "6.19.0" } spotless { java { googleJavaFormat() removeUnusedImports() trimTrailingWhitespace() endWithNewline() } } ``` #### Python - Black ```toml # 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 ```json // .prettierrc { "semi": true, "trailingComma": "es5", "singleQuote": true, "printWidth": 80, "tabWidth": 2, "useTabs": false } ``` ### 2. Линтеры #### Java - Checkstyle ```xml ``` #### Python - flake8 ```ini # .flake8 [flake8] max-line-length = 88 extend-ignore = E203, W503 exclude = .git, __pycache__, .venv, .eggs, *.egg, build, dist ``` #### JavaScript/TypeScript - ESLint ```json // .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 ```ini # 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 ```json // 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 ```yaml # .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. Производительность - Эффективные алгоритмы - Профилирование - Оптимизация