Design Patterns(GoF - Gang of Four)
Что это
Паттерны проектирования — шаблоны проектирования программного обеспечения.
Creational(Порождающие) - Отвечают за удобное и безопасное создание новых объектов или семейств объектов.
- Factory Method(Фабричный метод) - определяет общий интерфейс для создания объектов в суперклассе,
позволяя подклассам изменять тип создаваемых объектов.
class A {
public void doSomething() {
Foo f = makeFoo();
f.whatever();
}
protected Foo makeFoo() {
return new RegularFoo();
}
}
class B extends A {
protected Foo makeFoo() {
//subclass is overriding the factory method
//to return something different
return new SpecialFoo();
}
}
- Abstract Factory(Абстрактная фабрика) - позволяет создавать семейства связанных объектов, не привязываясь
к конкретным классам создаваемых объектов.
class A {
private Factory factory;
public A(Factory factory) {
this.factory = factory;
}
public void doSomething() {
//The concrete class of "f" depends on the concrete class
//of the factory passed into the constructor. If you provide a
//different factory, you get a different Foo object.
Foo f = factory.makeFoo();
f.whatever();
}
}
interface Factory {
Foo makeFoo();
Bar makeBar();
Aycufcn makeAmbiguousYetCommonlyUsedFakeClassName();
}
//need to make concrete factories that implement the "Factory" interface here
- Builder(Строитель) - позволяет создавать сложные объекты пошагово. Убирает необходимость создавать
множество конструкторов.
- Prototype(Прототип) - позволяет копировать объекты, не вдаваясь в подробности их реализации.
- Singleton(Одиночка) - гарантирует, что у класса есть только один экземпляр, и предоставляет к нему
глобальную точку доступа. Есть 2 варианта создания 1 - Lazy(создание при обращении), 2 - Eager(жадный,
создание при старте приложения).
Пример:
class Singleton {
private static Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
Structural(Структурные) - Отвечают за построение удобных в поддержке иерархий классов.
- Adapter(Адаптер) - позволяет объектам с несовместимыми интерфейсами работать вместе.
- Bridge(Мост) - разделяет один или несколько классов на две отдельные иерархии — абстракцию и реализацию,
позволяя изменять их независимо друг от друга.
- Composite(Компоновщик) - позволяет сгруппировать множество объектов в древовидную структуру,
а затем работать с ней так, как будто это единичный объект.
- Flyweight(Легковес) - позволяет вместить большее количество объектов в отведённую оперативную память.
Легковес экономит память, разделяя общее состояние объектов между собой, вместо хранения одинаковых данных
в каждом объекте.
- Facade(Фасад) - предоставляет простой интерфейс к сложной системе классов, библиотеке или фреймворку.
- Decorator(Wrapper)(Декоратор) - позволяет динамически добавлять объектам новую функциональность,
оборачивая их в полезные «обёртки». Гибкая альтернатива практике создания подклассов с целью расширения
функциональности. Примеры:InputStream, FileInputStream, BufferedReader и тд.
- Proxy(Заместитель) - позволяет подставлять вместо реальных объектов специальные объекты-заменители.
Эти объекты перехватывают вызовы к оригинальному объекту, позволяя сделать что-то до или после передачи
вызова оригиналу.
Сравнение Adapter, Decorator и Proxy?
Заместитель(proxy) оборачивает некоторый класс и предоставляет такой же интерфейс. Цель -- "притвориться"
оригинальным классом и скрыть от клиента детали.
Декоратор также оборачивает некоторый класс и предоставляет такой же или расширенный интерфейс. Т.е. декоратор
может притворяться оригинальным классом и при этом расширять его функциональность. Пример: у вас есть
заместитель, который прячет вызовы к стороннему сервису. Можно создать декоратор, который будет оборачивать и
кэшировать результаты вызовов. Другой пример: нужно расширить функциональность оригинального класса, но он
закрыт для наследования. Создается декоратор, который расширяет интерфейс оригинального класса.
Адаптер также оборачивает некоторый класс, но при этом предоставляет другой интерфейс. Т.е. используется
в случаях, когда есть класс с нужными данными и поведением, но с неподходящим интерфейсом.
Behavioral(Поведенческие) - Решают задачи эффективного и безопасного взаимодействия между объектами программы.
- Chain of Responsibility(Цепочка обязанностей) - позволяет передавать запросы последовательно по цепочке
обработчиков. Каждый последующий обработчик решает, может ли он обработать запрос сам и стоит ли передавать
запрос дальше по цепи.
- Command(Команда) - превращает запросы в объекты, позволяя передавать их как аргументы при вызове методов,
ставить запросы в очередь, логировать их, а также поддерживать отмену операций.
- Iterator(Итератор) - даёт возможность последовательно обходить элементы составных объектов,
не раскрывая их внутреннего представления.
- Mediator(Посредник) - позволяет уменьшить связанность множества классов между собой, благодаря перемещению
этих связей в один класс-посредник.
- Memento(Снимок) - позволяет сохранять и восстанавливать прошлые состояния объектов, не раскрывая
подробностей их реализации.
- Observer(Наблюдатель) - создаёт механизм подписки, позволяющий одним объектам следить и реагировать
на события, происходящие в других объектах.
- State(Состояние) - позволяет объектам менять поведение в зависимости от своего состояния. Извне создаётся
впечатление, что изменился класс объекта.
- Strategy(Стратегия) - определяет семейство схожих алгоритмов и помещает каждый из них в собственный класс,
после чего алгоритмы можно взаимозаменять прямо во время исполнения программы.
- Template Method(Шаблонный метод) - скелет алгоритма, перекладывая ответственность за некоторые его шаги
на подклассы. Паттерн позволяет подклассам переопределять шаги алгоритма, не меняя его общей структуры.
- Visitor(Посетитель) - позволяет добавлять в программу новые операции, не изменяя классы объектов,
над которыми эти операции могут выполняться.