就像标题所问的那样,什么时候应该在您的脑海中触发表示“啊哈!我应该在这里使用工厂模式!”?我发现这些时刻会发生在许多其他设计模式中,但我从来没有停下来思考这个模式。
6 回答
每当您发现自己的代码看起来像这样时,您可能应该使用工厂:
IFoo obj;
if ( someCondition ) {
obj = new RegularFoo();
} else if ( otherCondition ) {
obj = new SpecialFoo();
} else {
obj = new DefaultFoo();
}
工厂模式最适用于您希望将一组对象的实例化封装在方法中的情况。
换句话说,如果你有一组对象都继承自同一个基类或都实现了相同的接口,这将是你想要使用工厂模式的实例(这将是你会看的“模式”为了)。
我可以想到我想到工厂模式的两个具体案例:
- 当构造函数中有逻辑时。
- 当我不想让应用程序担心实例化的类型时(例如,我有一个要返回的抽象基类或接口)。
引自GoF:
使用工厂方法模式
- 一个类不能预测它必须创建的对象类
- 一个类希望它的子类指定它创建的对象
- 类将责任委托给几个助手子类之一,并且您希望本地化有关哪个助手子类是委托的知识。
我强烈推荐 GoF 书。它有一节介绍了它所涵盖的 23 种模式中的每一种的适用性。
你说的是工厂方法还是抽象工厂?
两者都解决的基本问题是让客户指定框架代码构造的确切类。例如,如果您提供一个接口,客户端可以实现,然后在您的代码中具有如下内容:
IMyInterface x = new ConcreteClass();
如果不访问该代码,客户就无法更改创建的确切类。
工厂方法是构造特定接口的具体类的虚拟方法。您的代码的客户端可以提供一个覆盖该方法的对象,以选择他们希望您创建的类。在您的代码中可能如下所示:
IMyInterface x = factory.Create();
factory
由客户端传入,并实现一个包含 Create() 的接口——他们可以决定确切的类。
如果您有相关对象的层次结构并且需要能够编写只与基本接口对话的代码,则应该使用抽象工厂。抽象工厂包含多个工厂方法,它们从每个层次结构中创建一个特定的具体对象。
在四人组的《设计模式》一书中,他们给出了一个带有房间、墙壁和门的迷宫的例子。客户端代码可能如下所示:
IRoom r = mazeFactory.CreateRoom();
IWall nw = mazeFactory.CreateWall();
IWall sw = mazeFactory.CreateWall();
IWall ew = mazeFactory.CreateWall();
IWall ww = mazeFactory.CreateWall();
r.AddNorthWall(nw);
r.AddSouthWall(sw);
r.AddEastWall(ew);
r.AddWestWall(ww);
(等等)
确切的混凝土墙、房间、门可以由 mazeFactory 的实现者决定,它将实现您提供的接口(IMazeFactory)。
因此,如果您提供接口或抽象类,您希望其他人实现和提供它们——那么工厂是他们为您的代码提供一种在您需要时构造其具体类的方法的一种方式。
工厂在本地化中被大量使用,您可以在屏幕上为每个市场提供不同的布局、提示和外观/感觉。您让屏幕工厂根据您的语言创建屏幕,并根据其参数创建适当的子类。