美文网首页Java 杂谈
Java链式构造器(译)

Java链式构造器(译)

作者: 我是罗比 | 来源:发表于2018-08-20 14:39 被阅读0次

我们写代码时,随时都要创建对象。 通常我们使用new关键字创建对象,这就涉及调用构造函数来初始化我们的对象。

假设我们有一个描述耳机的类,当中有两个属性:颜色和价格,默认的情况下,耳机是黑色的,售价150美元,于是我们有了以下代码

public class Headphones {
    private final Color color;
    private final BigDecimal priceInDollars;
    public Headphones() {
        this.color = Color.BLACK;
        this.priceInDollars = BigDecimal.valueOf(150.0);
    }
    //other methods
}

一段时间后,我们决定制作不同颜色的耳机了,但是价格维持不变,对于这种情况,我们增加了一个新的构造函数:价格设置为默认值,但颜色通过参数传入构造方法:

public Headphones(final Color color) {
    this.color = color;
    this.priceInDollars = BigDecimal.valueOf(150.0);
}

再过一段时间后,我们决定不同颜色的耳机可以有不同的价格。 于是我们再次添加了一个新的构造函数:

public class Headphones {
    private final Color color;
    private final BigDecimal priceInDollars;
    public Headphones() {
        this.color = Color.BLACK;
        this.priceInDollars = BigDecimal.valueOf(150.0);
    }
    public Headphones(final Color color) {
        this.color = color;
        this.priceInDollars = BigDecimal.valueOf(150.0);
    }
    public Headphones(final Color color, final BigDecimal priceInDollars) {
        this.color = color;
        this.priceInDollars = priceInDollars;
    }
    //other methods
}

我们可以看到,以上的实现导致编码重复。 每个构造函数都必须自己设置所有字段,如果我们想要更改默认值,我们必须改变所有构造函数。 那我们该怎么做呢?

想到的第一个解决方案是我们可以使用默认值:

public class Headphones {
    private Color color = Color.BLACK;
    private BigDecimal priceInDollars = BigDecimal.valueOf(150.0);
    public Headphones() {
    }
    public Headphones(final Color color) {
        this.color = color;
    }
    public Headphones(final Color color, final BigDecimal priceInDollars) {
        this.color = color;
        this.priceInDollars = priceInDollars;
    }
    //other methods
}

现在,我们的构造函数只设置他们想要更改的字段。

我们也可以用另一种方式完成它并使用初始化程序设置默认值:

public class Headphones {
    private Color color;
    private BigDecimal priceInDollars;
    {
        this.color = Color.BLACK;
        this.priceInDollars = BigDecimal.valueOf(150.0);
    }
    //other
}

当然,这三种方式可以混合使用。 你可以通过构造函数设置一个字段,通过默认值设置第二个字段,并在初始化程序中设置第三个字段,但有什么好处呢?

我没有看到任何好处,反而发现很多问题:

  • 我们没有一个统一的实现, 每个构造方法的实现都完全独立。

  • 不够简洁,由于有多个实现,使用者需要关心每一个实现

  • After transformation, our fields cannot be final. We are setting default values regardless of whether we change them or not, so we have to make the possibility of changing it

  • Unnecessary field initialization is creating an unused object. This is not really a problem until you are creating millions of objects

我们怎么解决这些问题呢?

答案是使用链式构造器。

链式构造器意味着我们以一种方式编写构造函数,构造函数调用其他构造函数,最终到达统一的构造函数。 这个统一的构造函数称为主构造函数,所有其他构造函数称为辅助构造函数。

主构造函数将是我们创建和初始化对象的单一点,因此我们可以将所有常见行为放入其中。 为了保持一致性,我们只有一个主要的构造函数; 理想情况下,此构造函数将设置所有类字段。 此外,重要的是,如果我们不想对外公开主构造函数,那么主构造函数可以设置成私有的。

使用链式构造器,你不必担心代码重复。 因此,它将使你的代码更简单,更易于维护。 所有构造函数最终都调用主构造函数,这是一个可以共享公共代码的单点创建。

我建议你将主构造函数编写为类中的最后一个构造函数,并将其作为所有辅助函数编写,就像我在下面的Headphones所做的那样:

public class Headphones {
    private final Color color;
    private final BigDecimal priceInDollars;
    public Headphones() {
        this(Color.BLACK);
    }
    public Headphones(final Color color) {
        this(color, BigDecimal.valueOf(150.0));
    }
    public Headphones(final Color color, final BigDecimal priceInDollars) {
        this.color = color;
        this.priceInDollars = priceInDollars;
    }
    //other methods
}

尽管Java提供了不同的方式实现初始化,我的建议是

  • 永远不要使用初始化程序块,永远不要使用默认值初始化成员,始终链接构造函数。

在创建类时,请始终考虑如何正确设计它。 公开许多构造函数将提供不同的创建方式,从而增加代码的可用性。

设计类不仅意味着提供一个易单漂亮的API,而且还意味着保持所有代码内部的可维护性和可读性。

相关文章

  • Java链式构造器(译)

    原文链接 https://dzone.com/articles/never-break-the-chain-1 我...

  • thinkphp5学习笔记(五)数据库与模型

    连接与查询构造器 数据库连接配置 数据库原生查询 查询构造器 1.查询构造器的原理: 2.什么是链式操作?为什么要...

  • 10.29

    Java 中的构造器链是什么?当你从一个构造器中调用另一个构造器,就是Java 中的构造器链。这种情况只在重载了类...

  • java构造方法(构造器)

    java构造方法(构造器) [TOC] 含义 语法 特点 好处

  • Java深入学习(一)——构造器创建对象

    1.构造器是创建对象的重要途径 问题:构造器是创建Java对象的途径,是不是说构造器完全负责创建Java对象? 答...

  • OnJava8_初始化和清理

    Java对象初始化通过构造器,清理通过垃圾收集器(Garbage Collector, GC) 构造器 无参构造函...

  • 第二章 Java与Kotlin的写法比较

    3 Java与Kotlin的写法比较 3.1 构造器、变量、常量和静态数据 3.1.1 构造函数 java中的构造...

  • java面向对象之构造方法

    构造函数(构造方法、构造器、Constructor) 关于java类的构造函数 1、构造方法语法【修饰符列表】构造...

  • Java构造器

    什么是构造器? 简单的说构造器就是用来搞对象的.主要就是为了实例化(搞出)一个对象,就必须要通过构造器,要么有参数...

  • JAVA构造器

    记住: 1.构造器与类同名; 2.每个类可以有一个以上的构造器; 3.构造可以有0、1或多个参数; 4.构造器没有...

网友评论

    本文标题:Java链式构造器(译)

    本文链接:https://www.haomeiwen.com/subject/fhhliftx.html