第 5 章 从豆子到价值 从豆子到价值
本作品已使用人工智能进行翻译。欢迎您提供反馈和意见:translation-feedback@oreilly.com
许多 Java 项目都采用可变 JavaBeans 或 POJO(普通 Java 对象)约定来表示数据。 然而,可变性带来了复杂性。 为什么不可变值是更好的选择,以及如何降低代码库中的可变性成本?
豆类
正如 我们在"Bean 风格 "中所讨论的那样,JavaBeans 的引入是为了允许开发 Visual Basic 风格的拖放式图形用户界面构建器。 开发人员可以在表单上拖放一个按钮,更改其标题和图标,然后在点击处理程序中布线。 在幕后,图形用户界面构建器将编写代码来实例化一个按钮对象,然后调用设置器来设置开发人员更改的属性。
要定义 JavaBean,一个类需要一个默认(无参数)构造函数、属性的获取器和可变属性的设置器(我们将略过 的要求,因为即使 Sun 也从未认真对待过这个问题)。(我们将略过Serializable 的要求,因为即使 Sun 也从未真正认真对待过这一点。)这对于拥有大量属性的对象来说是有意义的。 GUI 组件通常拥有前景色和背景色、字体、标签、边框、大小、对齐方式、衬垫等等。这些属性的默认值大多都没有问题,因此只需为特殊值调用设置器就能最大限度地减少生成的代码量。 即使在今天,可变组件模型也是 GUI 工具包的可靠选择。
不过,当 JavaBean 出现时,我们认为大多数对象都是可变的,而不仅仅是用户界面组件。 我的意思是,为什么不呢?对象的意义在于封装属性并管理它们之间的关系。 对象的设计是为了解决一些问题,比如当组件的边界发生变化时更新组件的宽度,或者当物品添加时更新购物车的总计。 对象是管理可变状态问题的解决方案。Java 在当时拥有一个不可变的String 类是相当激进的(尽管它无法控制自己,仍然选择了一个可变的Date )。
如今,作为一个专业人士,我们对对象有了更深入的了解。 我们知道可以使用对象来表示不同类型的事物--值、实体、服务、操作、事务等。 然而,Java 对象的默认模式仍然是 JavaBean,即一个为其属性提供获取器和设置器的可变对象。 尽管它可能适合 UI 工具包,但这并不是一个好的默认模式。 对于我们想用对象表示的大多数事物来说,值会更好。
价值观
在英语中,"值"(Value)是 一个被过度使用的术语。在计算中,我们说变量、参数和字段都有值:它们所绑定的基元或引用。 在本书中,当我们提到值时,我们指的是一种特定类型的基元或引用:那些具有值语义的基元或引用。如果一个对象在交互中只对其值有意义,而不是对其身份有意义,那么该对象就具有值语义。
Java 基元都具有值语义:每个7 都等同于其他7 。不过,对象可能具有值语义,也可能不具有值语义;尤其是可变对象不具有值语义。在后面的章节中,我们将研究更细微的区别,但现在,我们只需将值定义为不可变的数据,将值 类型定义为定义不可变数据行为的类型。
因此,7 是一个值,带方框的Integer 是一个值类型(因为带方框的类型是不可变的),banana 是一个值类型(因为Strings 是不可变的),URI 是一个值类型(因为URIs 是不可变的),但java.util.Date 不是一个值类型(因为我们可以在日期上调用setYear 和其他类型)。
不可变DBConnectionInfo 的实例是一个值,但Database 的实例不是一个值,即使它的所有属性都是不可变的。这是因为它不是数据块,而是访问和更改数据块的一种手段。 ...
Become an O’Reilly member and get unlimited access to this title plus top books and audiobooks from O’Reilly and nearly 200 top publishers, thousands of courses curated by job role, 150+ live events each month,
and much more.
Read now
Unlock full access