Каковы различия между шаблонами Builder, Factory Method и Abstract Factory? - PullRequest
12 голосов
/ 08 октября 2008

Программа получает список сообщений (базовый тип). Каждое сообщение в списке должно быть обработано в соответствии с его типом (тип потомка). Однако для правильной обработки разных сообщений требуются разные входные данные.

Как называется следующая техника? (Я не проверял этот код в компиляторе)

abstract class MessageProcessor
{
    public static MessageProcessor GetProcessor(Message message, DataDomain data)
    {
        if (message.GetType() == typeof(FooMessage))
        {
            return new FooMessageProcessor(message, data.Name, data.Classification);

        }
        else if (message.GetType() == typeof(BarMessage))
        {
            return new BarMessageProcessor(message, data.AccountNo, data.CreditLimit);

        }
        else
            throw new SomeException("Unrecognized type");

    }

    public abstract void Process();     
}

А этот?

static class MessageProcessorFactory
{
    public static MessageProcessor GetProcessor(Message message, DataDomain data)
    {
        if (message.GetType() == typeof(FooMessage))
        {
            return new FooMessageProcessor(message, data.Name, data.Classification);

        }
        else if (message.GetType() == typeof(BarMessage))
        {
            return new BarMessageProcessor(message, data.AccountNo, data.CreditLimit);

        }
        else
            throw new SomeException("Unrecognized type");
    }
}

И как это называется, если я могу добавить класс ProcessBuilder в MessageProcessor (используя свойство или метод Setter) и затем вызвать Process?

Какая техника была бы лучшей моделью для решения этой проблемы?

Ответы [ 2 ]

10 голосов
/ 08 октября 2008

Они оба являются примерами фабричного метода . Разница лишь в том, что второй пример имеет метод в своем собственном статическом классе.

Это будет пример абстрактной фабрики шаблона:

abstract class MessageProcessorFactory
 { public abstract MessageProcessor GetProcessor
                                     (Message message, DataDomain data);
 }

class FooMessageProcessorFactory :  MessageProcessorFactory
 { public override MessageProcessor GetProcessor
                                     (Message message, DataDomain data)
    { return new FooMessageProcessor(data.Name, data.Classification);
    }
 }

Каждый MessageProcessor получает свой собственный фабричный класс, который использует полиморфизм.

Передача ProcessBuilder для создания процесса будет стратегия шаблон:

class MessageProcessor
 { ProcessBuilder builder;

   public MessageProcessor(ProcessBuilder builder)
    { this.builder = builder;
    }

   public void Process()
    { builder.BuildMessage();
      builder.BuildProcess();
      builder.Process();
    }
 }

var mp = new MessageProcessor(new FooProcessBuilder());

Самое простое решение - инкапсулировать фабричный метод:

static void Process(Message msg, DataDomain data)
 { var p = getProcessor(msg.GetType());
   p.Process(msg, data);
 }

Если известно небольшое количество типов, вы можете использовать серию проверок типов:

private static MessageProcessor getProcessor(Type msgType)
 { return   (msgType == typeof(FooMessage)) ? new FooMessageProcessor()
          : (msgType == typeof(BarMessage)) ? new BarMessageProcessor()
          :                                   new DefaultMessageProcessor();
 }

В противном случае используйте словарь:

Dictionary<Type,MessageProcessor> processors;    

private static MessageProcessor getProcessor(Type msgType) 
 { return processors[msgType];
 }
2 голосов
/ 09 октября 2008

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...