假设我有一个小部件类:
struct Widget {
public Color Color { get; set; }
public int Frobbles { get; set; }
}
现在,我需要创建一个工厂来创建这些小部件,所以我构建了一个WidgetFactory:
abstract class WidgetFactory {
public virtual Widget GetWidget();
}
事实证明,你可以用几种不同的材料制作小部件,但结果小部件几乎是一样的。所以,我有一些WidgetFactory的实现:
class GoldWidgetFactory : WidgetFactory {
public GoldWidgetFactory(GoldMine goldmine) {
//...
}
public Widget GetWidget() {
Gold g = goldmine.getGold();
//...
}
}
class XMLWidgetFactory : WidgetFactory {
public XMLWidgetFactory(XmlDocument xmlsource) {
//...
}
public Widget GetWidget() {
XmlNode node = //whatever
//...
}
}
class MagicWidgetFactory : WidgetFactory {
public Widget GetWidget() {
//creates widget from nothing
}
}
我的问题是:WidgetFactory应该是一个抽象类还是一个接口?我可以在两个方向看到论点:
基类:
List<Widget> WidgetFactory.GetAllWidgets()
方法)接口:
对于那些回答的人来说,这并不(目前)与任何现实世界的问题并行,但如果/当我需要实现这种模式时,最好知道。此外,“无所谓”是一个有效的答案。
编辑:我应该指出为什么要首先考虑这个问题。这个类层次结构的假设用法类似于:
//create a widget factory
WidgetFactory factory = new GoldWidgetFactory(myGoldMine);
//get a widget for our own nefarious purposes
Widget widget = factory.GetWidget();
//this method needs a few widgets
ConsumeWidgets(factory);
因此,在WidgetFactory中使用GetGoldWidget()
方法并不是一个好主意。另外,Widget技术的出现也许让我们在未来添加不同的,更奇特的小部件类型?添加一个新类来处理它们比将现有类中的方法变为现有类更简单,更清晰。
答案 0 :(得分:5)
在您给出WidgetFactory
的示例中,绝对没有理由成为抽象类,因为工厂的不同实现之间没有共享属性或方法。
即使有共享功能,创建一个接口并将其传递给WidgetFactory
的用户也会更加惯用,以减少这些组件对工厂所需的知识量。
整体实施很好,实际上是abstract factory pattern,我唯一要做的就是IWidgetFactory
:
public interface IWidgetFactory {
Widget GetWidget();
}
abstract class WidgetFactory : IWidgetFactory {
//common attributes and methods
}
//Defferent implementations can still inherit from the base abstract class
class GoldWidgetFactory : WidgetFactory {
public GoldWidgetFactory(GoldMine goldmine) {
//...
}
public Widget GetWidget() {
Gold g = goldmine.getGold();
//...
}
}
答案 1 :(得分:3)
在这种情况下,我认为使用抽象类而不是接口没有任何好处。
我通常更喜欢接口而不是抽象类:
但是,在这种情况下,您可以轻松使用委托,因为只有一种方法...基本上是Func<Widget>
。
我不同意Larry关于使用单个工厂直接使用单独方法创建所有小部件的想法 - 因为您可能希望将WidgetFactory
作为依赖项传递给另一个不需要了解的类来源,但需要在不同的时间或可能多次调用CreateWidget
。
但是,您可以拥有一个小工具工厂,其中包含多个方法,每个方法都返回Func<Widget>
。这样可以获得单个工厂类的好处,而也允许依赖注入“工厂”概念。
答案 2 :(得分:0)
您不需要继承或接口,甚至不需要多个类。单个工厂应该制作所有不同类型的小部件;您可以将材质作为参数传递给create方法。这个想法是隐藏来自调用者的不同构造对象的方面 - 通过制作一堆你正在暴露它的不同类,而不是隐藏它。
答案 3 :(得分:0)
老实说,除了Concrete Factory类之外,你还希望从WidgetFactory继承吗?什么?......永远? 如果不是,它可能不重要。 如果您希望在它们之间添加公共代码,那么除了抽象类之外,您最好的选择。 此外,我并不认为您的工厂方法需要实现除创建方法之外的任何其他接口。因此无论是抽象还是界面都无关紧要。这一切都归结为将来您是否希望在将来向抽象类添加其他功能。