Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/361.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java:为什么使用方法而不是构造函数?_Java_Design Patterns - Fatal编程技术网

Java:为什么使用方法而不是构造函数?

Java:为什么使用方法而不是构造函数?,java,design-patterns,Java,Design Patterns,假设您有一个名为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; } 在当前的项目中,我看到很多这样的代码,通常

假设您有一个名为
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;
}
在当前的项目中,我看到很多这样的代码,通常使用方法对不同的
进行5-10个链式调用。这样做而不是在构造函数中设置这些值有什么好处

这样做而不是在构造函数中设置这些值有什么好处

1)过载

您可以轻松地管理要设置的值的数量,如果有很多参数要设置,但有些参数是可选的,则不必创建特定的构造函数或传递
null
value

 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");
将参数传递给方法/构造函数是匿名的,必须检查签名以了解传递的内容。有了这个符号,您就有了更详细、更可读的代码。(同样,二传手也是如此

3)可链接设定器 同样的情况也会发生在setter上,但是这里没有可链接的特性

person.setName("name");
person.setAge(19);

person.withName("name").withAge(19);


除了可读性之外,我不认为真的有什么改进,这个链需要返回实例本身的方法,在类本身中提供一个额外的代码(
返回这个;
)。

我看到的一个优点是可读性

如果我们扩展这个例子

new Person()
.withName("Lorem")
.withId("1234")
.withAge(29)
.withHeight(170)
.withWeight(75)
.withTaxId("1234");
如果我们不使用这个模式,而使用构造函数模式,那么在使用它们时,我们会得到很多参数,而没有任何关于它们的描述

new Person("Lorem","1234",29,170,75,"1234");

似乎有两大优势:

1.)灵活性:使用此模式,基本上可以选择要填充和不填充的字段。使用构造函数时,需要有多个构造函数才能实现相同的效果。与
中一样,Person
可以是

new Person().withName("Loren")
也可能是这样

new Person().withName("Loren").withAge(30)
其他所有内容都为空/默认值

在构造函数初始化的情况下,这两个都必须有2个构造函数

public Person(String name){
  //code
}

public Person(String name, String age){
//code
}
2.)如其他答案所述,可读性

new Person().withName("Loren").withAge(30).withId(567)
它的可读性比

new Person("Loren", 30, 567)

这一切都是关于可读性和可靠性的

虽然您的示例对于流畅的界面来说不是一个很好的示例,但您可以在以下内容中找到:


流畅的接口是API设计中的一个非常高级的主题,通常伴随着某种()或(为了避免难以理解,主要是内部API)

一个相当流利的API通常需要对您的需求有深入的了解,并且需要一个非常好的规划/准备阶段



请注意,使用fluent API与编写DSL密切相关。这里有一个例子和一个扩展的流畅界面,它的优点、缺点、理论等等。

代码更具可读性:新人(“a”、“b”、“c”)不容易指出a、b和c是什么。顺便说一下,Java不允许在单引号中使用字符串:)@ajb,他们发明了kotlin:-)如果返回,它应该是
publicperswithage
this@ZhekaKozlov这些提示很有帮助,但这并不能免除人们以更可读的方式编写代码的责任。在我工作的地方,我们很多人都使用IntelliJ,但也有人使用Eclipse,我们也有办法在浏览器中查看其他团队的代码,而无需将其下载到IDE中。因此,编写更难理解的代码并依靠其他使用IntelliJ的人来理解它是不够的。这是行不通的。我同意,我从来都不明白为什么这种方法链接如此大肆宣传。在这里,我知道我在什么地方见过这种符号@AxelH yeh,我补充了一些细节——我认为答案不会引起太多关注,所以一开始我没有花太多精力
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))));