开发者

Abstract Factory, Factory Method, Builder

It may seem as if this is question is a dupe, but please bear with me - I promise I've read the related posts (and the GOF book).

After everything I've read, I still don't have it clear when to use an Abstract Factory, a Factory Method, or a Builder. I believe it will finally sink in after I see a simple example of a problem which is开发者_Python百科 best approached by, say, a builder and it would be clearly silly to use, say, an abstract factory.

Can you provide a simple example where you would clearly use one pattern and not the others?

I understand it may boil down to a matter of opinion if the example is too simple, but I'm hopeful that if anybody can, that person is in SO.

Thanks.


A builder helps you construct a complex object. An example is the StringBuilder class (Java, C#), which builds the final string piece by piece. A better example is the UriComponentsBuilder in Spring, which helps you build a URI.

A factory method gives you a complete object in one shot (as opposed to the builder). A base class defines a single abstract method that returns an interface (or super class) reference, and defers the concrete creation of the object to subclasses.

An abstract factory is an interface (or abstract class) to create many different related objects. A good example (in .NET) is the DbProviderFactory class, that serves to create related objects (connections, commands, ...) to a given database provider (oracle, sql server, ...), depending on its concrete implementation.


Builder

// Builder encapsulates construction of other object. Building of the object can be done in multiple steps (methods)
public class ConfigurationBuilder
{
  // Each method adds some configuration part to internally created Configuration object
  void AddDbConfiguration(...);
  void AddSmtpConfiguration(...);
  void AddWebServicesConfiguration(...);
  void AddWebServerConfiguration(...);

  // Returns built configuration
  Configuration GetConfiguration();
}

Factory method

// Factory method is declared in base class or interface. Subclass defines what type is created by factory method.
public interface ICacheProvider
{
  ISession CreateCache(); // Don't have to return new instance each time - such decission is part of implementation in derived class.
}

public class InMemoryCacheProvider : ICacheProvider
{ ... }

public class DbStoredCacheProvider : ICacheProvider
{ ... }

// Client code
ICacheProvider provider = new InMemoryCacheProvider
ICache cache = provider.CreateCache(); 

Abstract Factory

// Abstract factory defines families of platform classes - you don't need to specify each platform class on the client.
public interface IDbPlatform
{
  // It basically defines many factory methods for related classes
  IDbConnection CreateConnection();
  IDbCommand CreateCommand();
  ...
}

// Abstract factory implementation - single class defines whole platform
public class OraclePlatfrom : IDbPlatform
{ ... }

public class MySqlPlatform : IDbPlatform
{ ... }

// Client code:
IDbPlatform platform = new OraclePlatform();
IConnection connection = platform.CreateConnection(); // Automatically Oracle related
...


Abstract Factory, Factory Method, Builder : All these patterns are creational patterns,which are design patterns that deal with object creation mechanisms, trying to create objects in a manner suitable to the situation.

Factory method:

  1. It defines an interface for creating an object, but let subclasses decide which class to instantiate
  2. We create an object without exposing the creation logic to the client and refer to newly created object using a common interface ( or an abstract classes)
  3. Provides loose-coupling by eliminating the need to bind application-specific classes into the code. Code interacts only with interface or abstract class
  4. It may use inheritance or sub classing to achieve the purpose

    Key note: You will create an interface & specific implementation of these interfaces. In Factory method, depending on condition, you will get concrete implementation of common interface.

Abstract Factory:

  1. Provide an interface for creating families of related or dependent objects without specifying their concrete classes
  2. A hierarchy that encapsulates: many possible "platforms"`, and the construction of a suite of "products"
  3. Abstract Factory classes are often implemented with Factory Methods, but they can also be implemented using Prototype

Builder:

  1. Builder pattern builds a complex object using simple objects and using a step by step approach
  2. Replacement to Factory method/Abstract Factory in this scenario : Too Many arguments to pass from client program to the Factory class that can be error prone
  3. Some of the parameters might be optional unlike in Factory which forces to send all parameters

Guidelines for Builder design pattern in Java

  1. Make a static nested class called Builder inside the class whose object will be build by Builder
  2. Builder class will have exactly same set of fields as original class
  3. Builder class will expose method for adding ingredients. Each method will return same Builder object. Builder will be enriched with each method call.
  4. Builder.build() method will copy all builder field values into actual class and return object of Item class
  5. Item class (class for which we are creating Builder) should have private constructor to create its object from build() method and prevent outsider to access its constructor.

Related posts:

Design Patterns: Factory vs Factory method vs Abstract Factory

Keeping builder in separate class (fluent interface)

Useful links:

sourcemaking design-patterns


The Abstract Factory pattern uses subclassing (of factories) to produce other objects (non-factories). Abstract Factory also envisions that the objects produced belong to parallel hierarchies (e.g. to handle platform independance, one hierarchy for each platform).

The Builder pattern uses subclassing to produce "output" - which is not necessarily objects at all. The GOF example has the Builder producing text output (markup or otherwise).

The Factory Method pattern, unlike the other two, divides the "creator" into an abstract and concrete implementation (thus the emphasis on it belonging to a framework implementation). Like Abstract Factory, it deals with making actual objects.

All three are highly similar, because they all use subclassing. It is the subclassing that is the outstanding quality of them all, which hides the subtle differences (outlined above) and thus many people have difficulty seeing the differences.


Abstract Factory is particularly helpful for test driven development and reducing coupling.

For example, in C#:

public class Worker
{
    public IConsumerFactory Factory { get; set; }

    private IResource resource;

    public DoWork()
    {
        IConsumer consumer = Factory.CreateConsumer();
        consumer.Consume(resource);
    }
}

public interface IConsumerFactory
{
    IConsumer CreateConsumer();
}

public interface IConsumer
{
    void Consume(IResource resource);
}

public class DefaultConsumerFactory : IConsumerFactory
{
    public IConsumer CreateConsumer()
    {
        return new DefaultConsumer();
    }
}

public class DefaultConsumer : IConsumer
{
    public void Consume(IResource resource)
    {
      ... Do Work ...
    }
}

This way, you can use dependency injection to inject the default implementations for production code, and then you can easily mock the factory and the objects it creates.


  • Factory Method pattern - When you want to build family of complex objects.
  • Object builder pattern - When you want to allow user to plugin their custom implementation into your framework

Please visit the following url for more details.

http://xeon2k.wordpress.com

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜