ilitirit
ilitirit

Reputation: 16352

What are the differences between the Builder, Factory Method, and Abstract Factory patterns?

A program receives a list of Messages (base type). Each message in the list has to be processed according to it's type (descendant type). However, different messages need different inputs in order to be processed correctly.

What is the following technique called? (I haven't checked this code in a compiler)

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();     
}

And this one?

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");
    }
}

And what is it called if I can inject the ProcessBuilder class into a MessageProcessor (using a property or Setter) and then call Process?

What technique would be the best pattern for solving this problem?

Upvotes: 12

Views: 4889

Answers (2)

DaSteph
DaSteph

Reputation: 149

In my understanding factory method defnies the abstract type of class with which to work with but delegates the creation of the concrete type to the succeeding/implementing classes. Abstract factory would define an interface for a manufactorer of a set of corresponding classes. A builder works simply to build an object step by step giving some control to the calling instance.

Upvotes: 2

Mark Cidade
Mark Cidade

Reputation: 99957

They are both examples of the factory method pattern. The only difference is that the second example has the method in its own static class.

This would be an example of the abstract factory pattern:

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

Each MessageProcessor gets its own factory class which makes use of polymorphism.

Passing a ProcessBuilder to create the process would be the strategy pattern:

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());

The simplest solution would be to encapsulate a factory method:

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

If it's a small known number of types, you can use the series of type checks:

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

Otherwise use a dictionary:

Dictionary<Type,MessageProcessor> processors;    

private static MessageProcessor getProcessor(Type msgType) 
 { return processors[msgType];
 }

Upvotes: 10

Related Questions