[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"question-patterny-chto-takoe-printsipy-solid":3},{"id":4,"slug":5,"topicId":6,"topicSlug":7,"topicName":8,"topicEmoji":9,"question":10,"answer":11,"codeLang":12,"codeSrc":12,"important":12,"commonMistakes":12,"modernUsage":12,"difficulty":13,"tags":14,"related":16,"progress":17,"seo":18},1257,"chto-takoe-printsipy-solid",40,"patterny","Паттерны","🧩","Что такое принципы SOLID?","SOLID -- пять принципов объектно-ориентированного проектирования, сформулированных Робертом Мартином. Они помогают создавать код, который легко поддерживать, расширять и тестировать.\n\n### S -- Single Responsibility Principle (Принцип единственной ответственности)\n\nКласс должен иметь только одну причину для изменения.\n\n\u003Cdetails>\n\u003Csummary>Пример кода\u003C\u002Fsummary>\n\n```java\n\u002F\u002F НАРУШЕНИЕ -- класс и обрабатывает заказ, и отправляет email, и сохраняет в БД\nclass OrderService {\n    void processOrder(Order order) {\n        validate(order);\n        save(order);                    \u002F\u002F ответственность: persistence\n        sendEmail(order.getEmail());    \u002F\u002F ответственность: уведомления\n        generatePdf(order);             \u002F\u002F ответственность: отчёты\n    }\n}\n\n\u002F\u002F ПРАВИЛЬНО -- каждый класс отвечает за одно\nclass OrderService {\n    private final OrderRepository repository;\n    private final NotificationService notifications;\n\n    void processOrder(Order order) {\n        validate(order);\n        repository.save(order);\n        notifications.orderCreated(order);\n    }\n}\n```\n\n\u003C\u002Fdetails>\n\n### O -- Open\u002FClosed Principle (Принцип открытости\u002Fзакрытости)\n\nКласс открыт для расширения, закрыт для модификации.\n\n\u003Cdetails>\n\u003Csummary>Пример кода\u003C\u002Fsummary>\n\n```java\n\u002F\u002F НАРУШЕНИЕ -- добавление нового типа скидки требует изменения метода\ndouble calculateDiscount(Order order) {\n    if (order.getType() == REGULAR) return 0;\n    if (order.getType() == VIP) return order.getTotal() * 0.1;\n    if (order.getType() == PREMIUM) return order.getTotal() * 0.2; \u002F\u002F добавили -- модифицировали\n}\n\n\u002F\u002F ПРАВИЛЬНО -- расширение через новый класс, без модификации существующего\ninterface DiscountStrategy {\n    double calculate(Order order);\n}\nclass VipDiscount implements DiscountStrategy { ... }\nclass PremiumDiscount implements DiscountStrategy { ... }\n\u002F\u002F Добавление нового типа = новый класс, существующий код не трогается\n```\n\n\u003C\u002Fdetails>\n\n### L -- Liskov Substitution Principle (Принцип подстановки Барбары Лисков)\n\nОбъекты подклассов должны быть заменяемы объектами суперкласса без нарушения корректности программы.\n\n\u003Cdetails>\n\u003Csummary>Пример кода\u003C\u002Fsummary>\n\n```java\n\u002F\u002F НАРУШЕНИЕ -- Square нарушает контракт Rectangle\nclass Rectangle {\n    void setWidth(int w) { this.width = w; }\n    void setHeight(int h) { this.height = h; }\n}\nclass Square extends Rectangle {\n    @Override void setWidth(int w) { this.width = w; this.height = w; } \u002F\u002F сюрприз!\n}\n\n\u002F\u002F ПРАВИЛЬНО -- отдельные типы или общий интерфейс Shape\ninterface Shape {\n    double area();\n}\nrecord Rectangle(double width, double height) implements Shape {\n    public double area() { return width * height; }\n}\nrecord Square(double side) implements Shape {\n    public double area() { return side * side; }\n}\n```\n\n\u003C\u002Fdetails>\n\n### I -- Interface Segregation Principle (Принцип разделения интерфейса)\n\nКлиент не должен зависеть от методов, которые он не использует.\n\n\u003Cdetails>\n\u003Csummary>Пример кода\u003C\u002Fsummary>\n\n```java\n\u002F\u002F НАРУШЕНИЕ -- один \"жирный\" интерфейс\ninterface Worker {\n    void work();\n    void eat();     \u002F\u002F роботу не нужно\n    void sleep();   \u002F\u002F роботу не нужно\n}\n\n\u002F\u002F ПРАВИЛЬНО -- разделённые интерфейсы\ninterface Workable { void work(); }\ninterface Feedable { void eat(); }\nclass Human implements Workable, Feedable { ... }\nclass Robot implements Workable { ... } \u002F\u002F только нужные методы\n```\n\n\u003C\u002Fdetails>\n\n### D -- Dependency Inversion Principle (Принцип инверсии зависимостей)\n\nМодули верхнего уровня не должны зависеть от модулей нижнего уровня. Оба должны зависеть от абстракций.\n\n\u003Cdetails>\n\u003Csummary>Пример кода\u003C\u002Fsummary>\n\n```java\n\u002F\u002F НАРУШЕНИЕ -- сервис зависит от конкретной реализации\nclass OrderService {\n    private MySqlOrderRepository repo = new MySqlOrderRepository(); \u002F\u002F жёсткая связь\n}\n\n\u002F\u002F ПРАВИЛЬНО -- зависимость от абстракции\nclass OrderService {\n    private final OrderRepository repo; \u002F\u002F интерфейс\n    OrderService(OrderRepository repo) { this.repo = repo; } \u002F\u002F внедрение\n}\n```\n\n\u003C\u002Fdetails>\n\n### Важное\n\n- SOLID -- ориентиры, не догмы; слепое следование может привести к over-engineering\n- SRP -- самый важный и часто нарушаемый принцип\n- DIP -- фундамент для Dependency Injection (Spring IoC)\n- LSP -- ключ к корректному наследованию; нарушение -- частый источник багов\n\n### Частые ошибки\n\n- Один класс = один метод -- это не SRP; SRP = одна причина для изменения\n- Абстракция ради абстракции -- интерфейс с одной реализацией не нужен, если не планируется подмена\n- Наследование вместо композиции -- LSP нарушается чаще при глубокой иерархии\n\n### Как используется в 2026\n\n- SOLID -- стандартный вопрос на собеседовании Middle+\n- Spring Framework построен на DIP (IoC-контейнер)\n- OCP реализуется через Strategy, Plugin-архитектуру, Spring Profiles\n\n> **На собеседовании:** от Middle ожидают не заученные определения, а примеры из собственного опыта: \"я нарушал SRP, когда...\", \"мы применили OCP через...\". Частая ошибка -- путать SRP с \"один метод в классе\" и не уметь объяснить DIP своими словами.","","middle",[15],"patterns",[],null,{"title":19,"description":20,"ogTitle":19,"ogDescription":21,"keywords":22,"schemaAnswer":23,"featuredSnippetReady":24},"Что такое принципы SOLID? — Gymterview","SOLID -- пять принципов объектно-ориентированного проектирования, сформулированных Робертом Мартином. Они помогают создавать код, который легко поддерживать, ра","SOLID -- пять принципов объектно-ориентированного проектирования, сформулированных Робертом Мартином. Они помогают созда",[15,13],"SOLID -- пять принципов объектно-ориентированного проектирования, сформулированных Робертом Мартином. Они помогают создавать код, который легко поддерживать, расширять и тестировать.",true]