关于设计模式:抽象工厂,工厂方法,生成器

Abstract Factory, Factory Method, Builder

这似乎是一个骗人的问题,但请原谅我-我保证我已经读过相关的帖子(和共和党的书)。

在我读了所有的东西之后,我仍然不清楚何时使用抽象工厂、工厂方法或生成器。我相信,当我看到一个简单的问题的例子,比如一个建设者最好的解决后,它最终会陷入困境,而使用一个抽象的工厂显然是愚蠢的。

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

我明白,如果这个例子太简单,可能会归结为一个观点问题,但我希望如果有人能做到的话,这个人就是这样的。

谢谢。


生成器帮助您构造复杂对象。一个例子是EDCOX1的0个ED类(Java,C.*),它逐个地构建最终的字符串。一个更好的例子是Spring中的UriComponentsBuilder,它帮助您构建一个URI。

工厂方法在一次放炮中为您提供一个完整的对象(而不是生成器)。基类定义了返回接口(或超级类)引用的单个抽象方法,并将对象的具体创建推迟到子类。

抽象工厂是创建许多不同相关对象的接口(或抽象类)。一个很好的例子(在.NET中)是DbProviderFactory类,它根据具体的实现,为给定的数据库提供程序(Oracle、SQL Server,…)创建相关的对象(连接、命令,…)。


建设者

1
2
3
4
5
6
7
8
9
10
11
12
// 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();
}

工厂法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 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();

抽象工厂

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 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
...


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

工厂方法:

  • 它定义了一个用于创建对象的接口,但是让子类决定要实例化哪个类。
  • 我们在不向客户机公开创建逻辑的情况下创建一个对象,并使用公共接口(或抽象类)引用新创建的对象。
  • 通过消除将特定于应用程序的类绑定到代码中的需要,提供松耦合。代码只与接口或抽象类交互
  • 它可以使用继承或子分类来达到目的。

    关键提示:您将创建一个接口以及这些接口的特定实现。在工厂方法中,根据条件,您将得到公共接口的具体实现。

  • 抽象工厂:

  • 提供一个接口,用于创建相关对象或从属对象的族,而不指定它们的具体类
  • 一种封装的层次结构:许多可能的"平台",以及一套"产品"的构造。
  • 抽象工厂类通常使用工厂方法实现,但也可以使用原型实现
  • 建设者:

  • 构建器模式使用简单对象和逐步方法构建复杂对象
  • 在这种情况下替换为工厂方法/抽象工厂:从客户机程序传递到工厂类的参数太多,容易出错
  • 有些参数可能是可选的,与工厂强制发送所有参数不同
  • 爪哇建设者设计模式指南

  • 在类中生成一个名为builder的静态嵌套类,该类的对象将由builder生成。
  • 生成器类将具有与原始类完全相同的字段集
  • Builder类将公开用于添加成分的方法。每个方法将返回相同的生成器对象。每个方法调用都将丰富生成器。
  • builder.build()方法将把所有builder字段值复制到实际类中,并返回item类的对象
  • 项类(我们正在为其创建生成器的类)应该有私有构造函数,以便从build()方法创建其对象,并防止外部人员访问其构造函数。
  • 相关员额:

    设计模式:工厂vs工厂方法vs抽象工厂

    将生成器保持在单独的类中(Fluent接口)

    有用链接:

    源代码生成设计模式


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

    从我自己的经验中,我发现头一本设计模式书也是一本非常好的关于设计模式的书。与ErichGamma所写的不同,它通过引入一个由何时不使用设计模式引起的问题来处理每个设计模式,然后进一步讨论设计模式如何解决这个问题。这对我来说是一个非常愉快的阅读。这也使得埃里希·伽玛写的那篇读完后更容易理解。


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

    有关详细信息,请访问以下URL。

    http://xeon2k.wordpress.com


    抽象工厂对于测试驱动开发和减少耦合特别有用。

    例如,在c:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    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 ...
        }
    }

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


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

    构建器模式使用子类化来生成"输出",这根本不一定是对象。GOF示例让生成器生成文本输出(标记或其他)。

    工厂方法模式不同于其他两种模式,它将"创建者"分为抽象和具体的实现(因此,对它的强调属于框架实现)。像抽象工厂一样,它处理实际对象的制作。

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