Questions tagged «builder-pattern»

1
“ StringBuilder”是Builder设计模式的应用程序吗?
是“构建器”模式仅限于解决“ telescoping构造函数”反模式,还是可以说也解决了复杂的不可变对象创建这一更普遍的问题? 该StringBuilder班在其名称中的“建设者”,但它没有任何可伸缩的构造函数,它只是帮助我们收集了所有我们需要传递给一个不可变对象的构造函数的数据。 在我看来,答案似乎是非常明确的“是”,但是在该主题上似乎存在一些分歧,因此我希望有人可以对此进行澄清。 我在回答这个问题:程序员SE:在构造函数中合法的“实际工作”?OP想要创建一个包含复杂树的(可能是不可变的)对象,然后弹出“ builder”模式的想法,在研究它时,我发现了这个问答,似乎是在说“ StringBuilder”风格的对象创建是不是 “建设者”模式的应用,这是我不明白原因:#1 - StringBuilder的和Builder模式。(据我所知,回答该问题的人未能提出令人信服的观点。)

9
为什么在实现Builder模式时我们需要一个Builder类?
我已经看到了Builder模式的许多实现(主要是Java)。它们都有一个实体类(假设是一个Person类)和一个构建器类PersonBuilder。构建器“堆叠”各种字段,并返回new Person带有传递的参数的。为什么我们显式需要一个构建器类,而不是将所有构建器方法放在Person类本身中? 例如: class Person { private String name; private Integer age; public Person() { } Person withName(String name) { this.name = name; return this; } Person withAge(int age) { this.age = age; return this; } } 我可以简单地说 Person john = new Person().withName("John"); 为什么需要PersonBuilder上课? 我看到的唯一好处是,我们可以将Person字段声明为final,从而确保了不变性。

8
如何在团队中促进使用Builder模式?
我们的代码库是新老程序员,像我自己一样,为了统一起见,他们很快就学会了按照做事的方式来做。考虑到我们必须从某个地方开始,我自己决定重构一个数据持有者类,如下所示: 删除了setter方法,并设置了所有字段final(我final理所当然地认为“ 好”)。事实证明,该二传手仅在构造函数中使用,因此没有副作用。 引入了一个Builder类 Builder类是必需的,因为构造函数(首先是提示重构的原因)跨越大约3行代码。它有很多参数。 幸运的是,我的一个团队的成员正在另一个模块上工作,并且碰巧需要设置者,因为他需要的值在流程的不同点可用。因此,代码如下所示: public void foo(Bar bar){ //do stuff bar.setA(stuff); //do more stuff bar.setB(moreStuff); } 我认为他应该改用构建器,因为摆脱设置器可以使字段保持不变(他们之前听说过关于不变性的内容),并且还因为构建器允许对象创建是事务性的。我草绘了以下伪代码: public void foo(Bar bar){ try{ bar.setA(a); //enter exception-throwing stuff bar.setB(b); }catch(){} } 如果引发该异常,bar将有损坏的数据,而使用构建器可以避免: public Bar foo(){ Builder builder=new Builder(); try{ builder.setA(a); //dangerous stuff; builder.setB(b); //more dangerous stuff builder.setC(c); return builder.build(); }catch(){} …

3
大量参数的构造函数与构造器模式
众所周知,如果您的类的构造函数带有许多参数,例如超过4个,则很可能是代码气味。您需要重新考虑该类是否满足SRP要求。 但是,如果我们构建并反对依赖10个或更多参数的对象,并最终通过Builder模式设置所有这些参数,该怎么办?想象一下,您Person用其个人信息,工作信息,朋友信息,兴趣信息,教育信息等构建了一个类型对象。这已经很好了,但是您可以通过多个4来设置相同的参数,对吗?为什么这两种情况不一样?

5
为什么将类型与生成器结合在一起?
我最近在Code Review上删除了我的一个Java答案,它的开始是这样的: private Person(PersonBuilder builder) { 停止。红色标志。一个PersonBuilder将建立一个Person;它知道一个人。Person类应该对PersonBuilder一无所知-这只是一个不可变的类型。您已经在此处创建了圆形耦合,其中A取决于B,而B取决于A。 该人员应仅获取其参数;愿意创建一个人而不创建它的客户应该能够做到这一点。 我被选票打了耳光,并告诉我(引用)红旗,为什么?这里的实现与Joshua Bloch在其“ Effective Java”书(项目2)中演示的形状相同。 因此,看来在Java 中实现构建器模式的一种正确方法是使构建器成为嵌套类型(尽管这不是这个问题),然后制造产品(正在构建的对象的类) )对构建器的依赖,如下所示: private StreetMap(Builder builder) { // Required parameters origin = builder.origin; destination = builder.destination; // Optional parameters waterColor = builder.waterColor; landColor = builder.landColor; highTrafficColor = builder.highTrafficColor; mediumTrafficColor = builder.mediumTrafficColor; lowTrafficColor = builder.lowTrafficColor; } https://zh.wikipedia.org/wiki/Builder_pattern#Java_example 对于相同的Builder模式,相同的Wikipedia页面对于C#具有非常不同的实现(并且更加灵活): //Represents …


4
Java:如何实现设置程序的顺序无关紧要的步骤生成器?
编辑:我想指出,这个问题描述了一个理论上的问题,并且我知道我可以使用构造函数参数作为强制参数,或者如果API使用不正确则抛出运行时异常。然而,我在寻找,它的解决方案不要求构造函数参数或运行时检查。 假设您有一个Car这样的界面: public interface Car { public Engine getEngine(); // required public Transmission getTransmission(); // required public Stereo getStereo(); // optional } 正如评论所暗示的,a Car必须具有Engineand,Transmission而a Stereo是可选的。这意味着可以build()将Car实例创建的Builder 仅应在已将和都指定给该Builder实例的情况下才具有build()方法。这样,类型检查器将拒绝编译任何尝试在不使用or 的情况下创建实例的代码。EngineTransmissionCarEngineTransmission 这需要一个步骤构建器。通常,您将实现以下内容: public interface Car { public Engine getEngine(); // required public Transmission getTransmission(); // required public Stereo getStereo(); // optional public class Builder …

3
将构建器和流体接口与对象初始化器一起使用是否有意义?
在Java和C#中,您可以创建具有可在初始化时设置的属性的对象,方法是定义带参数的构造函数,构造对象后定义每个属性,或使用builder / fluid接口模式。但是,C#3引入了对象和集合初始化程序,这意味着构建器模式在很大程度上没有用。在没有初始化程序的语言中,可以实现一个生成器,然后像这样使用它: Vehicle v = new Vehicle.Builder() .manufacturer("Toyota") .model("Camry") .year(1997) .colour(CarColours.Red) .addSpecialFeature(new Feature.CDPlayer()) .addSpecialFeature(new Feature.SeatWarmer(4)) .build(); 相反,在C#中,可以这样写: var vehicle = new Vehicle { Manufacturer = "Toyota", Model = "Camry", Year = 1997, Colour = CarColours.Red, SpecialFeatures = new List<SpecialFeature> { new Feature.CDPlayer(), new Feature.SeatWarmer { Seats = 4 } …
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.