Interfaces vs. inheritance: which is better in this case?

Suppose I have a widget class:

struct Widget { public Color Color { get; set; } public int Frobbles { get; set; } } 

Now I need to create a factory to create these widgets, so I create a WidgetFactory:

 abstract class WidgetFactory { public virtual Widget GetWidget(); } 

As it turned out, you can make widgets from several different materials, but the resulting widgets are almost the same. So, I have several 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 a WidgetFactory be an abstract class or interface? I see arguments in both directions:

Base class:

  • Implementations of ARE WidgetFactories
  • They may be able to use functionality (for example, the List<Widget> WidgetFactory.GetAllWidgets() method)

Interface:

  • Implementations do not inherit any data or functionality from the parent
  • Their inner workings are completely different.
  • Only one method defined

For those who answer, this is not (at present) parallel to any real problem, but if / when I need to implement this template, it would be nice to know. Also, “it doesn't matter” is the correct answer.

Edit: I must indicate why this is happening in the first place. A hypothetical use of this class hierarchy would be something like this:

 //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 the GetGoldWidget() method in a WidgetFactory is not a good idea. Plus, maybe adventures 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 for processing than the shoehorn method in an existing class.

+4
source share
4 answers

Honestly, what else, besides the Concrete Factory classes, do you expect inheritance from WidgetFactory? Anything? ... ever? If not, it probably never matters. If you want to add common code between them along the way, then your abstract class would be the best option. Also, I really don't see the need for Factory methods to implement any other interface other than what is used for your create method. Therefore, it does not matter whether it is abstract or an interface. It all comes down to the fact that in the future you want to add additional functionality in the future to an abstract class.

0
source

In the example you provided WidgetFactory , there is absolutely no reason to be an abstract class, since there are no common attributes or methods between the various factory implementations.

Even if there was general functionality, it would be more idiomatic to create an interface and pass it on to WidgetFactory users in order to reduce the level of knowledge that these components should have about the factory.

The overall implementation is beautiful and really is an abstract factory template , the only addition I would make 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(); //... } } 
+5
source

In this case, I do not see the advantage of using an abstract class instead of an interface.

I would generally welcome interfaces over abstract classes:

  • They do not use your only opportunity when inheriting a class.
  • They are easier to fool.
  • They feel “cleaner” in some way (it’s clear from the interface that the developer must provide, you don’t need to check each method to see if it is concrete, abstract or virtual).

In this case, however, you can easily use a delegate, since there is only one method ... basically Func<Widget> .

I disagree with Larry’s idea of ​​simply using a single factory to directly create all widgets using separate methods - since you can pass the WidgetFactory as a dependency to another class that should not know about the source, but you need to call CreateWidget either at another time, or maybe , repeatedly.

However, you can have one factory widget with several methods, each of which returns a Func<Widget> . This would give the advantage of having one factory class, as well as allowing dependency injection of the concept of “factory”.

+3
source

You do not need inheritance or an interface or even more than one class. The only factory should do all kinds of widgets; you can simply pass materials as a parameter to the creation method. The idea is to hide aspects of the different construction of objects from the caller - by creating a bunch of different classes that you expand, rather than hide.

0
source

All Articles