数据抽象 Data Abstraction
隐藏实现 并非 只是在变量之间放上一个函数层那么简单,隐藏实现 关乎 抽象
类不能简单地通过 Setter 和 Getter 把变量暴露出去,而应该暴露抽象接口,以便用户无需了解数据的的实现就能操作数据本体
如果把变量设为 private,然后通过 Setter 和 Getter 暴露,这跟设为 public 有什么区别
举两个例子:
1 | public class Point { |
1 | public interface Vehicle { |
即使用了接口,也不一定就隐藏实现,比如第一种实现
以上两段代码以后者为佳,不要暴露数据细节,要以抽象形态表述数据
在定义接口时,要严肃思考,不可随意乱加 setter 和 getter
数据、对象的反对称性 Data/Object Anti-Symmetry
对象和数据结构是不同的
对象:把数据隐藏于抽象之后,暴露操作数据的函数
数据结构:暴露其数据,没有提供有意义的函数
对象和数据结构之间的二分原理:
过程式代码(使用数据结构的代码)便于在不改动既有数据结构的前提下添加新函数
面向对象代码便于在不改动既有函数的前提下添加新类
换句话说:
过程式代码难以添加新的数据结构,因为必须修改所有函数
面向对象代码难以添加新函数,因为必须修改所有类
过程式代码难做的事,面向对象代码反而好做,反之亦然
所以,我们应该随机应变,不能武断地说一切都是对象,有时数据结构会更加合适
混杂 Hybrids
不要让一个类既扮演对象,又扮演数据结构,这种类中拥有执行操作的函数,也有公共变量或 setter/getter
这种混杂增加了添加新函数的难度,也增加了添加新数据结构的难度,两头不讨好,应避免创造这种结构
它们的出现,展示了一种乱七八糟的设计
数据传送对象
最为精炼的数据结构,是一个只有公共变量,没有函数的类
这种数据结构被称为 数据传送对象(DTO),常用在消息传递中
小结
对象暴露行为,隐藏数据,便于添加新对象类型而无须修改既有行为,但是难以在既有对象中添加新行为
数据结构暴露数据,没有明显的行为,便于向既有数据结构中添加新行为,但是难以向既有函数中添加新的数据结构
所以在设计时,我们要看场景是什么,从而使用数据结构或对象
希望灵活地添加新的数据类型:使用对象
希望灵活地添加新的行为:使用数据结构
优秀的软件开发者应了解这些情形,选择合适的手段