Абстрактная фабрика, Фабричный метод, Строитель

Может показаться, что этот вопрос является обманом, но, пожалуйста, потерпите меня - я обещаю, что прочитал соответствующие сообщения (и книга GOF).

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

Можете ли вы привести простой пример, в котором вы бы явно использовали один шаблон, а не другие?

Я понимаю, что это может сводиться к мнению, если пример слишком прост, но я надеюсь, что если кто-то может, этот человек находится в ТАК.

Спасибо.


person Escualo    schedule 10.09.2010    source источник


Ответы (6)


Строитель помогает вам построить сложный объект. Примером может служить класс StringBuilder (Java, C#), который создает окончательную часть строки поштучно. Лучшим примером является UriComponentsBuilder в Spring, что поможет вам создать URI.

Фабричный метод дает вам полный объект за один раз (в отличие от построителя). Базовый класс определяет один абстрактный метод, который возвращает ссылку на интерфейс (или суперкласс) и откладывает конкретное создание объекта до подклассов.

Абстрактная фабрика — это интерфейс (или абстрактный класс) для создания множества различных связанных объектов. Хорошим примером (в .NET) является DbProviderFactory класс, который служит для создания связанных объектов (соединений, команд и т. д.) с данным провайдером базы данных (оракул, сервер sql и т. д.), в зависимости от его конкретной реализации.

person Jordão    schedule 10.09.2010
comment
StringBuilder не является реализацией шаблона построителя. Это миф. - person NileshChauhan; 21.02.2013
comment
@NileshChauhan: позволю себе не согласиться! - person Jordão; 21.02.2013
comment
WebRequest.Create не является заводским методом GoF. Это статический фабричный метод. Это два разных узора. - person jaco0646; 30.07.2016
comment
@ jaco0646: спасибо, что разъяснили это. Я изменю текст соответственно. - person Jordão; 30.07.2016

Конструктор

// Builder encapsulates construction of other object. Building of the object can be done in multiple steps (methods)
public class ConfigurationBuilder
{
  // Each method adds some configuration part to internally created Configuration object
  void AddDbConfiguration(...);
  void AddSmtpConfiguration(...);
  void AddWebServicesConfiguration(...);
  void AddWebServerConfiguration(...);

  // Returns built configuration
  Configuration GetConfiguration();
}

Заводской метод

// Factory method is declared in base class or interface. Subclass defines what type is created by factory method.
public interface ICacheProvider
{
  ISession CreateCache(); // Don't have to return new instance each time - such decission is part of implementation in derived class.
}

public class InMemoryCacheProvider : ICacheProvider
{ ... }

public class DbStoredCacheProvider : ICacheProvider
{ ... }

// Client code
ICacheProvider provider = new InMemoryCacheProvider
ICache cache = provider.CreateCache(); 

Абстрактная фабрика

// Abstract factory defines families of platform classes - you don't need to specify each platform class on the client.
public interface IDbPlatform
{
  // It basically defines many factory methods for related classes
  IDbConnection CreateConnection();
  IDbCommand CreateCommand();
  ...
}

// Abstract factory implementation - single class defines whole platform
public class OraclePlatfrom : IDbPlatform
{ ... }

public class MySqlPlatform : IDbPlatform
{ ... }

// Client code:
IDbPlatform platform = new OraclePlatform();
IConnection connection = platform.CreateConnection(); // Automatically Oracle related
...
person Ladislav Mrnka    schedule 10.09.2010
comment
Разница между фабричным методом и абстрактной фабрикой заключается не только в количестве методов в интерфейсе. См.: stackoverflow.com/questions/5739611/ - person jaco0646; 05.10.2018

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

Заводской метод:

  1. Он определяет интерфейс для создания объекта, но позволяет подклассам решать, экземпляр какого класса создавать
  2. Мы создаем объект, не раскрывая логику создания клиенту, и обращаемся к вновь созданному объекту, используя общий интерфейс (или абстрактные классы).
  3. Обеспечивает слабую связь, устраняя необходимость привязки классов приложения к коду. Код взаимодействует только с интерфейсом или абстрактным классом
  4. Он может использовать наследование или подклассы для достижения цели.

    Ключевое примечание: вы создадите интерфейс и конкретную реализацию этих интерфейсов. В методе Factory, в зависимости от условия, вы получите конкретную реализацию общего интерфейса.

Абстрактная фабрика:

  1. Предоставьте интерфейс для создания семейств связанных или зависимых объектов без указания их конкретных классов.
  2. Иерархия, которая включает в себя: множество возможных "платформ"` и построение набора "продуктов"
  3. Классы абстрактной фабрики часто реализуются с помощью фабричных методов, но их также можно реализовать с помощью прототипа.

Построитель:

  1. Шаблон Builder создает сложный объект, используя простые объекты и применяя пошаговый подход
  2. Замена метода Factory/Abstract Factory в этом сценарии: слишком много аргументов для передачи из клиентской программы в класс Factory, что может быть подвержено ошибкам
  3. Некоторые параметры могут быть необязательными, в отличие от Factory, где принудительно отправляются все параметры.

Рекомендации по шаблону проектирования Builder в Java

  1. Создайте статический вложенный класс с именем Builder внутри класса, объект которого будет создан Builder.
  2. Класс Builder будет иметь точно такой же набор полей, что и исходный класс
  3. Класс Builder предоставляет метод добавления ингредиентов. Каждый метод будет возвращать один и тот же объект Builder. Builder будет обогащаться с каждым вызовом метода.
  4. Метод Builder.build() скопирует все значения полей построителя в фактический класс и вернет объект класса Item
  5. Класс элемента (класс, для которого мы создаем Builder) должен иметь частный конструктор для создания своего объекта из метода build() и предотвращения доступа посторонних к его конструктору.

Похожие сообщения:

Шаблоны проектирования: метод Factory vs Factory vs Abstract Factory

Сохранение построителя в отдельном классе (свободный интерфейс)

Полезные ссылки:

создание исходного кода шаблоны проектирования

person Ravindra babu    schedule 20.02.2016

Шаблон абстрактной фабрики использует подклассы (фабрик) для создания других объектов (не фабрик). Абстрактная фабрика также предполагает, что создаваемые объекты принадлежат параллельным иерархиям (например, для обеспечения независимости от платформы, одна иерархия для каждой платформы).

Шаблон Builder использует подклассы для создания "выходных данных", которые не обязательно являются объектами. В примере GOF Builder производит текстовый вывод (разметку или что-то другое).

Шаблон Factory Method, в отличие от двух других, делит "создателя" на абстрактную и конкретную реализацию (таким образом, акцент на нем относится к реализации фреймворка). Как и Abstract Factory, он занимается созданием реальных объектов.

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

person Brent Arias    schedule 10.09.2010

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

Например, в С#:

public class Worker
{
    public IConsumerFactory Factory { get; set; }

    private IResource resource;

    public DoWork()
    {
        IConsumer consumer = Factory.CreateConsumer();
        consumer.Consume(resource);
    }
}

public interface IConsumerFactory
{
    IConsumer CreateConsumer();
}

public interface IConsumer
{
    void Consume(IResource resource);
}

public class DefaultConsumerFactory : IConsumerFactory
{
    public IConsumer CreateConsumer()
    {
        return new DefaultConsumer();
    }
}

public class DefaultConsumer : IConsumer
{
    public void Consume(IResource resource)
    {
      ... Do Work ...
    }
}

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

person Matt H    schedule 10.09.2010

  • Шаблон Factory Method — когда вы хотите построить семейство сложных объектов.
  • Шаблон построителя объектов — когда вы хотите разрешить пользователю подключать свою собственную реализацию к вашей структуре.

Пожалуйста, посетите следующий URL для более подробной информации.

http://xeon2k.wordpress.com

person Nitin    schedule 27.11.2010