Подтвердить что ты не робот

Каковы различия между конструкторами Builder, Factory и Abstract Factory?

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

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

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?

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

4b9b3361

Ответ 1

Они являются примерами шаблона метода factory. Единственное отличие состоит в том, что второй пример имеет метод в своем собственном статическом классе.

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

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 получает свой собственный класс factory, который использует полиморфизм.

Передача 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());

Простейшим решением было бы инкапсулировать метод factory:

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

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