这是表示抽象工厂模式的一个很好的例子

时间:2011-02-24 18:50:54

标签: c# factory-pattern

想要检查这是否是表示抽象工厂模式的好例子。 这是主题 戴尔(工厂)生产xps(产品) 戴尔(工厂)生产inspiron(产品) 惠普(工厂)使特使(产品) hp(工厂)制作presario(产品)

BestBuy销售电脑。

//Abstract factory
abstract class ComputerFactory
{
    public abstract Computer BuildComputer(Computer.ComputerType compType);
}

//Concrete factory
class Dell : ComputerFactory
{
    public override Computer BuildComputer(Computer.ComputerType compType)
    {
        if (compType == Computer.ComputerType.xps)
            return (new xps());
        else if (compType == Computer.ComputerType.inspiron)
            return new inspiron();
        else
            return null;
    }
}

//Concrete factory
class Hp : ComputerFactory
{
    public override Computer BuildComputer(Computer.ComputerType compType)
    {
        if (compType == Computer.ComputerType.envoy)
            return (new envoy());
        else if (compType == Computer.ComputerType.presario)
            return new presario();
        else
            return null;
    }
}

//Abstract product
public abstract class Computer
{
    public abstract string Mhz { get; set; }
    public enum ComputerType
    {
        xps,
        inspiron,
        envoy,
        presario
    }
}

//Concrete product for DELL
public class xps : Computer
{
    string _mhz = string.Empty;

    public override string Mhz
    {
        get
        {
            return _mhz;
        }
        set
        {
            _mhz = value;
        }
    }
}

//Concrete product for DELL
public class inspiron : Computer
{
    string _mhz = string.Empty;

    public override string Mhz
    {
        get
        {
            return _mhz;
        }
        set
        {
            _mhz = value;
        }
    }
}

//Concrete product for HP
public class envoy : Computer
{
    string _mhz = string.Empty;

    public override string Mhz
    {
        get
        {
            return _mhz;
        }
        set
        {
            _mhz = value;
        }
    }
}

//Concrete product for HP
public class presario : Computer
{
    string _mhz = string.Empty;

    public override string Mhz
    {
        get
        {
            return _mhz;
        }
        set
        {
            _mhz = value;
        }
    }
}

public class BestBuy
{
    ComputerFactory compFactory;
    Computer comp;
    public BestBuy(Computer.ComputerType compType)
    {
        if (compType == Computer.ComputerType.xps || compType == Computer.ComputerType.inspiron)
            compFactory = new Dell();
        else
            compFactory = new Hp();

        comp = compFactory.BuildComputer(compType);
    }

    public Computer Sell()
    {
        return comp;
    }
}

提前致谢。

3 个答案:

答案 0 :(得分:8)

这是模式部分的一个很好的例子。对象的基本构造是一个不错的例子,然而,逻辑依赖于单个Computer.ComputerType枚举。这个枚举需要事先知道每个工厂暴露的每种类型的计算机。

通常,使用抽象工厂的动机是从图片中抽象出那种类型的硬编码要求。最好不要使用单个枚举,而是添加ComputerType类,并允许工厂返回可用类型的集合。然后,您可以使用返回的ComputerType来构建新系统。

这允许您在不更改API的情况下添加其他工厂,这是抽象工厂模式的主要优势之一。阅读Abstract Factory Pattern - 其中一个要点是:

  

客户端不知道(或关心)从每个内部工厂获得的具体对象,因为它只使用其产品的通用接口。

在这种情况下,你将已知类型“硬编码”到枚举中,这违反了模式的这一部分。

答案 1 :(得分:3)

我不是工厂模式专家,但我会采取不同的做法:

  • 我会使用一个接口代替抽象类。因此,如果“戴尔”需要从另一个类继承它,并且仍然可以通过实现IComputerFactory来成为ComputerFactory。
  • 另一个小问题是在BuildComputer函数中使用“switch”而不是“if / else if”。谁知道最后你最终会有多少台计算机。
  • 您如何知道在Hp和戴尔之间使用哪个混凝土工厂?您可以使用“Autofac”之类的内容来“解析”要使用的工厂。

答案 2 :(得分:0)

我认为,在您提供的方案和代码中,只有一种类型的产品,即“计算机”。没有涉及的产品系列。因此,抽象工厂模式不适用于此处。相反,工厂模式可以在这里使用。我修改了下面的代码以便理解。

//Abstract factory
abstract class ComputerFactory
{
    public abstract Computer BuildComputer(Computer.ComputerType compType);
}

public class ConcreteFactory : ComputerFactory
{
    public override Computer BuildComputer(Computer.ComputerType compType)
    {
        if (compType == Computer.ComputerType.xps)
            return (new xps());
        else if (compType == Computer.ComputerType.inspiron)
            return new inspiron();
        else if (compType == Computer.ComputerType.envoy)
            return (new envoy());
        else if (compType == Computer.ComputerType.presario)
            return new presario();
        else
            return null;
    }
}

//Abstract product
public abstract class Computer
{
    public abstract string Mhz { get; set; }
    public enum ComputerType
    {
        xps,
        inspiron,
        envoy,
        presario
    }
}

//Concrete product for DELL
public class xps : Computer
{
    string _mhz = string.Empty;

    public override string Mhz
    {
        get
        {
            return _mhz;
        }
        set
        {
            _mhz = value;
        }
    }
}

//Concrete product for DELL
public class inspiron : Computer
{
    string _mhz = string.Empty;

    public override string Mhz
    {
        get
        {
            return _mhz;
        }
        set
        {
            _mhz = value;
        }
    }
}

//Concrete product for HP
public class envoy : Computer
{
    string _mhz = string.Empty;

    public override string Mhz
    {
        get
        {
            return _mhz;
        }
        set
        {
            _mhz = value;
        }
    }
}

//Concrete product for HP
public class presario : Computer
{
    string _mhz = string.Empty;

    public override string Mhz
    {
        get
        {
            return _mhz;
        }
        set
        {
            _mhz = value;
        }
    }
}

public class BestBuy
{        
    ConcreteFactory compFactory;
    Computer comp;
    public BestBuy(Computer.ComputerType compType)
    {
        comp = compFactory.BuildComputer(compType);            
    }

    public Computer Sell()
    {
        return comp;
    }
}