抽象工厂模式 - 具体工厂点

use*_*757 5 c# factory abstract factory-pattern

这是我通常看到显示的抽象工厂模式的方式:

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

我通常这样写它,这不是真正的模式:

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

我的问题是 - 具体工厂的优势是什么?我从来没有理解这一点 - 它似乎只是添加了另一个不必要的层.第二个例子似乎更简洁明了.

Chr*_*air 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();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Linux现在如何被考虑在内?除非添加支持,否则它不能.此外,现在API的所有消费者都间接依赖于所有操作系统实现.

编辑:请注意,Factory Pattern并且Abstract Factory Pattern是两个完全不同的概念.关于您首先询问问题的原因,抽象工厂模式并不总是必要的.如果您不需要,那么不要添加一个的复杂性.如果你只需要一个简单的工厂(你的第二个例子是变体),那就用它吧.正确的工作和正确的工作.