工厂方法和抽象工厂设计模式之间有什么区别?我对两者都感到困惑。抽象工厂是否使用工厂方法来实现自己?
请举一些具体的例子。
工厂模式通常源于这样一种想法,即对象实例化是一件重要的事情,它不应该分散在代码中,而应该在集中位置中进行,以获得更多的控制;它也更整洁。
工厂方法仅用于上述目的
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和ExoticControlontrol(我不是在这里写代码)
现在您将编写以下代码,将所有控件切换到另一个版本
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控件)的客户端与控件的实现解耦。