抽象工厂,工厂方法,生成器

时间:2010-09-10 18:31:58

标签: design-patterns language-agnostic builder abstract-factory factory-method

似乎这个问题似乎是一个骗局,但请耐心等待 - 我保证我已阅读相关帖子(以及GOF book)。

在我读过的所有内容之后,我仍然不清楚何时使用抽象工厂,工厂方法或构建器。我相信它会在我看到一个问题的简单示例后最终陷入其中,例如, builder 最好接近这个问题,使用抽象工厂显然很愚蠢

你能提供一个简单的例子,你可以清楚地使用一种模式而不是其他模式吗?

据我所知,如果这个例子过于简单,可能会归结为意见问题,但我希望如果有人可以,那个人就是这样。

感谢。

7 个答案:

答案 0 :(得分:53)

构建器可帮助您构建复杂对象。一个例子是StringBuilder类(JavaC#),它逐段构建最终的字符串。一个更好的例子是Spring中的UriComponentsBuilder,它可以帮助您构建URI。

工厂方法一次性为您提供完整的对象(与构建器相对)。基类定义了一个返回接口(或超类)引用的抽象方法,并将对象的具体创建推迟到子类。

抽象工厂是一个接口(或抽象类),用于创建许多不同的相关对象。一个很好的例子(在.NET中)是DbProviderFactory类,用于创建给定数据库提供程序(oracle,sql server,...)的相关对象(连接,命令......),具体取决于具体实施。

答案 1 :(得分:8)

<强>生成器

// 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 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 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
...

答案 2 :(得分:2)

抽象工厂,工厂方法,构建器:所有这些模式都是创建模式,它们是处理对象创建机制的设计模式,试图以某种方式创建对象适合这种情况。

工厂方法:

  1. 它定义了一个用于创建对象的接口,但让子类决定实例化哪个类
  2. 我们创建一个对象而不将创建逻辑暴露给客户端并使用公共接口(或抽象类)引用新创建的对象
  3. 通过消除将特定于应用程序的类绑定到代码的需要,提供松散耦合。代码仅与接口或抽象类进行交互
  4. 可以使用继承或子类来达到目的

    重点说明:您将创建一个界面&amp;这些接口的具体实现。在Factory方法中,根据条件,您将获得通用接口的具体实现。

  5. 抽象工厂:

    1. 提供用于创建相关或从属对象族的界面,而不指定其具体类
    2. 一个层次结构,它包含:许多可能的&#34;平台&#34;`,以及一套&#34;产品的构建&#34;
    3. 抽象工厂类通常使用工厂方法实现,但它们也可以使用Prototype实现
    4. 生成器:

      1. Builder模式使用简单对象并使用分步方法构建复杂对象
      2. 在此方案中替换为Factory方法/抽象工厂:从客户端程序传递到可能容易出错的Factory类的参数太多
      3. 与Factory强制发送所有参数
      4. 不同,某些参数可能是可选的

        Java中的Builder设计模式指南

        1. 在类中创建一个名为Builder的静态嵌套类,其对象将由Builder
        2. 构建
        3. Builder类与原始类
        4. 具有完全相同的字段集
        5. Builder类将公开添加成分的方法。每个方法都将返回相同的Builder对象。每次方法调用都会丰富Builder。
        6. Builder.build()方法会将所有构建器字段值复制到Item类的实际类和返回对象
        7. Item类(我们正在创建Builder的类)应该有私有构造函数来从build()方法创建它的对象,并防止局外人访问它的构造函数。
        8. 相关帖子:

          Design Patterns: Factory vs Factory method vs Abstract Factory

          Keeping builder in separate class (fluent interface)

          有用的链接:

          sourcemaking设计模式

答案 3 :(得分:1)

我前几天撰写了一篇文章,目的是比较工厂方法模式和Builder模式。你可以在这里找到它:http://www.shenghua.co.uk/factory-method-vs-builder/。希望它也可以提供一些帮助。

根据我自己的经验,我发现Head First Design Pattern一书也是一本非常好的书,谈论设计模式。与Erich Gamma编写的不同,它通过引入一个问题来解决每个设计模式,这个问题是在没有使用设计模式的情况下引起的,然后逐步提升设计模式如何解决这个问题。对我来说这是一个非常愉快的阅读。它也使得Erich Gamma写的那个在读完之后更容易理解。

答案 4 :(得分:0)

抽象工厂模式使用子类化(工厂)来生成其他对象(非工厂)。 Abstract Factory还设想生成的对象属于并行层次结构(例如,处理平台独立性,每个平台一个层次结构)。

Builder模式使用子类化来生成“输出” - 根本不是对象。 GOF示例使Builder生成文本输出(标记或其他)。

工厂方法模式与其他两个模式不同,将“创建者”划分为抽象且具体的实现(因此强调它属于框架实现)。与抽象工厂一样,它涉及制作实际对象。

这三个都非常相似,因为它们都使用子类化。它的子类是它们的优秀品质,它隐藏了细微的差异(如上所述),因此许多人很难看到差异。

答案 5 :(得分:0)

Abstract Factory特别有助于测试驱动开发和减少耦合。

例如,在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 ...
    }
}

这样,您可以使用依赖注入来为生产代码注入默认实现,然后您可以轻松地模拟工厂及其创建的对象。

答案 6 :(得分:0)

  • 工厂方法模式 - 当您想要构建复杂对象族时。
  • 对象构建器模式 - 当您希望允许用户将其自定义实现插入到框架中时

请访问以下网址了解详情。

http://xeon2k.wordpress.com