В чем разница между фабричным методом и шаблонами абстрактного фабричного дизайна? - PullRequest
1 голос
/ 08 июня 2011

В чем разница между фабричным методом и абстрактным фабричным дизайном? Я запутался в обоих.Использует ли абстрактная фабрика фабричный метод для самореализации?

Пожалуйста, приведите несколько реальных примеров.

Ответы [ 3 ]

3 голосов
/ 08 июня 2011

Фабричный шаблон в целом исходит из мысли, что Создание объекта - важная вещь, и ее не следует разбрасывать по коду, а нужно делать из Централизованное расположение , чтобы иметь больший контроль;он также аккуратнее.

Заводской метод просто служит вышеуказанной цели

     ControlFactory
 {
  public Button GetButton(){return new Button();}
  public Label GetLabel(){return new Label();}
  public TextBox GetTextBox(){return new TextBox();}
 }

Тогда для создания экземпляров этих элементов управления вы будете писать под кодом

ControlFactory cf=new ControlFactory();

Button b=cf.GetButton();b.Text="Click Me";
Label l=cf.GetLabel();

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

 abstract class ControlsFactory
 {
    public abstract Button GetButton();
    public abstract Label GetLabel();
 }

--- теперь FreeControlFactory и ExoticControlFactory наследуют вышеприведенный класс

 class FreeControlsFactory:ControlsFactory
 {


  public override Button GetButton()
  {
      return new FreeButton();//Assume that **FreeControl** and **ExoticControl** are Inherited From **Control** 
  }

  public override Label GetLabel()
  {
      return new FreeLabel();
  }

 }

...

 class ExoticControlsFactory : ControlsFactory
 {


  public override Button GetButton()
  {
   return new ExoticButton();
  }

  public override Label GetLabel()
  {
   return new ExoticLabel();
  }

 }

Предположим, что FreeControl и ExoticControl унаследованы от Control (я не пишу здесь код)

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

if (VersionKey=="FreeVersion")
    {ControlFactory cf= new FreeControlFactory();}
ese if (VersionKey=="PaidVersion")
    {cf=new ExoticControlFactory();}

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

Button b1=cf.GetButton();//b1 will be based on which family cf is containing
Button b2=cf.GetButton();
Button b3=cf.GetButton();
Label l1= cf.GetLabel();
Label l2= cf.GetLabel();

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

2 голосов
/ 08 июня 2011

Заводской метод скрывает строительство одного объекта;его можно использовать для реализации виртуальных конструкторов .Другим частным случаем фабричного метода является метод «клон», используемый в шаблоне прототипа .Методы фабрики - это просто функции, возвращающие новые объекты.

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

class Button { };
class Label { };
class CheckBox { };

class Toolkit {
public:
    virtual ~Toolkit() {}
    virtual Button *createButton() = 0;
    virtual CheckBox *createCheckBox() = 0;
    virtual Label *createLabel() = 0;
};

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

class QtButton : public Button { };
class QtLabel : public Button { };
class QtCheckBox : public Button { };

class QtToolkit {
public:
    virtual ~Toolkit() {}
    virtual Button *createButton() { return new QtButton; }
    virtual CheckBox *createCheckBox() { return new QtCheckBox; }
    virtual Label *createLabel() { return new QtLabel; }
};

Код, который фактически создает GUI, нуждается только в Toolkit*, поэтому существует очень низкая связь:

void constructGUI( Toolkit *tk )
{
   Button *okButton = tk->createButton();
   okButton->setText( "OK" );

   // ...
}

Это разъединяет клиента с помощью набора связанных объектов(в данном случае: элементы управления с графическим интерфейсом) из реализации элементов управления.

2 голосов
/ 08 июня 2011

Используйте шаблон «Фабрика» для непосредственного создания подклассов, например,

class CatFactory
{
    ICat Create(string name);
}

CatFactory = new CatFactory();
ICat myCat = myCatFactory.Create("Lion")

. Абстрактная фабрика продвигается дальше, определяя интерфейсы, которые должны реализовывать фабрики, например, ICatFactory, что освобождает вас от использованияопределенный класс фабрики.

interface ICatFactory
{
    ICat Create(string name);
}

Как вы создаете экземпляры абстрактной фабрики?Фабричная фабрика, возможно, является самым простым способом концептуального понимания, но на практике самым простым (в зависимости от масштаба вашего приложения) может быть использование Dependency Injection фреймворка, который предоставляет множество вспомогательных функций для развязкиклассы.

ICatFactory = DependencyInjector.Get<ICatFactory>();
ICat myCat = myCatFactory.Create("Lion")

или в зависимости от структуры просто

ICat myCat = DependencyInjector.Get<ICat>("Lion")
...