Это хороший пример для представления абстрактной фабричной модели - PullRequest
6 голосов
/ 24 февраля 2011

Хотите проверить, является ли это хорошим примером для представления абстрактного фабричного шаблона.Вот тема, которую Dell (Фабрика) делает xps (Продукт). Dell (Фабрика) делает inspiron (Продукт) hp (Фабрика) делает посланника (Продукт).

//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 ]

8 голосов
/ 24 февраля 2011

Это хороший пример частей шаблона.Базовая конструкция объектов является достойным примером, однако логика основана на единственном перечислении Computer.ComputerType.Это перечисление должно заранее знать каждый тип компьютера, выставляемого каждой фабрикой.

Часто мотивация для использования абстрактной фабрики состоит в том, чтобы абстрагировать этот тип жестко закодированных требований от картинки.Вместо одного перечисления может быть лучше добавить класс ComputerType и позволить фабрике возвращать коллекцию доступных типов.Затем вы могли бы использовать ComputerType, возвращаемый для создания новых систем.

Это позволяет вам добавлять другие фабрики без изменения вашего API, что является одним из основных преимуществ абстрактного шаблона фабрики.Прочтите Абстрактный шаблон фабрики - один из основных пунктов:

Клиент не знает (или не заботится), какие конкретные объекты он получает от каждой из этих внутренних фабрик.поскольку он использует только общие интерфейсы своих продуктов.

В этом случае вы «жестко кодируете» известные типы в enum, что нарушает эту часть шаблона.

3 голосов
/ 24 февраля 2011

Я не эксперт по фабричным шаблонам, но вот несколько вещей, которые я бы сделал по-другому:

  • Вместо абстрактного класса я бы использовал интерфейс.Так что, если «Dell» нужно унаследовать от другого класса, он может и все еще может быть ComputerFactory, например, путем реализации IComputerFactory.
  • Другая небольшая вещь - это использование «switch» вместо «if / elseif "в вашей функции BuildComputer.Кто знает, сколько компьютеров вы можете получить в итоге.
  • Как вы узнаете, какую конкретную фабрику использовать между Hp и Dell?Вы можете использовать что-то вроде « Autofac », чтобы «решить», какую фабрику использовать.
0 голосов
/ 05 июля 2012

Я думаю, что в предоставленном вами сценарии и коде есть только один тип продукта, то есть «Компьютер».Там нет семейства продуктов, участвующих.Таким образом, абстрактный шаблон фабрики здесь не применим.Вместо фабричного образца можно использовать здесь.Я изменил код ниже для понимания.

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