我正在制作关于构建器模式的演示文稿,我很确定我会被问到构建器模式和构造函数之间的区别.
我的意思是构建器模式只是构建类似于构造函数的对象的一种方式,那么为什么要使用构建器模式而不是普通的旧构造函数呢?
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,而且还可以在构造函数周围提供,Sequence并Stage允许您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)
(尽管我以一种反映伸缩式构造器的方式使用了压痕,但这只是装饰性的,而不是结构性的.)
从维基百科页面:
当对象构造函数参数组合的增加导致构造函数的指数列表时,发生伸缩构造函数反模式.构建器模式不是使用大量构造函数,而是使用另一个对象(构建器),它逐步接收每个初始化参数,然后立即返回生成的构造对象
因此,如果我有一个需要许多构造参数的对象,并且这些参数需要各种组合(从而使一些参数可选),那么构建器是一种很好的方法.
例如,我可以为对象创建多个不同的构造函数,或者我可以执行以下操作:
new ObjectBuilder().withParam1(1).withParam4(4).withParam19(19).build();
Run Code Online (Sandbox Code Playgroud)
因此允许我选择所需的参数,而不必定义许多不同的构造函数.另请注意,上述内容可以允许您填充构建器,并build()多次设置参数/调用以轻松创建一组相关对象.