我有以下具体的 Animal
产品:Dog
和 Cat
。
我正在使用 parameterized Factory method创造所述产品。根据传递给 Factory 方法的 AnimalInfo
参数,将创建一个具体的产品。映射逻辑放在工厂方法中。
这是我的代码:
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);
}
}
这是我的工厂方法及其逻辑:
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;
}
}
我在这里看到的问题是工厂方法本身违反了 Open/Closed principle这样一来,如果我添加一个新的 Animal,我将需要修改 Factory 方法以反射(reflect)新的映射。
有没有办法通过反射让创作更“动态”?更重要的是,我的设计中是否存在任何反模式?
最佳答案
让我回避一下。 SOLID 原则很好。但意识到在某些时候,原则会崩溃,这个事实甚至 SOLID 术语的创始人也承认。是的,您想要遵循单一职责、开放/封闭等,但是当您这样做时,某物 必须知道如何创建所有那些在其他方面与单一职责很好地分离的东西。
想想 Bob 叔叔所说的关于代码中的 ifs 和 switch 的事情之一。 “只吃一次。”按理说长的if
或者switch
确实会违反SRP和OCP。没关系,如果您有这种违规行为一次。
所以继续吧,有你的
if (a)
return x;
else if (b)
return y;
else if (c)
return z;
else
throw new InvalidOperationException();
并拥有它一次。是的,这违反了 OCP。是的,它可能会违反 SRP。但是某事某处必须。关键是减少那些某事和某处的数量。
关于c# - 满足开放/封闭原则的工厂模式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7876462/