S — Single Responsibility Principle (SRP) - Суть: класс/модуль должен иметь лишь одну причину для изменения (одну ответственность). - Пример нарушения: класс Report содержит методы fetchData(), formatHtml(), saveToFile(), sendEmail(). - Исправление: разделить на отдельные классы/слоя: DataFetcher, ReportFormatter, ReportPersister, EmailSender; Report только координирует их работу. O — Open/Closed Principle (OCP) - Суть: сущности должны быть открыты для расширения, но закрыты для модификации. - Пример нарушения: функция calculateArea(shape) делает if/else по type: if type=="circle" ... elseif type=="rectangle" ... - Исправление: ввести абстракцию Shape с методом area(); для нового типа добавлять новый класс, не меняя calculateArea (полиморфизм). L — Liskov Substitution Principle (LSP) - Суть: объекты подклассов должны заменять объекты базового класса без нарушения корректности программы. - Пример нарушения: класс Rectangle с методами setWidth(), setHeight(); класс Square наследует Rectangle и переопределяет сеттеры так, что invariant нарушается (изменение ширины меняет высоту). - Исправление: переработать иерархию: выделить интерфейсы/абстракции (например, ImmutableRectangle или интерфейс Quadrilateral), либо убрать мутабельные сеттеры, либо не делать Square наследником Rectangle. I — Interface Segregation Principle (ISP) - Суть: клиенты не должны зависеть от методов, которые они не используют (интерфейсы должны быть узкоспециализированными). - Пример нарушения: интерфейс MultiFunctionDevice { print(); scan(); fax(); } — класс Scanner вынужден реализовывать fax(), print(). - Исправление: разбить на IPrinter, IScanner, IFax; классы реализуют только нужные интерфейсы. D — Dependency Inversion Principle (DIP) - Суть: модули верхнего уровня не должны зависеть от модулей нижнего уровня — оба должны зависеть от абстракций; абстракции не должны зависеть от деталей. - Пример нарушения: class OrderService { constructor() { this.db = new MySqlDatabase(); } } — OrderService жёстко зависит от конкретной БД. - Исправление: ввести абстракцию (интерфейс Repository/Database) и передавать реализацию через конструктор (инъекция зависимостей) или использовать фабрику/контейнер: constructor(db: Database) { this.db = db; }. (Каждое нарушение решается введением явных абстракций, разделением ответственности и использованием полиморфизма/инъекции зависимостей.)
- Суть: класс/модуль должен иметь лишь одну причину для изменения (одну ответственность).
- Пример нарушения: класс Report содержит методы fetchData(), formatHtml(), saveToFile(), sendEmail().
- Исправление: разделить на отдельные классы/слоя: DataFetcher, ReportFormatter, ReportPersister, EmailSender; Report только координирует их работу.
O — Open/Closed Principle (OCP)
- Суть: сущности должны быть открыты для расширения, но закрыты для модификации.
- Пример нарушения: функция calculateArea(shape) делает if/else по type: if type=="circle" ... elseif type=="rectangle" ...
- Исправление: ввести абстракцию Shape с методом area(); для нового типа добавлять новый класс, не меняя calculateArea (полиморфизм).
L — Liskov Substitution Principle (LSP)
- Суть: объекты подклассов должны заменять объекты базового класса без нарушения корректности программы.
- Пример нарушения: класс Rectangle с методами setWidth(), setHeight(); класс Square наследует Rectangle и переопределяет сеттеры так, что invariant нарушается (изменение ширины меняет высоту).
- Исправление: переработать иерархию: выделить интерфейсы/абстракции (например, ImmutableRectangle или интерфейс Quadrilateral), либо убрать мутабельные сеттеры, либо не делать Square наследником Rectangle.
I — Interface Segregation Principle (ISP)
- Суть: клиенты не должны зависеть от методов, которые они не используют (интерфейсы должны быть узкоспециализированными).
- Пример нарушения: интерфейс MultiFunctionDevice { print(); scan(); fax(); } — класс Scanner вынужден реализовывать fax(), print().
- Исправление: разбить на IPrinter, IScanner, IFax; классы реализуют только нужные интерфейсы.
D — Dependency Inversion Principle (DIP)
- Суть: модули верхнего уровня не должны зависеть от модулей нижнего уровня — оба должны зависеть от абстракций; абстракции не должны зависеть от деталей.
- Пример нарушения: class OrderService { constructor() { this.db = new MySqlDatabase(); } } — OrderService жёстко зависит от конкретной БД.
- Исправление: ввести абстракцию (интерфейс Repository/Database) и передавать реализацию через конструктор (инъекция зависимостей) или использовать фабрику/контейнер: constructor(db: Database) { this.db = db; }.
(Каждое нарушение решается введением явных абстракций, разделением ответственности и использованием полиморфизма/инъекции зависимостей.)