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

Ale*_*ecu 22 design-patterns

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

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

max*_*der 29

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

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

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

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

很多参数

如果构造函数具有许多参数,则可以使代码更易读或易于维护以使用构建器.

例如

new Foo(1,2,3,4,5,6,7,8,9,10,11,12)
Run Code Online (Sandbox Code Playgroud)

比.

Foo.newBuilder()
   .bar(1)
   .bar(2)
   .quux(3)
   ...
   .build()
Run Code Online (Sandbox Code Playgroud)

构造对象图

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

例如,假设您有一个面向对象的管道接口,其中a Pipeline取决于Sequence哪个取决于Stage.A PipelineBuilder不仅可以在构造函数周围提供一个很好的包装器Pipeline,而且还可以在构造函数周围提供,SequenceStage允许您Pipeline从单个Builder接口组成复合体.

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

new Pipeline(
    new Sequence(
        new Stage(
            new StageFunction() {
                public function execute() {...}
            }
        ),
        new Stage(
            new StageFunction() {
                public function execute() {...}
            }
        )
    )
)
Run Code Online (Sandbox Code Playgroud)

A PipelineBuilder可以让你"折叠"望远镜.

Pipeline.newBuilder()
    .sequence()
        .stage(new StageFunction () {
            public function execute() {...}
        })
        .stage(new StageFunction () {
           public function execute() {...}
        })
    .build()
Run Code Online (Sandbox Code Playgroud)

(尽管我以一种反映伸缩式构造器的方式使用了压痕,但这只是装饰性的,而不是结构性的.)


Bri*_*new 5

维基百科页面:

当对象构造函数参数组合的增加导致构造函数的指数列表时,发生伸缩构造函数反模式.构建器模式不是使用大量构造函数,而是使用另一个对象(构建器),它逐步接收每个初始化参数,然后立即返回生成的构造对象

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

例如,我可以为对象创建多个不同的构造函数,或者我可以执行以下操作:

new ObjectBuilder().withParam1(1).withParam4(4).withParam19(19).build();
Run Code Online (Sandbox Code Playgroud)

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