Вопросы по теме «Шаблоны проектирования»

Начнем с максимально общего и простого вопроса. А что такое вообще шаблоны проектирования и для чего они нужны?

Максимально просто и своими словами.

Ответ

Шаблон проектирования — это, если максимально просто, описание типового способа решения какой-либо архитектурной проблемы. Шаблоны проектирования могут описывать то, как объект


Приведите классификацию шаблонов проектирования по типам. При этом укажите хотя бы по-одному примеру.

Ответ

Шаблоны проектирования разделяют на:

  • Порождающие — описывают, каким именно происходит создание объекта (например Singleton).
  • Поведенческие — описывают поведение объекта (например Observer).
  • Структурные (или архитектурные) — описывают внутреннюю структуру объекта (например MVC).

Назовите несколько шаблонов проектирования, которые максимально часто используются при разработке iOS-приложени.

Ответ

  1. Singleton для доступа к экземпляру UIApplication.
  2. Группа шаблонов MV(X) при проектировании внутренней архитектуры проекта.
  3. Observer при работе с Notification Center или любыми реактивными фреймворками.
  4. Delegation при передаче данных между экранами, конфигурировании UITableView и UICollectionView.

Хорошо, вы упомянули Singleton. Расскажите о нем чуть подробнее и покажите пример его реализации.

Ответ

Singleton (одиночка) — это порождающий шаблон, который гарантирует, что для некоторого класса существует всего один один экземпляр. Такое поведение достигается за счет создания глобальной точки доступа.

Пример реализации:

class App {
    static let shared: App = {
        App()
    }()
}

let appInstance = App.shared

 


Как вы сказали, Singleton используется для классов. А что со структурами? Как нам использовать Singleton для них?

Ответ

Singleton предусматривает передачу экземпляра по ссылке, а значит для него необходимо использовать reference type. Так как структура является value type, то напрямую использовать для нее Singleton не представляется возможным.

Но при острой необходимости передачи структуры мы можем написать некую обертку (wrapper), которая будет передаваться по ссылке, но внутри себя хранить экземпляр структуры.

final class Ref {
    static let shared: Ref = {
        var item = Item()
        item.value = 101
        return Ref(item)
    }()
    var instance: Item
    init( _ instance: Item) {
        self.instance = instance
    }
}

// Сама структура
struct Item {
    var value = 100
}

// Проверка работы
let a = Ref.shared
let b = Ref.shared
a.instance.value = 102
b.instance.value // 102

Теперь поговорим о других шаблонах. Я хотел бы понять, имеете ли вы общее представление о некоторых из них. Для начала расскажите, что такое шаблон "Фасад".

Ответ

Фасад — это шаблон проектирования, название которого говорит само за себя ?.

Фасад предусматривает, что вместо того, чтобы показывать пользователю множество классов, каждый из которых имеет собственное API, должен быть создан один класс, имеющий собственный API для взаимодействия с пользователем, принимающий запросы и делегирующий решение задач этим классам. Таким образом пользователь всегда общается только с одним классом и его API, вместо работы с множеством классов.


Расскажите что такое шаблон "Декоратор"

Ответ

Декоратор — это шаблон проектирования, который предусматривает расширения и изменение поведения некоторого объекта без изменения его программного кода.


Каким образом на Swift можно реализовать "Декоратор"?

Ответ

В общем случае для этого есть несколько вариантов:

  1. Использовать расширения (extension).
  2. Использовать делегирование.
  3. Использовать дочерние классы.

Ни в одном из этих случаев программный код исходного класса не изменяется.


Расскажите что подразумевает под собой паттерн "Внедрение зависимостей (Dependency Injection)"

Ответ

Паттерн предусматривает передачу ответственности за создание зависимостей, которые использует объект во время работы, то есть от которых зависит, некоторому внешнему компоненту. Таким образом объект не создает зависимости самостоятельно, а получает эти зависимости из вне.

Данный паттерн является одной из форм реализации принципа «Инверсия зависимостей (Inversion of Control)»


Какие типы внедрения зависимостей вы знаете?

Ответ

Выделяют следующие типы внедрения зависимостей:

  • Constructor injection — внедрение через инициализатор/конструктор. В этом случае все зависимости передаются при создании объекта в качестве аргумента инициализатора.
  • Property injection и Method injection — внедрение через публичное свойство или метод.
  • Interface injection — внедрение через интерфейс. Интерфейс (или в случае Swift — протокол), на который подписана зависимость, определяет метод, при вызове которого данная зависимость будет внедряться.