C# 这是表示抽象工厂模式的好例子吗

C# 这是表示抽象工厂模式的好例子吗,c#,factory-pattern,C#,Factory Pattern,希望检查这是否是表示抽象工厂模式的好例子。 这是主题 戴尔(工厂)生产xps(产品) 戴尔(工厂)生产inspiron(产品) hp(工厂)制造商(产品) hp(工厂)生产presario(产品) 百思买销售电脑 //Abstract factory abstract class ComputerFactory { public abstract Computer BuildComputer(Computer.ComputerType compType); } //Concrete f

希望检查这是否是表示抽象工厂模式的好例子。 这是主题 戴尔(工厂)生产xps(产品) 戴尔(工厂)生产inspiron(产品) hp(工厂)制造商(产品) hp(工厂)生产presario(产品)

百思买销售电脑

//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;
    }
}

提前感谢。

这是一个很好的模式部分示例。对象的基本构造是一个不错的例子,但是,逻辑依赖于单个
计算机.ComputerType
enum。此枚举需要提前知道每个工厂公开的每种类型的计算机

通常,使用抽象工厂的动机是将这种类型的硬编码需求从图中抽象出来。与其使用单个枚举,不如添加一个
ComputerType
类,并允许工厂返回可用类型的集合。然后,您可以使用返回的
ComputerType
构建新系统

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

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


在本例中,您正在将已知类型“硬编码”到枚举中,这违反了模式的这一部分。

我不是工厂模式专家,但这里有两件事我会做得不同:

  • 我将使用接口而不是抽象类。因此,如果“戴尔”需要从另一个类继承,那么它可以而且仍然能够通过实现IComputerFactory成为一个计算机工厂
  • 另一件小事是在构建计算机功能中使用“开关”而不是“if/else if”。谁知道你最终会拥有多少台电脑
  • 您如何知道Hp和Dell之间使用哪家混凝土工厂?您可以使用类似“”的内容来“解析”要使用的工厂

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

//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;
    }
}

您好,我还添加了客户机类。我理解您对使用computertype作为枚举的担忧。Thanks@saidevakumar:这显示了问题所在。“百思买”需要提前了解每一种潜在的电脑类型。比如说戴尔现在除了两条生产线之外还推出了一台“XPQ”电脑。您必须更改API、更改客户端代码等。如果要添加第三个品牌,必须将其添加到枚举中。通过让工厂提供他们可以创建的类型,你就消除了这种需要……更糟糕的是,如果两个计算机制造商生产出一个同名的型号怎么办?