PurpleSchool — курсы программирования онлайн
  • Пути
    • Frontend React разработчик
    • Frontend Vue разработчик
    • Backend разработчик Node.js
    • Fullstack разработчик React / Node.js
    • Mobile разработчик React Native
    • Backend разработчик Golang
    • Devops инженер
    • Backend разработчик Python
  • AI для кодаНовое
  • О нас
    • Отзывы
    • Реферальная программа
    • О компании
    • Контакты
  • Иконка открытия меню
    • Сообщество
    • PurpleПлюс
    • AI Собеседование
    • AI тренажёр
    • Проекты
PurpleSchool — платформа бесплатных roadmap и курсов для разработчиков
ютуб иконка
Telegram иконка
VK иконка
VK иконка
Курсы
ГлавнаяКаталог курсовFrontendBackendFullstack
Практика
КарьераПроектыPurpleПлюс
Материалы
БлогБаза знаний
Документы
Договор офертаПолитика конфиденциальностиПроверка сертификатаМиграция курсовРеферальная программа
Реквизиты
ИП Ларичев Антон АндреевичИНН 773373765379contact@purpleschool.ru

PurpleSchool © 2020 -2026 Все права защищены

  • Курсы
    • FrontendИконка стрелки
    • AI разработкаИконка стрелки
    • BackendИконка стрелки
    • DevOpsИконка стрелки
    • MobileИконка стрелки
    • ТестированиеИконка стрелки
    • Soft-skillsИконка стрелки
    • ДизайнИконка стрелки
    Иконка слояПерейти в каталог курсов
  • Бесплатно
    • Курсы
    • JavaScript Основы разработкиPython Основы PythonCSS CSS FlexboxКарта развитияВопросы для собеседований
    • База знанийИконка стрелки
    • Новостные рассылкиИконка стрелки
  • PurpleSchool — курсы программирования онлайн
    • AI для кодаНовое
    • Сообщество
    • PurpleПлюс
    • AI Собеседование
    • AI тренажёр
    • Проекты
    Главная
    Сообщество
    Паттерны проектирования на TypeScript: SOLID с примерами

    Паттерны проектирования на TypeScript: SOLID с примерами

    Аватар автора Паттерны проектирования на TypeScript: SOLID с примерами

    Антон Ларичев

    Иконка календаря13 июня 2026
    typescriptsolidпаттерны проектированияоопархитектураmiddleИконка уровня middle
    Картинка поста Паттерны проектирования на TypeScript: SOLID с примерами

    Введение

    Принципы SOLID — это пять фундаментальных правил объектно-ориентированного проектирования, сформулированных Робертом Мартином. Они помогают писать гибкий, расширяемый и поддерживаемый код. TypeScript благодаря строгой типизации, интерфейсам и модификаторам доступа отлично подходит для демонстрации этих принципов на практике. В этой статье разберём каждый принцип SOLID с примерами кода и покажем, как они работают в реальных проектах.

    S — Single Responsibility Principle

    Принцип единственной ответственности гласит: класс должен иметь только одну причину для изменения. Часто это интерпретируют как «один класс — одна задача».

    Плохой пример: класс, который и хранит данные пользователя, и работает с базой, и отправляет письма.

    // Нарушение SRP: класс делает слишком много
    class User {
      constructor(public email: string, public name: string) {}
    
      saveToDatabase(): void {
        // логика сохранения в БД
      }
    
      sendWelcomeEmail(): void {
        // логика отправки письма
      }
    }
    

    Правильный вариант — разделить ответственности:

    class User {
      constructor(public email: string, public name: string) {}
    }
    
    class UserRepository {
      save(user: User): void {
        // сохранение в базу данных
      }
    }
    
    class EmailService {
      sendWelcome(user: User): void {
        // отправка приветственного письма
      }
    }
    

    Теперь изменение схемы БД не затронет логику отправки писем, и наоборот.

    O — Open/Closed Principle

    Классы должны быть открыты для расширения, но закрыты для модификации. Добавление нового поведения не должно требовать правок старого кода.

    interface PaymentMethod {
      pay(amount: number): void;
    }
    
    class CardPayment implements PaymentMethod {
      pay(amount: number): void {
        // оплата картой
      }
    }
    
    class CryptoPayment implements PaymentMethod {
      pay(amount: number): void {
        // оплата криптовалютой
      }
    }
    
    class Checkout {
      process(method: PaymentMethod, amount: number): void {
        method.pay(amount);
      }
    }
    

    Добавление нового способа оплаты сводится к созданию нового класса, реализующего PaymentMethod. Класс Checkout менять не нужно.

    L — Liskov Substitution Principle

    Объекты подкласса должны быть взаимозаменяемы с объектами базового класса без нарушения корректности программы.

    Классический пример — Прямоугольник и Квадрат. Если Square наследуется от Rectangle и переопределяет сеттеры так, что ширина и высота всегда равны, это сломает код, который ожидает поведение прямоугольника.

    // Правильный подход: общий интерфейс вместо наследования
    interface Shape {
      area(): number;
    }
    
    class Rectangle implements Shape {
      constructor(private width: number, private height: number) {}
      area(): number {
        return this.width * this.height;
      }
    }
    
    class Square implements Shape {
      constructor(private side: number) {}
      area(): number {
        return this.side * this.side;
      }
    }
    

    Здесь обе фигуры реализуют контракт Shape без нарушения ожидаемого поведения.

    I — Interface Segregation Principle

    Клиенты не должны зависеть от методов, которые они не используют. Лучше несколько узких интерфейсов, чем один «жирный».

    // Плохо: один большой интерфейс
    interface Worker {
      work(): void;
      eat(): void;
      sleep(): void;
    }
    
    // Хорошо: разделение по ролям
    interface Workable {
      work(): void;
    }
    
    interface Eatable {
      eat(): void;
    }
    
    class Robot implements Workable {
      work(): void {
        // робот работает, но не ест
      }
    }
    
    class Human implements Workable, Eatable {
      work(): void {}
      eat(): void {}
    }
    

    Теперь класс Robot не обязан реализовывать ненужные методы.

    D — Dependency Inversion Principle

    Модули верхнего уровня не должны зависеть от модулей нижнего уровня. Оба должны зависеть от абстракций.

    interface Logger {
      log(message: string): void;
    }
    
    class ConsoleLogger implements Logger {
      log(message: string): void {
        console.log(message);
      }
    }
    
    class OrderService {
      // зависимость от абстракции, а не от конкретной реализации
      constructor(private logger: Logger) {}
    
      createOrder(): void {
        this.logger.log('Заказ создан');
      }
    }
    
    const service = new OrderService(new ConsoleLogger());
    service.createOrder();
    

    Легко заменить ConsoleLogger на FileLogger или мок в тестах — OrderService об этом не узнает.

    Частые ошибки

    Начинающие разработчики часто впадают в крайности. Перечислим типичные проблемы.

    • Чрезмерное дробление классов ради SRP. Если класс делает одно осмысленное действие — этого достаточно, не нужно выделять каждую строку в отдельный модуль.
    • Использование наследования вместо композиции. LSP легко нарушить, когда подкласс пытается «уточнить» поведение родителя. Композиция и интерфейсы безопаснее.
    • Преждевременные абстракции. Создание интерфейсов для классов, у которых заведомо одна реализация, усложняет код без выгоды. Вводите абстракции, когда появляется второй сценарий использования.
    • Игнорирование DIP при работе с фреймворками. Прямое создание зависимостей через new внутри классов затрудняет тестирование. Используйте внедрение через конструктор или DI-контейнеры.
    • Смешение SRP и слоистой архитектуры. SRP относится к причинам изменения, а не к количеству методов в классе.

    Заключение

    Принципы SOLID — это не догма, а ориентир для принятия архитектурных решений. На TypeScript они особенно естественно ложатся благодаря системе типов и интерфейсам. Применяйте их вдумчиво: цель — не идеальный код по чек-листу, а реальное снижение стоимости изменений и упрощение тестирования. Начните с SRP и DIP — они дают наибольшую отдачу в большинстве проектов. Со временем SOLID станет частью интуиции, и вы будете применять эти принципы автоматически при проектировании любых модулей.

    Иконка глаза469

    Комментарии

    0

    Постройте личный план изучения Основы разработки до уровня Middle — бесплатно!

    Основы разработки — часть карты развития Frontend, Backend, Mobile

    • step100+ шагов развития
    • lessons30 бесплатных лекций
    • lessons300 бонусных рублей на счет

    Бесплатные лекции

    Лучшие курсы по теме

    изображение курса

    Основы Git

    Антон Ларичев
    AI-тренажерыAI-тренажеры
    Гарантия
    Бонусы
    иконка звёздочки рейтинга4.9
    3 999 ₽ 6 990 ₽
    Подробнее
    изображение курса

    HTML и CSS

    Антон Ларичев
    AI-тренажерыAI-тренажеры
    Практика в студииПрактика в студии
    Гарантия
    Бонусы
    иконка звёздочки рейтинга4.9
    3 999 ₽ 6 990 ₽
    Подробнее
    изображение курса

    CSS Flexbox

    Антон Ларичев
    Гарантия
    Бонусы
    иконка звёздочки рейтинга4.9
    бесплатно
    Подробнее

    Похожие статьи

    Картинка поста Domain-Driven Design на TypeScript: практическое руководство
    Иконка аватараАнтон
    Иконка календаря14 июля 2026
    TypeScriptDDDархитектура+ 2seniorИконка уровня senior

    Domain-Driven Design на TypeScript: практическое руководство

    Domain-Driven Design на TypeScript: как моделировать сложные домены с помощью Value Objects, Entities, Aggregates и Domain Events с реальными примерами кода.

    Иконка чипа0
    Иконка глаза161
    Иконка комментариев0
    Картинка поста Clean Architecture: чистая архитектура для веб-разработки
    Иконка аватараАнтон
    Иконка календаря02 июля 2026
    архитектураclean architecturetypescript+ 3middleИконка уровня middle

    Clean Architecture: чистая архитектура для веб-разработки

    Clean Architecture разделяет код на независимые слои: бизнес-логика не зависит от фреймворков, БД и внешних сервисов. Разбираем на примерах TypeScript.

    Иконка чипа0
    Иконка глаза310
    Иконка комментариев0
    Картинка поста Kafka и Node.js: Event-Driven архитектура на практике
    Иконка аватараАнтон
    Иконка календаря13 июля 2026
    kafkanodejsevent-driven+ 2seniorИконка уровня senior

    Kafka и Node.js: Event-Driven архитектура на практике

    Event-Driven архитектура с Kafka в Node.js: продюсеры, консьюмеры, гарантии доставки и типичные ошибки на реальных примерах.

    Иконка чипа0
    Иконка глаза191
    Иконка комментариев0
    Иконка чипа0