| name | engineering-principles |
| description | Pragmatic coding principles: SOLID, KISS, DRY, YAGNI in balance. Use when writing code, refactoring, reviewing, or designing architecture. Prevents over-engineering while maintaining code quality. Триггеры: "напиши код", "рефактори", "code review", "архитектура", "engineering principles", "SOLID", "KISS", "DRY", "YAGNI", "design this", "how to structure", "разбей на модули", "спроектируй архитектуру", "создай проект", "структура проекта", "объясни архитектуру"
|
Engineering Principles — Pragmatic Balance
Priority (when in conflict)
- Работает → решает задачу пользователя
- Просто (KISS) → простейшее рабочее решение, можно понять и поддерживать
- Не усложняй заранее (YAGNI) → сначала работающий простой код, не усложнять заранее
- Убери настоящий дубль (DRY) → только когда реально нужно (3+ места), настоящая одинаковая логика
- SOLID → когда система уже растёт; маленький скрипт ≠ нужна абстракция
Что даёт каждый принцип (цель, не догма)
| Принцип | Зачем | Стоп-сигнал |
|---|
| SRP — одна ответственность | Меняешь одно → не ломает другое | Функция > 40 строк или 3+ причин менять → раздели |
| OCP — расширяй, не меняй | Новая фича → старое работает | Не создавай абстракции "на будущее" (см. YAGNI) |
| LSP — замена без сюрпризов | Подставил реализацию → работает | instanceof, if type → плохой дизайн, переделай |
| ISP — минимум зависимостей | Не тяни лишнее | Интерфейс > 5 методов → разбей |
| DIP — завись от абстракций | Меняешь деталь → бизнес-логика не знает | Не абстрагируй то что не будет меняться |
| KISS — простота | Код понятен с первого чтения | if/else на 3 ветки ≠ нужна фабрика |
| DRY — без дублирования | Баг в одном месте → починил везде | Похожий код, разная логика → НЕ трогай |
| YAGNI — фокус | Не тратишь время на ненужное | "Конфиг на будущее", "generic для всего" → стоп |
Product-first Checks
Перед финальной реализацией спроси:
- Какую видимую пользователю проблему это решает?
- Как пользователь поймёт что это сработало?
- Что сломается если входные данные, сеть, зависимость или данные — плохие?
- Можно ли это наблюдать, тестировать, откатить, объяснить?
- Это простейший код который оставляет будущие изменения продукта дешёвыми?
Product Engineering Priorities
- Correct user outcome — правильный результат для пользователя
- Clear surfaced behavior — ясные API/UI/контракты/ошибки
- Safe changeability — безопасно менять
- Operational visibility — можно наблюдать и дебажить
- Code elegance — красота кода (последний приоритет)
Before writing code — 3 вопроса
- Какую задачу пользователя это решает?
- Есть ли проще способ?
- Что если это изменится — легко ли переделать?
Complexity gates
- Cyclomatic complexity ≤ 15 (функции > 20 → рефактори или обоснуй в PR)
- Вложенность > 3 уровней → early return / guard clauses
- Файл > 400 строк → раздели если логически делится
✅/❌ Quick Reference
KISS
✅ Простая коллекция вместо сложной структуры
✅ Одна функция 40 строк понятнее чем 3 по 15
❌ Фабрика + стратегия + декоратор для if/else на 3 ветки
DRY
✅ Одинаковая бизнес-логика в 3 местах → вынеси
❌ Две функции с 2 общими строками → не объединяй
❌ Совпадение структуры ≠ дублирование (accidental duplication)
YAGNI
❌ "Интерфейс пригодится когда будет вторая реализация"
❌ "Generic решение для всех возможных случаев"
❌ "Конфиг на будущее"
✅ Делаешь под задачу → рефакторишь когда задачи меняются
SOLID
✅ SRP: одна причина менять → один класс/функция
❌ SRP: 10 классов для 10 строк кода → over-engineering
✅ DIP: бизнес-логика не знает про базу данных
❌ DIP: абстракция над каждым console.log
✅ OCP: новый тип через композицию, не правка существующего
❌ OCP: 5 уровней наследования "на всякий случай"
Practical Guidelines
Когда применять SOLID
- Код > 100 строк в одном файле
- Уже есть 2+ места где используется
- Команда > 1 человека или долгоживущий проект
- Частые изменения в одной области
Когда остановиться (KISS wins)
- Скрипт < 50 строк
- Одноразовая утилита
- Прототип / spike
- if/else на 2-3 ветки
- Нет признаков что будет расти
DRY — прагматичный подход
- True duplication: одинаковая логика, одинаковая причина менять → выноси
- Accidental similarity: похожая структура, разная причина менять → НЕ трогай
- Rule of 3: нашёл в 3 местах → время вынести
YAGNI — красные флаги over-engineering
- "Потом пригодится"
- "На случай если..."
- "Может быть вторая реализация"
- "Generic для всех случаев"
- Абстракция без конкретного второго пользователя
What this gives
| Principle | Real benefit |
|---|
| KISS | Readability — understand code on first read |
| YAGNI | Focus — spend time on what's needed now, no over-engineering |
| DRY | Consistency — fix bugs once, everywhere fixed (when truly duplicated) |
| SRP | Stability — change one thing without breaking another |
| OCP | Safe extensions — new features don't break old code |
| LSP | Predictability — swap implementations without surprises |
| ISP | Minimal deps — depend only on what you use |
| DIP | Modularity — swap infrastructure freely |
Project Structure Standards
Стандартная структура (адаптируй под стек)
project/
├── src/ # Бизнес-логика, компоненты, сервисы
│ ├── modules/ # Функциональные модули (SRP: один модуль = одна зона)
│ ├── shared/ # Переиспользуемые утилиты (общие helpers, types)
│ └── index # Entry point
├── config/ # Конфигурации (дефолтные, примеры, env templates)
├── scripts/ # Утилиты: билд, деплой, миграции, генераторы
├── tests/ # Тесты: unit, integration, e2e
├── docs/ # Доки: API, архитектура, runbooks
└── .env.example # Шаблон переменных окружения
Зоны ответственности папок
| Папка | Что внутри | Что НЕ внутри |
|---|
src/ | Бизнес-логика, компоненты, API handlers | Конфиги, скрипты деплоя, тесты |
config/ | Дефолтные конфиги, .env.example, templates | Секреты, хардкод значений |
scripts/ | Автоматизация, CLI-утилиты, генераторы | Бизнес-логика приложения |
tests/ | Unit, integration, e2e, fixtures, mocks | Production код |
docs/ | README, API specs, architecture decisions | Устаревшие доки без даты |
SRP на уровне файлов
- Файл > 400 строк → раздели если логически делится
- Один класс/функция/модуль = одна причина менять
- Entry point (
index.ts, main.py) = только wiring, без логики
Architecture Explanation Guide
После проектирования — объясни:
1. Ключевые решения
- Что решил → почему так → какие альтернативы отверг
- Формат:
Решение: X. Причина: Y. Альтернатива Z отвергнута потому что W.
2. Последовательность компонентов
- Что за чем идёт и почему
- Формат:
A → B → C с пояснением зачем каждый шаг
- Пример:
CLI (парсинг args) → Config (валидация) → Service (логика) → Output (результат)
3. Зона ответственности каждого компонента
- Каждый модуль/файл: что делает, что НЕ делает
- Формат:
Компонент X: делает Y. Не делает Z. Зависит от W.
4. Потоки данных
- Откуда данные приходят, куда уходят, где трансформируются
- Формат:
Input → [Transform] → Output
- Укажи контракты: типы данных, форматы, ошибки
5. Связи и зависимости
- Кто кого вызывает, кто от кого зависит
- Стрелки зависимостей:
модуль A → модуль B (A зависит от B)
- Покажи где DIP/абстракции, где прямые зависимости
Правило: кратко, без воды
- Связь → Причина → Следствие
- Не "этот компонент очень важен" → "Config валидирует env → сервис падает рано с понятной ошибкой"
Pre-implementation Checklist
Перед написанием кода — пройдись по чеклисту:
1. План (Todos ≤ 10 пунктов)
2. Проектирование
3. Объяснение
4. Complexity gates
Syntax & Smoke Test Checklist
После написания — проверь:
Проверка синтаксиса (по стеку)
| Язык | Команда |
|---|
| JavaScript/Node.js | node -c file.js |
| TypeScript | npx tsc --noEmit |
| Python | python -m py_compile file.py |
| Bash | bash -n script.sh |
| Go | go build ./... |
| Rust | cargo check |
Базовая работоспособность
Configuration Standards
Обязательные конфиги
Правила
- Никогда не коммить реальные секреты — токены, ключи, пароли
.env.example показывает структуру, не значения
- Дефолты = безопасные (localhost, пустые строки, тестовые значения)
- Документируй откуда брать значения (ссылки на API, сервисы)
Формат .env.example
API_KEY=your-api-key-here
DATABASE_URL=postgresql://localhost:5432/mydb
PORT=3000
LOG_LEVEL=info
Implementation Workflow
Полный цикл создания проекта/фичи:
- Прочитай этот скилл — загрузи engineering-principles
- Составь Todos ≤ 10 — конкретные действия, порядок
- Спроектируй структуру — папки, модули, контракты
- Объясни архитектуру — решения, последовательность, потоки
- Реализуй — код, конфиги, скрипты, примеры
- Проверь синтаксис — по языку (см. таблицу выше)
- Smoke test — запусти, убедись работает
- Зафиксируй — README, примеры использования