Встречается на 72% собеседований по Mobile

что такое Solid

SOLID — это акроним пяти принципов объектно-ориентированного проектирования, которые помогают создавать гибкие, поддерживаемые и масштабируемые системы. Эти принципы были сформулированы Робертом Мартином (также известным как дядя Боб) и стали стандартом для разработки на многих языках, включая Swift.

Как это работает

Каждая буква аббревиатуры соответствует одному принципу:

  • S — Single Responsibility Principle (Принцип единственной обязанности): каждый класс должен иметь только одну причину для изменения, то есть выполнять только одну задачу. Например, в iOS-приложении класс UserManager не должен одновременно отвечать за сетевые запросы и за сохранение данных в Core Data — лучше разделить эти обязанности.

  • O — Open/Closed Principle (Принцип открытости/закрытости): программные сущности (классы, модули, функции) должны быть открыты для расширения, но закрыты для изменения. Это означает, что новое поведение можно добавлять без изменения существующего кода. В Swift это часто реализуется через протоколы и расширения.

  • L — Liskov Substitution Principle (Принцип подстановки Барбары Лисков): если функция использует базовый тип, то она должна корректно работать и с любым его подтипом, не зная о конкретной реализации. Другими словами, подклассы не должны нарушать контракт базового класса. Например, если у вас есть класс Bird с методом fly(), а подкласс Penguin не умеет летать, то это нарушение принципа.

  • I — Interface Segregation Principle (Принцип разделения интерфейса): много специализированных интерфейсов лучше, чем один универсальный. Клиенты не должны зависеть от методов, которые они не используют. В Swift это выражается в создании узких протоколов вместо одного «толстого».

  • D — Dependency Inversion Principle (Принцип инверсии зависимостей): зависимости внутри системы должны строиться на основе абстракций, а не конкретных реализаций. Модули верхнего уровня не должны зависеть от модулей нижнего уровня; оба должны зависеть от абстракций. Абстракции не должны зависеть от деталей, а детали — от абстракций. На практике это означает использование протоколов для внедрения зависимостей.

Пример на Swift

Рассмотрим пример, иллюстрирующий принцип единственной обязанности и инверсии зависимостей.

swift
// Протокол для работы с сетью
protocol NetworkService {
    func fetchData() -> Data
}

// Реализация сетевого сервиса
class URLSessionNetworkService: NetworkService {
    func fetchData() -> Data {
        // реальная реализация
        return Data()
    }
}

// Класс, который использует сетевой сервис
class DataLoader {
    private let networkService: NetworkService

    init(networkService: NetworkService) {
        self.networkService = networkService
    }

    func loadData() -> Data {
        return networkService.fetchData()
    }
}

Здесь DataLoader зависит от абстракции NetworkService, а не от конкретной реализации. Это позволяет легко заменять сетевой сервис (например, на мок для тестирования) без изменения DataLoader.

Подводные камни

  • Переусложнение: следование всем принципам SOLID может привести к излишней абстракции, особенно в небольших проектах. Важно соблюдать баланс и применять принципы там, где они действительно нужны.
  • Нарушение LSP: часто встречается при наследовании, когда подкласс изменяет поведение базового класса. Это может привести к неожиданным ошибкам.
  • Интерфейсы-«зомби»: разделение интерфейсов иногда приводит к созданию множества мелких протоколов, которые трудно поддерживать. Нужно группировать связанные методы.
  • Игнорирование DIP: без инверсии зависимостей код становится жестко связанным, что затрудняет тестирование и модификацию.

Когда использовать

SOLID полезен в любом проекте, но особенно в больших и долгоживущих. Он помогает уменьшить связанность, повысить читаемость и упростить рефакторинг. Однако для маленьких прототипов или одноразовых скриптов следование всем принципам может быть избыточным.

Коротко

  • SOLID — пять принципов ООП: единственная обязанность, открытость/закрытость, подстановка Лисков, разделение интерфейса, инверсия зависимостей.
  • Принципы направлены на создание гибкого и поддерживаемого кода.
  • В Swift активно используются протоколы для реализации OCP, ISP и DIP.
  • Соблюдение SOLID упрощает тестирование и расширение функциональности.
  • Избегайте излишней абстракции — применяйте принципы осознанно.
как отвечать на вопрос
пример собеседования
фреймворки на собеседовании
типичные вопросы junior
интервью вопросы и ответы