满足开放/封闭原则的工厂模式?

我有以下具体的Animal产品: DogCat

我正在使用参数化的Factory方法来创建所述产品。 根据传递给Factory方法的AnimalInfo参数,将创建具体产品。 映射逻辑放在Factory方法中。

这是我的代码:

  public abstract class AnimalInfo { public abstract String Sound { get; } } public class DogInfo : AnimalInfo { public override string Sound { get { return "Bark"; } } } public class CatInfo : AnimalInfo { public override string Sound { get { return "Meow"; } } } public abstract class Animal { public abstract void Talk(); } public class Dog : Animal { private readonly DogInfo _info; public Dog(DogInfo aInfo) { _info = aInfo; } public override void Talk() { Console.WriteLine(_info.Sound); } } public class Cat : Animal { private readonly CatInfo _info; public Cat(CatInfo aInfo) { _info = aInfo; } public override void Talk() { Console.WriteLine(_info.Sound); } } 

这是我的Factory方法及其逻辑:

 public static class AnimalFactory { public static Animal CreateAnimal(AnimalInfo aInfo) { if (aInfo is DogInfo) return new Dog(aInfo as DogInfo); if (aInfo is CatInfo) return new Cat(aInfo as CatInfo); return null; } } 

我在这里看到的问题是Factory方法本身违反了Open / Closed原则 ,如果我添加一个新的Animal,我将需要修改Factory方法以反映新的映射。

有没有办法通过反思使创作更“动态”? 更重要的是,我的设计中是否有任何反模式?

简单的方法是让AnimalInfo本身成为工厂:

 public abstract class AnimalInfo where T: Animal { public abstract String Sound { get; } public abstract T CreateAnimal(); } 

DogInfo的实现:

 public class DogInfo : AnimalInfo { public override string Sound { get { return "Bark"; } } public override Dog CreateAnimal() { return new Dog(this); } } 

如果您想要,您可以保留当前的静态工厂:

 public static class AnimalFactory { public static Animal CreateAnimal(AnimalInfo aInfo) { return aInfo.CreateAnimal(); } } 

不完全严格遵守工厂模式,IMO,但不再违反您的开/关原则。

让我稍微回避一下。 SOLID原则很好。 但是在某些方面意识到原则已经破裂,甚至SOLID术语的创始人都承认这一事实。 是的,您希望遵循单一责任,开放/关闭等,但是当您这样做时,必须知道如何创建所有那些与单一职责完全脱钩的事物。

考虑一下Bob叔叔关于代码中ifs和switch的说法。 “只有一次。” 按理说,长时间或switch确实会违反SRP和OCP。 如果你有一次违规,那没关系

所以,继续吧,拥有你的

 if (a) return x; else if (b) return y; else if (c) return z; else throw new InvalidOperationException(); 

拥有一次。 是的,这违反了OCP。 是的,它可能违反了SRP。 但某些地方必须要做的事情 关键是减少那些事情和那些事情的数量。

如果您正在寻找基于reflection的方法,您可以执行以下操作…

 public static class AnimalFactory { public static Animal CreateAnimal(Type animalType) { return Activator.CreateInstance(animalType) as Animal; } public static Animal CreateAnimal(string animalType) { Type type = Assembly.GetExecutingAssembly().GetType(animalType); return Activator.CreateInstance(type) as Animal; } }