例如,我有类
Apple
、 Orange
、 Banana
等。继承自 Fruit
。我还有enum Fruits
enum Fruits
{
Apple,
Orange,
Banana
}
我想根据枚举参数创建正确的实例。
我了解简单工厂。
public Fruit CreateFruit(enum Fruits fruits)
{
switch (fruits)
{
case Apple:
return new Apple();
case Orange:
return new Orange();
case Banana:
return new Banana();
}
}
但是这种方法违反了开闭原则,那么有没有更好的解决方案呢?
使用枚举时没有真正的方法可以避免这样的工厂。但是您可以用工厂对象替换枚举,例如:
public interface IFruit { }
public class Apple: IFruit { }
public class Orange : IFruit { }
public interface IFruitFactory
{
IFruit Create();
}
public class AppleFactory : IFruitFactory
{
public static readonly AppleFactory Instance = new();
public IFruit Create() => new Apple();
}
public class OrangeFactory : IFruitFactory
{
public static readonly OrangeFactory Instance = new();
public IFruit Create() => new Orange();
}
使用这种模式,您将传递
IFruitFactory
而不是水果枚举,允许任何人轻松地从中构建水果。如果您想添加香蕉,只需创建一个新的 BananaFactory
。
但我建议务实。在您的示例中,开关方法的问题是,当有人在添加新值时忘记添加案例时,将工厂放在靠近枚举声明的位置,即在同一个文件中,有助于降低这种风险。
通常情况下,“开闭原则”等规则是一般性建议,但您需要知道它们为何存在以及何时适用。试图教条地遵循所有设计原则并不是一个好主意。