假设您有一个名为Person
的班级,Person
有name
,id
,age
等属性,而不是设置这些构造函数中的值,一个
new Person().withName("Lorem").withId("1234").withAge(29)
with
方法是对set
方法的调用,并返回该对象,例如,
public Person withAge(int age) {
this.setAge(age);
return this;
}
在当前项目中,我看到很多这样的代码,通常会对不同的with
方法进行5-10个链式调用。这样做有什么好处,而不是在构造函数中设置这些值?
答案 0 :(得分:3)
这样做有什么好处,而不是在构造函数中设置这些值?
1)超载
如果要设置大量参数,可以轻松管理要设置的值的数量,但有些是可选的,您不必创建特定的构造函数或传递null
值。 / p>
new Person("name", 19);
new Person("name", 19, address);
new Person("name", 19, phone);
(那些是不好的例子;))
在你的情况下,你只需要调用你需要的方法(与setter相同)。
2)身份认同
此外,在方法/构造函数中包含大量参数往往难以阅读,以识别每个参数上下文
new Person("frank", "John", "Emma");
person.withName("frank").withFather("john").withMother("Emma");
将参数传递给方法/构造函数是无名的,您必须检查签名以了解您传递的内容。使用该表示法,您可以获得更详细和可读的代码。 (再次,与setter相同)。
3)可连接的二传手 使用setter也是如此,但没有你在这里的可链接功能。
person.setName("name");
person.setAge(19);
person.withName("name").withAge(19);
除了可读性之外,我认为没有真正的改进,链需要方法来返回实例本身,在类本身中提供重新生成代码({{1 }})。
答案 1 :(得分:2)
我看到的一个优点是可读性。
如果我们扩展示例
new Person()
.withName("Lorem")
.withId("1234")
.withAge(29)
.withHeight(170)
.withWeight(75)
.withTaxId("1234");
如果我们没有使用这种模式并使用了构造函数模式,那么在使用它们时我们会得到很多参数而没有任何关于它们的描述。
new Person("Lorem","1234",29,170,75,"1234");
答案 2 :(得分:2)
关于可读性和fluent interfaces。
虽然您的示例对于流畅的界面不是很好,但您可以在Java part of the wikipedia article:中找到:
Author author = AUTHOR.as("author");
create.selectFrom(author)
.where(exists(selectOne()
.from(BOOK)
.where(BOOK.STATUS.eq(BOOK_STATUS.SOLD_OUT))
.and(BOOK.AUTHOR_ID.eq(author.ID))));
流畅的接口是API设计中一个非常高级的主题,通常带有某种Builder pattern(to avoid too big and too many constructors)或Facade pattern(以避免难以理解,主要是内部API )。
漂亮流畅的API通常需要深入了解您的要求和非常好的计划/准备阶段。
请注意,使用流畅的API与编写DSL密切相关。这里有一个Martin Fowler的例子和一个扩展的,really good explanation流畅的接口,它的优点,缺点,理论等。
答案 3 :(得分:1)
似乎有两大优势:
1。)灵活性:使用此模式,您基本上可以选择填充而不填充的字段。使用构造函数时,您需要具有多个构造函数才能实现相同的功能。正如在std.textio
中可以
Person
或者它可以是
new Person().withName("Loren")
其他一切都为null / default。
如果是构造函数初始化,则必须为这两个构造函数提供2个构造函数。
new Person().withName("Loren").withAge(30)
2。)正如其他答案所述,可读性。
public Person(String name){
//code
}
public Person(String name, String age){
//code
}
比
更具可读性new Person().withName("Loren").withAge(30).withId(567)