Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 424
ilitirit Avatar asked Oct 08 '08 16:10

ilitirit


1 Answers

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];
 }
like image 126
Mark Cidade Avatar answered Nov 12 '22 19:11

Mark Cidade