美文网首页
第十六条:在公共类中使用访问而方法而非公有域

第十六条:在公共类中使用访问而方法而非公有域

作者: taogan | 来源:发表于2021-02-05 16:02 被阅读0次

有时候,可能需要编写一些退化类,它们没有声明作用,只是用来集中实例域:

class Point {
    public double x;
    public double y;
}

由于这些类的数据域是可以直接访问的,这些类没有提供封装的功能,如果不改变API,就无法改变它的数据表达法,也无法强化任何约束条件;当域别被访问的时候,无法采取任何辅助的行为。坚持面向对象编程的程序员对这种类深恶痛绝,认为应该用包含私有域和公有方法(getter)的类代替。对于可变的类来说,应该用公有设值方法(setter)的类代替:

class Point {
    private double x;
    private double y;

    public Point(double x, double y) {
        this.x = x;
        this.y = y;
    }

    public double getX() { return x; }

    public double getY() { return y; }

    public void setX(double x) { this.x = x; }

    public void setY(double y) { this.y = y; }

}

毫无疑问,说到公有类的时候,坚持面向对象编程思想的看法是正确的:如果类可以在它所在的包之外进行访问,就提供访问方法,以保留将来改变该类的内部表达法的灵活性。如果公有类暴露了它的数据域,要想在将来改变其内部表达法是不可能的,因为公有类的客户端代码已经遍布各处了

然而,如果类是包级私有的,或者是私有的嵌套类,直接暴露它的数据域并没有本质的错误,假设这些数据域确实描述了该所提供的抽象。无论是在类定义中,还是在使用该类的客户端代码中,这种方式比访问方法的做法更不容易产生视觉混乱。虽然客户端代码与该类的内部表示法紧密相连,但是这些代码被限定在包含该类的包中。如有必要,也可以不改变包之外的任何代码,而只改变内部数据表示法。在私有嵌套类的情况下,改变的作用范围被进一步限制在外围类中

Java平台类库有几个类违反了“公有类不应该直接暴露数据域”的告诫。显著的例子包括java.awt包中的Point类和Dimension类。它们是不值得效仿的例子,相反,这些类应该被当作反面的警告示例。正如第67条所述,决定暴露Dimension类的内部数据造成了严重的性能问题,而且这个问题至今依然存在。

让公有类直接暴露域虽然从来都不是种好办法,但是如果域是不可变得,这种做法得危害就比较小一些。如果不改变类的API,就无法改变这种类的表示法,当域被读取的时候,你也无法采取辅助的行为,但是可以加强约束条件。例如,这个类确保了每个实例都表示一个有效的时间:

// Public class with exposed immutable fields - questionable

public final class Time {
    private static final int HOURS_PER_DAY    = 24;
    private static final int MINUTES_PER_HOUR = 60;
    public final int hour;
    public final int minute;

    public Time(int hour, int minute) {
        if (hour < 0 || hour >= HOURS_PER_DAY)
           throw new IllegalArgumentException("Hour: " + hour);
        if (minute < 0 || minute >= MINUTES_PER_HOUR)
           throw new IllegalArgumentException("Min: " + minute);
        this.hour = hour;
        this.minute = minute;
    }

    ... // Remainder omitted
}

简而言之,共有类永远都不应该暴露可变的域。虽然还是有问题,但是让公有类暴露不可变的域,其危害相对来说比较小。但有时候需要用包级私有或者私有的嵌套类来暴露域,无论这个类是可变的还是不可变的。

相关文章

  • 第十六条:在公共类中使用访问而方法而非公有域

    有时候,可能需要编写一些退化类,它们没有声明作用,只是用来集中实例域: 由于这些类的数据域是可以直接访问的,这些类...

  • 在公有类中使用访问方法而非公有域

    第十四条:在公有类中使用访问方法而非共有域 1.简单介绍 这一条的意思是让你这样做: 而不要这样做: 2. 原因 ...

  • 在公有类中使用访问方法而非共有域

    由于这种类的数据域是可以被直接访问的,并且没有提供封装的功能。如果不改变API,就无法改变他的数据域表示法,也无法...

  • 在公有类中使用访问方法而非公有域

    这种类数据是可以被直接访问的,这些类没有提供封装的功能,如果不改变API,就无法改变它的数据表示法,也无法强加任何...

  • 第四章类和接口

    目录 使类和成员的可访问性最小化 在公共类中使用访问方法而不是公共属性 最小化可变性 组合优于继承 如果使用继承则...

  • 死磕java-java内部类

    定义: 定义在一个类内部的类,其中的方法可以访问外部类的域 使用原因: 1、内部类可以访问该类定义的所在作用域的数...

  • python中类中属性和方法的具体定义方法和使用

    1. Python中类中特性分成属性和方法 属性和方法都分为私有和公有的,私有的只可以在本类中使用外部是无法访问的...

  • 提示十六

    今天来看: 在公共类中使用访问方法而不是公共属性。 如果不更改API,则无法更改其表示形式,无法强制执行不变量,并...

  • Effective Java-类和接口

    使类和成员的可访问性最小化 尽可能地使每个类或者成员不被外界访问 除了公有静态final域的特殊情况之外,公有类都...

  • 老男孩python--面向对象25

    1.子类无法访问父类的私有字段,如果要访问,可以在父类中写一个公有方法,子类继承该方法间接访问私有字段 2.__i...

网友评论

      本文标题:第十六条:在公共类中使用访问而方法而非公有域

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