这是我通常看到显示的抽象工厂模式的方式:
public abstract class Factory
{
public abstract Product GetProduct();
}
public class ConcreteFactory1 : Factory
{
public override Product GetProduct() { return new Product1(); }
}
class ConcreteFactory2 : Factory
{
public override Product GetProduct() { return new Product2(); }
}
interface Product
{
void SomeMethod();
}
class Product1 : Product
{
public void SomeMethod() { Console.WriteLine("1"); }
}
class Product2 : Product
{
public void SomeMethod() { Console.WriteLine("2"); }
}
class Program
{
static void Main(string[] args)
{
Factory f = null;
Product p = null;
switch (args[0])
{
case "1":
f = new ConcreteFactory1();
p = f.GetProduct();
break;
case "2":
f = new ConcreteFactory2();
p = f.GetProduct();
break;
}
p.SomeMethod();
}
}
我通常这样写,这不是真正的模式:
interface Product
{
void SomeMethod();
}
class Product1 : Product
{
public void SomeMethod() { Console.WriteLine("1"); }
}
class Product2 : Product
{
public void SomeMethod() { Console.WriteLine("2"); }
}
public static class Factory
{
public static Product GetProduct(prodType)
{
Product p = null;
switch (prodType)
{
case "1":
p = new Product1();
break;
case "2":
p = new Product2();
break;
}
return p;
}
}
class Program
{
static void Main(string[] args)
{
Product p = Factory.GetProduct(args[0]);
p.SomeMethod();
}
}
我的问题是 - 具体工厂的优势是什么?我从来没有理解这一点 - 它似乎只是添加了另一个不必要的层。第二个例子似乎更简洁明了。
答案 0 :(得分:7)
因为Odrade同意我的意见(猜测我不是完全不在我的摇杆),我会发布这个答案:
我想,如果我弄错了,请纠正我,通常你的基础代码没有使用具体工厂的概念。它也不关心通过prodType指定(在您的情况下)产品类型。相反,具体的工厂实现通过某种形式的依赖注入提供给您的抽象工厂,并且您的代码以其快乐的方式进行,而没有任何关于使用什么工厂或所需的具体类型的概念。特别是如果那些具体的工厂实现是由您的API的第三方消费者提供的。
关于它的维基百科文章提供了关于操作系统GUI构建的一个很好的例子:http://en.wikipedia.org/wiki/Abstract_factory_pattern#C.23
基本上,您的库中的代码可以正常运行,而无需了解所使用的操作系统的任何实现细节或依赖性。当您(或您的API的消费者)然后转移到Linux(在此Wikipedia示例中)时,您只需实现LinuxFactory
和LinuxButton
并将其提供给您的API。相反,如在典型示例中,您通过输入控制它,比如枚举,那么您的工厂需要了解Linux:
public static class Factory
{
public static Button GetButton(operatingSystem)
{
switch (operatingSystem)
{
case "windows":
return new WindowsButton();
case "macintosh":
return new MacButton();
}
}
}
现在如何考虑Linux?好吧,除非你添加支持,否则它不能。此外,现在,API的所有消费者都间接依赖于所有操作系统实现。
编辑:请注意,Factory Pattern
和Abstract Factory Pattern
是两个完全不同的概念。关于您首先询问问题的原因,抽象工厂模式并不总是必要的。如果您不需要,那么不要添加一个的复杂性。如果你只需要一个简单的工厂(你的第二个例子是变体),那就用它吧。正确的工作和正确的工作。
答案 1 :(得分:2)
我会将您的方法称为工厂模式,这与抽象工厂不同。
答案 2 :(得分:1)
具体工厂的优势是什么?我从来没有理解这一点 - 它似乎只是添加了另一个不必要的层
工厂(一般来说 - 工厂方法,抽象工厂等)用于解决复杂创建类型的对象,如果Product1
和Product2
需要不同类型的初始化,那么它不会是一个好的想在你的混凝土工厂硬编码。
答案 3 :(得分:1)
“抽象工厂”对于这种模式来说真是个坏名字。一个更好的名称是GoF也使用的“Kit”模式。我同意,在你给出的例子中,它是过度设计的。当你的工厂有责任创建许多可以协同工作的对象时,它会更有意义。然后,在给定的运行时或设计时条件下,由不同的工厂创建它们的不同组(工具包,如果您将)。
This is a really good article about it.公式与英语套接字集的非软件类比是完美的。