软件构造 | Abstract Data Type (ADT)
抽象数据类型与表示独立性:如何设计良好的抽象数据结构,通过封 装来避免客户端获取数据的内部表示(即“表示泄露”),避免潜在 的bug
——在client
和implementer
之间建立“防火墙”
ADT的特性:不变量、表示泄漏、抽象函数AF、表示不变量RI
Classifying Types and Operations
Creators:构造器(从无到有) Producers:生产器(从有到新) Observers:观察器
Mutators:变值器,改变对象属性的方法
在面向对象编程中,常见的设计原则之一是将类的方法分为不同的类型,以便更好地组织和理解类的功能。以下是针对Java中的不同类型方法的详细解释:
- 构造器 (Creators):
构造器是用于创建新对象并初始化其状态的特殊类型的方法。在Java中,构造器的主要作用是初始化类的新实例。构造器的特点是它们的方法名与类名相同,并且没有返回类型。当我们使用关键字new
来实例化一个类的对象时,实际上是在调用该类的构造器。
示例:
public class Person {private String name;// 构造器public Person(String name) {this.name = name;}// 其他方法// ...public static void main(String[] args) {Person person1 = new Person("Alice"); // 调用构造器创建一个名为 Alice 的 Person 对象}
}
- 生产器 (Producers):
生产器是一种类型的方法,用于基于现有对象生成新的对象。生产器方法通常不会改变原始对象的状态,而是返回一个新对象,继承或衍生自原始对象。生产器方法可以帮助我们避免更改原始对象的状态或进行不必要的对象复制。
示例:
public class Circle {private double radius;// 生产器方法,返回一个新的 Circle 对象,半径为当前对象的两倍public Circle createScaledCircle() {return new Circle(this.radius * 2);}
}
- 观察器 (Observers):
观察器是一种类型的方法,用于查看对象的状态或属性,而不修改它们。观察器方法通常返回对象的状态或属性信息,而不会对对象进行任何更改。这有助于遵循对象的封装性原则,使对象的内部状态受到保护,并通过公共方法提供对状态的访问。
示例:
public class Rectangle {private double width;private double height;// 观察器方法,返回矩形的面积public double getArea() {return this.width * this.height;}
}
- 变值器 (Mutators):
变值器是一种方法类型,用于改变对象的状态或属性值。变值器方法会修改对象所代表的数据,这可能会改变对象的内部状态。当我们需要更改对象的属性或状态时,可以使用变值器方法。
示例:
public class Car {private String color;// 变值器方法,用于设置汽车的颜色public void setColor(String color) {this.color = color;}
}
以上是对Java中不同类型方法的详细解释,包括构造器、生产器、观察器和变值器。这些方法类型可以帮助我们更好地组织和理解类的功能,同时遵循良好的面向对象设计原则。
Designing an Abstract Type:
- 设计简洁、一致的操作
- 要足以支持client对数据所做的所有操作需要,且 用操作满足client需要的难度要低
- 要么抽象、要么具体,不要混合 — 要么针对抽象 设计,要么针对具体应用的设计
Representation Independence(表示独立性)
表示独立性:client使用ADT时无需考虑其内部如何实现,ADT内部表示的变化不应影响外部spec和客户端。
Example: Different Representations for Strings
The corresponding implementation for MyString
An example of the client
Another representation for better performance
Invariants of an ADT
总是要假设client 有“恶意”破坏ADT不变量的 行为—defensive programming
表示泄露的例子:
To make it immutable…+private.
Rep Invariant and Abstraction Function
R: the space of representation values (rep value)
:表示值构成的空间,实现者看到和使用的值。A: the space of abstract values
:抽象值构成的空间:client看到和使用的值。- ADT开发者关注表示空间R,client关注抽象空间A。 ADT的内部表示(私有属性)对外部都应严格不可见。故在代码中以注释的形式写出AF和RI而不 能在Javadoc文档中,防止被外部看到而破坏表示独立性/信息隐藏
A F ( A b s t r a c t i o n f u n c t i o n ) : R → A AF(Abstraction \ function): R → A AF(Abstraction function):R→A
An abstraction function that maps rep values to the abstract values they represent
抽象函数:R和A之间映射关系的函数,即如何将R中 的每一个值解释为A中的每一个值。
AF: 满射、非单射、 未必双射(R中的部分值并非合法的, 在A中无映射值)
R I ( R e p i n v a r i a n t ) : R → b o o l e a n RI(Rep \ invariant) : R→boolean RI(Rep invariant):R→boolean
A rep invariant that maps rep values to booleans
RI可以看作:所有表示值的一个子集,包含了所有合法的表示值
RI也可看作:一个条件,描述了什么是“合法”的表示值
设计ADT:(1) 选择R和A;(2) RI — 合法的表示值; (3) 如何解释合法的表示值 —映射AF
随时检查RI是否满足:在所有可能改变rep的方法内都要检查