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 станет частью интуиции, и вы будете применять эти принципы автоматически при проектировании любых модулей.

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

    Комментарии

    0

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

    HTML и CSS - полный курс по вёрстке с нуля — часть карты развития Frontend, Mobile

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

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

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

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

    Основы JavaScript

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

    Продвинутый JavaScript

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

    TypeScript с нуля

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

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

    Картинка поста Микросервисы vs монолит: как выбрать архитектуру проекта
    Иконка аватараАнтон
    Иконка календаря10 июня 2026
    архитектурамикросервисымонолит+ 2middleИконка уровня middle

    Микросервисы vs монолит: как выбрать архитектуру проекта

    Микросервисы vs монолит — разбираем плюсы и минусы обеих архитектур, показываем примеры кода и помогаем выбрать подход под ваш проект.

    Иконка чипа+1
    Иконка глаза97
    Иконка комментариев0
    Картинка поста TypeScript дженерики на практике: полный гайд для разработчиков
    Иконка аватараАнтон
    Иконка календаря30 мая 2026
    typescriptgenericsjavascript+ 1middleИконка уровня middle

    TypeScript дженерики на практике: полный гайд для разработчиков

    TypeScript дженерики на практике: разбираем синтаксис, ограничения, условные типы и реальные примеры использования в проектах.

    Иконка чипа0
    Иконка глаза201
    Иконка комментариев0
    Картинка поста Микрофронтенды и Module Federation: когда применять и как внедрить
    Иконка аватараАнтон
    Иконка календаря28 мая 2026
    микрофронтендыmodule federationwebpack+ 2seniorИконка уровня senior

    Микрофронтенды и Module Federation: когда применять и как внедрить

    Микрофронтенды и Module Federation: разбираем когда нужна такая архитектура, как настроить host и remote приложения и избежать типичных ошибок.

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