2011-10-06 75 views
2

我正在设计一个系统,让用户在按下按钮时指定要执行的特定任务。要执行的任务可以分配给各种事物。所以我有一个名为“ButtonTask”的抽象基类,并且所有其他任务都从此基类继承,以实现要执行的任务以及需要知道的相关数据。这样我就可以使用多态性来抽象出所有的细节,我只需调用“PerformTask”而不必关心它实际是什么类型。到现在为止还挺好。工厂模式 - 是否有多个工厂是一个好主意?

实际任务本身可以通过不同的方式设置,用户可以通过UI菜单更改任务,可以从文件中读取任务,也可以通过网络消息远程设置任务。

目前我有一个工厂函数,将根据网络消息创建正确的派生类型,并返回一个指向基类型的指针。问题在于用户界面菜单和文件阅读感觉像他们需要自己的工厂方法来创建对象,因为它们本质上是彼此不同的。对于这种问题,有多个工厂通常是一个好主意?我无法想出解决这个问题的另一种方法,但也许我能做些更好的事情。

回答

1

我看到实现多个工厂方法的唯一好理由是,如果您希望能够使用不同的初始属性集创建对象,例如允许调用者指定某些属性并为其他设置默认值 - 相当于拥有多个公共构造函数。

如果想法是这些任务独立于它们的启动方式(GUI,网络等),那么我认为不需要单独的工厂方法。相反,我会说工厂的职责之一就是实现这种抽象。换句话说,从代码的三个不同部分调用同一工厂是绝对好的。不过,将工厂方法设为静态或将工厂设置为单例对象可能是一个好主意。

另一方面,如果您有一种情况,某些任务只能从网络和GUI中的其他人发起,并且只有少数人可以通过三种方式启动,那么重新考虑这种情况可能是值得的设计一下。然后,您应该考虑添加另一个级别的抽象任务类,例如CommonTask,GuiTask,NetworkTask,FileTask,并且为他们设置工厂而不是ButtonTask。这显然更复杂,它是否值得它取决于任务类的数量和代码的结构。

你想避免的情况是工厂的用户知道他们可以从工厂接收哪些ButtonTask的特定子类。这是一个“假基类”的情况,也就是说,基类不是整个子类集合的真正抽象,并且通过添加如上所述的额外子类层就可以摆脱它。

除此之外,你可能还想考虑重命名ButtonTask;这听起来像是一个仅从名称开始的GUI任务。

+0

所有的任务都可以从任何方法(UI,netowrk,file)中设置。所以我同意你的观点,只有一个工厂是合理的。但是,我不知道如何实现这一点,因为与UI相关的数据结构,netowrk消息和文件以固有不同的方式存储任务的数据。我不希望我的工厂必须知道这些不同的数据结构,但我怎么能把数据放到一个通用的工厂将能够处理的?我不会最终需要3种不同的方式为工厂创建通用数据吗?这似乎打败了这一点。 – oggmonster

+0

嗯,是的,你需要从相应的发起人提取相关数据到工厂要求的形式,这应该是不知道它是如何调用和由谁。如果配置很复杂,你可以让工厂接受一个TaskConfig对象,而TaskConfig是一个抽象类(或接口),它允许检索必要的数据。然后,将其分类到UiTaskConfig,NetworkTaskConfig和FileTaskConfig,并使其成为各个任务启动器的职责,正确填充这些对象并将它们传递给工厂。 – Uffe