Let's suppose I have a widget class:
struct Widget {
public Color Color { get; set; }
public int Frobbles { get; set; }
}
Now, I need to make a factory to create these widgets, so I build a WidgetFactory:
abstract class WidgetFactory {
public virtual Widget GetWidget();
}
As it turns out, you can make widgets out of several different materials, but the resulting widgets are pretty much the same. So, I have a few implementations of 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
}
}
My question is this: Should WidgetFactory be an abstract class, or an interface? I can see arguments in both directions:
Base class:
List<Widget> WidgetFactory.GetAllWidgets()
method)Interface:
To those answering, this does not (currently) parallel to any real-world problem, but if/when I need to implement this pattern, it would be good to know. Also, "it doesn't matter" is a valid answer.
Edit: I should point out why go through this in the first place. The hypothetical usage of this class hierarchy would be something like:
//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);
So, having a GetGoldWidget()
method in WidgetFactory is not a very good idea. Plus, perhaps advents in Widget technology allow us to add different and more exotic types of widgets in the future? It's easier and cleaner to add a new class to handle them than shoehorn a method into an existing class.
In the example that you have given WidgetFactory
has absolutely no reason to be an abstract class since there are not shared attributes or methods between different implementations of the factory.
Even if there was shared functionality, it would be more idiomatic to make an interface and pass it around to the users of WidgetFactory
, to reduce the mount of knowledge those components need to have about the factory.
The overall implementation is fine and is really an abstract factory pattern, the only addition I would do is 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();
//...
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With