我正在撰写关于构建器模式的演示文稿,我很确定我会被问到构建器模式和构造函数之间的区别。
我的意思是构建器模式只是构建类似于构造函数的对象的一种方式,那么为什么要使用构建器模式而不是普通的旧构造函数呢?
答案 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
,取决于Stage
。 PipelineBuilder
不仅会在Pipeline
的构造函数周围提供一个很好的包装器,而且还会在构造函数Sequence
和Stage
周围提供一个很好的包装器,允许您组成一个复杂的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)
伸缩构造器反模式发生时增加 对象构造函数参数组合导致指数列表 建设者。而不是使用众多构造函数,构建器 pattern使用另一个对象,一个构建器,接收每个对象 初始化参数一步一步然后返回结果 立即构造对象
因此,如果我有一个需要许多构造参数的对象,并且这些参数需要各种组合(从而使一些参数可选),那么构建器是一种很好的方法。
e.g。我可以为一个对象创建多个不同的构造函数,或者我可以执行以下操作:
new ObjectBuilder().withParam1(1).withParam4(4).withParam19(19).build();
因此允许我选择所需的参数,而不必定义许多不同的构造函数。另请注意,上述内容可以允许您填充构建器,并多次设置参数/调用build()
以轻松创建一组相关对象。
答案 2 :(得分:0)
在构建器类中构建对象允许在一个位置封装与构建对象相关的逻辑。此外,您可以更轻松地处理对象构造所需的依赖项,而不是使用常规构造函数。
换句话说 - 如果构造一个对象很复杂,并且依赖性很少 - 使用构建器模式,如果对象构造很简单(很少逻辑和很少的参数) - 使用构造函数。
答案 3 :(得分:0)
构造函数构造所需的对象,而构造函数是构造所需对象的帮助对象。我认为这太可怕了!
例如:
// 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弃用构造函数时,我不喜欢这样。它喜欢,类型类型类型;不推荐使用。