工厂方法和抽象工厂设计模式之间的区别是什么



工厂方法和抽象工厂设计模式之间有什么区别?我对两者都感到困惑。抽象工厂是否使用工厂方法来实现自己?

请举一些具体的例子。

工厂模式通常源于这样一种想法,即对象实例化是一件重要的事情,它不应该分散在代码中,而应该在集中位置中进行,以获得更多的控制;它也更整洁。

工厂方法仅用于上述目的

     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();

抽象工厂另一方面有助于处理对象族。例如:如果你为免费和付费用户计划不同版本的软件,你可以选择为免费版本使用普通控件,为付费版本使用一些美学上更好的控件。这可以用抽象工厂模式优雅地处理。

 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();
  }
 }

假设FreeControlExoticControlontrol(我不是在这里写代码)

现在您将编写以下代码,将所有控件切换到另一个版本

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可以包含自由工厂或外来工厂。并决定创建哪些控件。

使用Factory模式直接创建子类,例如

class CatFactory
{
    ICat Create(string name);
}
CatFactory = new CatFactory();
ICat myCat = myCatFactory.Create("Lion")

抽象工厂进一步定义了工厂必须实现的接口,例如ICatFactory,它使您无法使用特定的工厂类。

interface ICatFactory
{
    ICat Create(string name);
}

如何创建抽象工厂的实例?工厂工厂可能是概念上理解的最简单的方法,但在实践中最简单的方式(取决于应用程序的规模)可能是使用依赖注入框架,该框架为解耦类提供了大量帮助功能。

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

或者取决于的框架

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

工厂方法隐藏单个对象的构造;它可以用来实现虚拟构造函数。工厂方法的另一个特殊情况是原型模式中使用的"克隆"方法。工厂方法只是返回新对象的函数。

抽象工厂隐藏了一系列相关对象的构造。抽象工厂通常使用(一组)工厂方法来实现。例如,假设您希望使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" );
   // ...
}

这将使用一组相关对象(在本例中为GUI控件)的客户端与控件的实现解耦。

最新更新