Введение в шаблоны креативного дизайна

Введение в шаблоны креативного дизайна

1. Вступление

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

Шаблоны проектирования приобрели популярность после того, как в 1994 году была опубликована книгаDesign Patterns: Elements of Reusable Object-Oriented Software Эрихом Гаммой, Джоном Влиссидесом, Ральфом Джонсоном и Ричардом Хелмом (также известным как Банда четырех или GoF).

В этой статье мы рассмотрим шаблоны творческого проектирования и их типы. Мы также рассмотрим несколько примеров кода и обсудим ситуации, когда эти шаблоны подходят нашему дизайну.

2. Шаблоны творческого дизайна

Creational Design Patterns are concerned with the way in which objects are created. Они уменьшают сложность и нестабильность, создавая объекты контролируемым образом.

Операторnew часто считается вредоносным, поскольку он разбрасывает объекты по всему приложению. Со временем может стать сложной задачей изменить реализацию, поскольку классы становятся тесно связанными.

Шаблоны Creational Design решают эту проблему, полностью отделяя клиента от фактического процесса инициализации.

В этой статье мы обсудим четыре типа Creation Design Pattern:

  1. Singleton - гарантирует, что во всем приложении существует не более одного экземпляра объекта

  2. Factory Method - создает объекты нескольких связанных классов без указания точного объекта, который будет создан

  3. Абстрактная фабрика - создает семейства связанных зависимых объектов

  4. Builder Построение сложных объектов с использованием пошагового подхода.

Давайте теперь подробно обсудим каждый из этих шаблонов.

3. Синглтон Дизайн

Шаблон проектирования Singleton направлен на то, чтобы контролировать инициализацию объектов определенного классаensuring that only one instance of the object exists throughout the Java Virtual Machine..

Класс Singleton также предоставляет одну уникальную глобальную точку доступа к объекту, так что каждый последующий вызов точки доступа возвращает только этот конкретный объект.

3.1. Пример шаблона Singleton

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

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

public class Singleton  {
    private Singleton() {}

    private static class SingletonHolder {
        public static final Singleton instance = new Singleton();
    }

    public static Singleton getInstance() {
        return SingletonHolder.instance;
    }
}

Здесь мы создали внутренний классstatic, который содержит экземпляр классаSingleton. Он создает экземпляр только тогда, когда кто-то вызывает методgetInstance(), а не когда загружается внешний класс.

Это широко используемый подход для класса Singleton, так как он не требует синхронизации, является потокобезопасным, обеспечивает ленивую инициализацию и имеет сравнительно меньше шаблонов.

Также обратите внимание, что в конструкторе есть модификатор доступаprivate. This is a requirement for creating a Singleton since a public constructor would mean anyone could access it and start creating new instances.

Помните, что это не оригинальная реализация GoF. Для исходной версии посетитеthis linked example article на синглтонах на Java.

3.2. Когда использовать шаблон проектирования Singleton

  • Для ресурсов, которые дорого создавать (например, объекты подключения к базе данных)

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

  • Классы, которые предоставляют доступ к настройкам конфигурации для приложения

  • Классы, которые содержат ресурсы, доступ к которым осуществляется в общем режиме

4. Фабрика Метод Дизайн Шаблон

Шаблон проектирования фабрики или шаблон проектирования фабричных методов является одним из наиболее часто используемых шаблонов проектирования в Java.

Согласно GoF, этот шаблон“defines an interface for creating an object, but let subclasses decide which class to instantiate. Метод Factory позволяет классу отложить создание экземпляра до подклассов ».

Этот шаблон делегирует ответственность за инициализацию класса от клиента до конкретного фабричного класса путем создания типа виртуального конструктора.

Чтобы достичь этого, мы полагаемся на фабрику, которая предоставляет нам объекты, скрывая фактические детали реализации. Доступ к созданным объектам осуществляется через общий интерфейс.

4.1. Пример шаблона проектирования фабричного метода

В этом примере мы создадим интерфейсPolygon, который будет реализован несколькими конкретными классами. PolygonFactory будет использоваться для извлечения объектов из этого семейства:

image

Давайте сначала создадим интерфейсPolygon:

public interface Polygon {
    String getType();
}

Затем мы создадим несколько реализаций, напримерSquare,Triangle, и т. Д. реализующие этот интерфейс и возвращающие объект типаPolygon.

Теперь мы можем создать фабрику, которая принимает число сторон в качестве аргумента и возвращает соответствующую реализацию этого интерфейса:

public class PolygonFactory {
    public Polygon getPolygon(int numberOfSides) {
        if(numberOfSides == 3) {
            return new Triangle();
        }
        if(numberOfSides == 4) {
            return new Square();
        }
        if(numberOfSides == 5) {
            return new Pentagon();
        }
        if(numberOfSides == 7) {
            return new Heptagon();
        }
        else if(numberOfSides == 8) {
            return new Octagon();
        }
        return null;
    }
}

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

4.2. Когда использовать шаблон проектирования фабричного метода

  • Когда ожидается, что реализация интерфейса или абстрактного класса будет часто меняться

  • Когда текущая реализация не может комфортно принять новые изменения

  • Когда процесс инициализации относительно прост, а конструктору требуется только несколько параметров

5. Абстрактный дизайн фабрики шаблон

В предыдущем разделе мы увидели, как шаблон проектирования Factory Method можно использовать для создания объектов, связанных с одним семейством.

В отличие от этого, абстрактный шаблон проектирования фабрики используется для создания семейств связанных или зависимых объектов. Его также иногда называют фабрикой фабрик.

Для подробного объяснения ознакомьтесь с нашим руководством поAbstract Factory.

6. Конструктор шаблонов

Шаблон проектирования Builder - это еще один шаблон создания, разработанный для построения сравнительно сложных объектов.

Когда сложность создания объекта увеличивается, шаблон Builder может отделить процесс создания экземпляра, используя другой объект (построитель) для создания объекта.

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

6.1. Пример шаблона Builder

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

Джошуа Блох в своей книге «Эффективная Java» представил улучшенную версию шаблона компоновщика, которая является чистой, хорошо читаемой (поскольку в ней используетсяfluent design) и простой в использовании с точки зрения клиента. В этом примере мы обсудим эту версию.

В этом примере есть только один класс,BankAccount, который содержит конструктор как внутренний классstatic:

public class BankAccount {

    private String name;
    private String accountNumber;
    private String email;
    private boolean newsletter;

    // constructors/getters

    public static class BankAccountBuilder {
        // builder code
    }
}

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

Конструктор такжеprivate, поэтому только Builder, назначенный этому классу, может получить к нему доступ. Все свойства, установленные в конструкторе, извлекаются из объекта построителя, который мы предоставляем в качестве аргумента.

Мы определилиBankAccountBuilder во внутреннем классеstatic:

public static class BankAccountBuilder {

    private String name;
    private String accountNumber;
    private String email;
    private boolean newsletter;

    public BankAccountBuilder(String name, String accountNumber) {
        this.name = name;
        this.accountNumber = accountNumber;
    }

    public BankAccountBuilder withEmail(String email) {
        this.email = email;
        return this;
    }

    public BankAccountBuilder wantNewsletter(boolean newsletter) {
        this.newsletter = newsletter;
        return this;
    }

    public BankAccount build() {
        return new BankAccount(this);
    }
}

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

Эта реализация также поддерживает гибкий подход к проектированию, так как методы установки возвращают объект компоновщика.

Наконец, метод build вызывает закрытый конструктор внешнего класса и передает себя в качестве аргумента. ВозвращенныйBankAccount будет создан с параметрами, установленнымиBankAccountBuilder.

Давайте посмотрим на быстрый пример паттерна построителя в действии:

BankAccount newAccount = new BankAccount
  .BankAccountBuilder("Jon", "22738022275")
  .withEmail("[email protected]")
  .wantNewsletter(true)
  .build();

6.2. Когда использовать шаблон Builder

  1. Когда процесс, связанный с созданием объекта, чрезвычайно сложен, с множеством обязательных и дополнительных параметров

  2. Когда увеличение количества параметров конструктора приводит к большому списку конструкторов

  3. Когда клиент ожидает различных представлений для созданного объекта

7. Заключение

В этой статье мы узнали о шаблонах креативного дизайна в Java. Мы также обсудили их четыре различных типа, т. Е. Синглтон, фабричный метод, абстрактная фабрика и шаблон строителя, их преимущества, примеры и когда мы должны их использовать.

Как всегда, полные фрагменты кода -available over on GitHub.