构建器模式和构造函数之间的区别

时间:2015-04-26 17:44:02

标签: design-patterns

我正在撰写关于构建器模式的演示文稿,我很确定我会被问到构建器模式和构造函数之间的区别。

我的意思是构建器模式只是构建类似于构造函数的对象的一种方式,那么为什么要使用构建器模式而不是普通的旧构造函数呢?

4 个答案:

答案 0 :(得分:23)

我同意你的观点,Builder实际上只是一个美化的构造函数,而“构建器模式只是构建类似于构造函数的对象的一种方式”。

但是,这里有一些场景,其中构造对象的复杂性使Builder引人注目。

在一段时间内收集的对象依赖项

在Java中,StringBuilder通常用于在一段时间内构建字符串,或者更确切地说,在复杂过程中构建字符串。例如,如果服务器通过套接字与客户端通信,并且想要将某些客户端响应附加到字符串而不是其他客户端,并且可能删除先前附加的某些响应,则可以使用StringBuilder类这样做。在客户端/服务器会话结束时,服务器可以调用StringBuilder#toString来获取构建的String

很多参数

如果构造函数包含许多参数,则可能使代码更易读或易于维护以使用构建器。

E.g。

new Foo(1,2,3,4,5,6,7,8,9,10,11,12)

Vs以上。

Foo.newBuilder()
   .bar(1)
   .bar(2)
   .quux(3)
   ...
   .build()

构建对象图

与“大量参数”场景类似,我认为构建器最引人注目的场景是构建复杂对象图时。这个问题的其他答案是指伸缩式反模式。这种情况(构建一个复杂的对象图)可以导致“伸缩”,Builder有助于解决。

例如,假设您有一个面向对象的管道接口,Pipeline取决于Sequence,取决于StagePipelineBuilder不仅会在Pipeline的构造函数周围提供一个很好的包装器,而且还会在构造函数SequenceStage周围提供一个很好的包装器,允许您组成一个复杂的Pipeline来自单个Builder界面。

而不是像这样伸缩构造器:

new Pipeline(
    new Sequence(
        new Stage(
            new StageFunction() {
                public function execute() {...}
            }
        ),
        new Stage(
            new StageFunction() {
                public function execute() {...}
            }
        )
    )
)

PipelineBuilder允许你“折叠”望远镜。

Pipeline.newBuilder()
    .sequence()
        .stage(new StageFunction () {
            public function execute() {...}
        })
        .stage(new StageFunction () {
           public function execute() {...}
        })
    .build()

(尽管我以反映伸缩式构造器的方式使用缩进,但这只是装饰性的,而不是结构式的。)

答案 1 :(得分:5)

来自Wikipedia page

  

伸缩构造器反模式发生时增加   对象构造函数参数组合导致指数列表   建设者。而不是使用众多构造函数,构建器   pattern使用另一个对象,一个构建器,接收每个对象   初始化参数一步一步然后返回结果   立即构造对象

因此,如果我有一个需要许多构造参数的对象,并且这些参数需要各种组合(从而使一些参数可选),那么构建器是一种很好的方法。

e.g。我可以为一个对象创建多个不同的构造函数,或者我可以执行以下操作:

new ObjectBuilder().withParam1(1).withParam4(4).withParam19(19).build();

因此允许我选择所需的参数,而不必定义许多不同的构造函数。另请注意,上述内容可以允许您填充构建器,并多次设置参数/调用build()以轻松创建一组相关对象。

答案 2 :(得分:0)

在构建器类中构建对象允许在一个位置封装与构建对象相关的逻辑。此外,您可以更轻松地处理对象构造所需的依赖项,而不是使用常规构造函数。

换句话说 - 如果构造一个对象很复杂,并且依赖性很少 - 使用构建器模式,如果对象构造很简单(很少逻辑和很少的参数) - 使用构造函数。

答案 3 :(得分:0)

构造函数构造所需的对象,而构造函数是构造所需对象的帮助对象。我认为这太可怕了!

  1. 它与对象创建的自然而学识渊博的方法相矛盾。他们接下来会提出什么新方法?
  2. 不是创建一个对象,而是强制创建两个对象。
  3. 绝对没有必要!我们总是必须为函数参数准备变量,并且从未使用过构建器。

例如:

// a class with ctor that takes lots of params
class Params
{
    Params(int,int,int,String,char,boolean,int){}
}

// We dont need a builder.
// A builder will do the same following thing.
int p1 = 20;
int p2 = 40 + 40;
int p3 = (67 >> 1) * 3;
String p4 = "go" + "to" + "church";
char p5 = ' ' == 32 ? '5' : '7';
boolean p6 = true;
int p7 = MATCH_PARAMS;
new Params(p1,p2,p3,p4,p5,p6,p7);

//There is also this design pattern
new Params(
    20,
    40 + 40,
    (67 >> 1) * 3,
    "go" + "to" + "church",
    ' ' == 32 ? '5' : '7',
    true,
    MATCH_PARAMS
   );

最终,如果您是建筑商的粉丝,那就没问题了。但是,当Android弃用构造函数时,我不喜欢这样。它喜欢,类型类型类型;不推荐使用。