类的接口分为两部分
- 良好的抽象(Good Abstraction)
- 良好的封装(Good Encapsulation)
一、良好的抽象
类的接口应该展现一致的抽象层次。每一个类应该实现一个ADT,并且仅仅实现这个ADT。
一定要理解类所实现的抽象是什么。理解对应的ADT。
提供成对的服务,比如Add、Delete。On、Off等。不要盲目创建相反的操作,但是得考虑是否有需要
把不相关的信息转移到其他类中。当发现类中一半的方法在使用该类的一半数据,另一半的方法在使用另外一半的数据,这个时候已经把两个类混在一起了,需要拆分。
尽可能的让接口可编程,而不是语义表达。可编程的接口部分由接口中的数据类型和其他属性构成,编译器能强制要求他们,语义部分则由“本接口会被怎样使用”组成,如FuntionA必须在FunctionB调用之前进行调用。
不要添加与接口抽象不一致的公用成员,当要在类中添加方法时,先问问“这个方法与现有接口的所提供的抽象一致吗?”
同时考虑抽象性和内聚性,一个呈现很好抽象的类接口通常有很高的内聚性,反之亦然。如果发现某个类的内聚性很弱,也不知道该怎么修改,换一种方法:问问这个类是否表现为一致的抽象。
二、良好的封装
抽象通过提供一个可以让你忽略实现细节的模型来管理复杂度,而封装则用于强制组织让看到细节。
尽可能的限制类和成员的可访问性。
不要公开暴漏数据成员。
避免把私有的实现细节放入类的接口中。
不要对类的使用者做出任何假设。
不要因为一个子程序里仅仅使用了公用子程序,就把它归入公开接口。要反问:把这个子程序暴漏给外界后,接口所展示的抽象性是否还是一致的。