Reputation: 25312
Classical implementation of Abstract Factory/Factory method is based on polymorphism. But on the lowest level we have to have some kind of factory which is not based on polymorphism and breaks open-closed principle:
public Device Create(string deviceName)
{
switch (deviceName)
{
case "Device1": return new Device1();
case "Device2": return new Device2()'
default: throw new NotSupportedDeviceException(deviceName);
}
}
Is there any special name for this kind of factories?
Upvotes: 3
Views: 1616
Reputation: 18213
If you want to respect the open-closed principle in your function by allowing the factory to be extensible, then you can use the dependency injection pattern to configure the factory as shown in the answer by brahmagupta.
To answer the specific question as to whether there is a special name for the pattern you showed, the answer is no. It is still considered an example of the factory method pattern.
Upvotes: 2
Reputation: 1898
This is indeed a Factory Method and there's nothing wrong with using concrete classes as their construction logic may vary and that's where Factory can be useful.
But in this particular case you can use reflection or IoC containers to achieve low coupling.
For example, if you're using C# and Common Service Locator abstraction, you can then register your Device implementations with names and then you wouldn't even need a factory at all, because it'd look like:
public Device Create(string deviceName)
{
return ServiceLocator.Current.GetInstance<Device>(deviceName);
}
Upvotes: 0
Reputation: 71
public class Factory
{
private Map<String, Device> devices;
public Factory(Map<String, Device> devices)
{
this.devices = devices;
}
public Device Create(String deviceName)
{
return devices.get(deviceName);
}
}
Configure the map using dependency injection.
Upvotes: 7
Reputation: 3575
From what I can see, you've posted a perfectly valid example of the Factory Method pattern:
It's true, the internal implementation is a little heavy-handed (switch-case). However, that doesn't make it any less of a true Factory Method pattern.
I don't really see where your example "isn't based on polymorphism" nor where it "breaks the open/closed principle". If I've missed the point entirely, feel free to update your post, to help us zero in on your question.
Now if the Factory method was taking the passed deviceName, and using it to find an exact match of the concrete class to instantiate (using reflection), that would absolutely break the Factory Method pattern, because the caller would have to have intimate knowledge of the different concrete classes. But as currently written, the passed deviceName is just a piece of data used in the decision-making process - it doesn't break the encapsulation of the factory pattern.
Upvotes: 8
Reputation: 7389
You are talking about the AbstractFactory Factory, right? One way to avoid what you're talking about is through configuration. If the correct factory is chosen based on some parameters or setup, then you don't necessarily have this issue. For example, each Device your software is deployed on would specify a different concrete instance to use. This could be done manually or through dependency injection. If it really needs to be a runtime decision, then I am not sure what else you could do.
Upvotes: 3