工厂方法和抽象工厂设计模式有什么区别?

时间:2011-06-08 08:26:18

标签: design-patterns

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

请举出一些实际的例子。

3 个答案:

答案 0 :(得分:3)

工厂模式一般来自于对象实例化是一个重要的事情,它不应该分散在整个代码中,而应该从集中位置来完成更多控制;它也更整洁。

工厂方法仅用于上述目的

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

 }

假设 FreeControl ExoticControl 是从控制继承的(我不是在这里编写代码) < / p>

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

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可以包含freefactory或exoticfacctory。并决定创建哪些控件。

答案 1 :(得分:2)

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

class CatFactory
{
    ICat Create(string name);
}

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

抽象工厂通过定义工厂必须实现的接口(例如ICatFactory)来进一步发展,它将您与使用特定工厂类分开。

interface ICatFactory
{
    ICat Create(string name);
}

如何创建抽象工厂的实例?工厂工厂可能是概念上理解的最简单方法,但实际上最简单的方法(取决于应用程序的规模)可能是使用Dependency Injection框架,它为解耦类提供了许多辅助功能。 / p>

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

或取决于框架

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

答案 2 :(得分:2)

工厂方法隐藏单个对象的构造;它可以用来实现virtual constructors。工厂方法的另一个特例是prototype pattern中使用的“克隆”方法。工厂方法只是返回新对象的函数。

抽象工厂隐藏了一系列相关对象的构造。抽象工厂通常使用(一组)工厂方法实现。例如,假设您希望使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控件)从控件的实现中分离客户端。