For example I have classes Apple, Orange , Banana , etc.. inherited from Fruit . Also I have enum Fruits
enum Fruits
{
Apple,
Orange,
Banana
}
I want to create correct instance depending on enum parameter.
I know about simple factory.
public Fruit CreateFruit(enum Fruits fruits)
{
switch (fruits)
{
case Apple:
return new Apple();
case Orange:
return new Orange();
case Banana:
return new Banana();
}
}
But this method violates the Open-Closes Principle (OCP), so are there better solutions?
There is no real way to avoid such a factory while using an enum. But you could replace the enum with an factory object, something like:
With this pattern you would pass around a
IFruitFactoryinstead of a fruit enum, allowing anyone to easily constrct a fruit from it. If you want to add a Banana you just create a newBananaFactory.But I would recommend being pragmatic. The problem with switch-methods as in your example is when someone forgets to add a case when adding a new value, putting the factory close to the enum declaration, i.e. in the same file, help reduce this risk.
As is often the case, rules like 'open-close principle' are general recommendations, but you need to know why they exist and when they are applicable. Trying to dogmatically follow all design principles is just not a good idea.