《代码大全》阅读笔记-6-可以工作的类

抽象数据类型是指一些数据以及对这些数据所进行的操作的集合

接口/API先行——Tacey

只有一个实例的类是值得怀疑的

不要创建任何并非绝对必要的继承结构

继承层次尽量限制在3层之内

如果可能,应该在所有的构造函数中初始化所有的数据成员(防御式编程实践)

优先使用深拷贝


创建类的原因

  • 为现实世界中的对象建模
  • 为抽象的对象建模
  • 降低复杂度
  • 隔离复杂度
  • 隐藏实现细节
  • 限制变动的影响范围
  • 隐藏全局数据
  • 让参数传递更顺畅
  • 建立中心控制点
  • 让代码更易于重用
  • 为程序族做计划
  • 把相关操作包装在一起
  • 实现某种特定的重构

应该避免

  • 避免创建万能类
  • 消除无关紧要的类
  • 避免用动词命名的类

超越类:包

核对表:类的质量

抽象数据类型

  • 你是否把程序中的类都看作是抽象数据类型了?是否从这个角度评估它们的接口了?

抽象

  • 类是否有一个中心目的
  • 类的命名是否恰当?其名字是否表达了其中心目的?
  • 类的接口是否展现了一致的抽象?
  • 类的接口是否能够让人清除明白地知道该如何用它
  • 类的接口是否足够抽象,使你能不必顾虑它是如何实现其服务的?你能把类当作做黑盒子吗?
  • 类提供的服务是否足够完整,能让其他类无需动用其内部数据?
  • 是否已从类中除去无关信息?
  • 是否考虑过把类进一步分解为组件类?是否已尽可能将其分解?
  • 在修改类时是否维持其接口的完整性

封装

  • 是否把类的成员的可访问性降到最小?
  • 是否避免暴露类中的数据成员
  • 在编程语言所许可的范围内,类是否已尽可能地对其他类隐藏了自己的实现细节?
  • 类是否避免对其使用者,包括其派生类会如何使用它做了假设?
  • 类是否不依赖于其他类?他是松散耦合的吗?

继承

  • 继承是否只用来建立“is a”的关系?也就是说,派生类是否遵循了LSP替换原则
  • 类的文档中是否技术了其他继承策略?
  • 派生类是否避免了“覆盖”不可覆盖的方法?
  • 是否把公用的接口、数据和行为都放到尽可能高的继承层次中了?
  • 基类中所有的数据成员是否都被定义成了private而非protected?
  • 继承层次是否很浅?

跟现实相关的其他问题

  • 类是否有只有大约七个或更少的数据成员?
  • 是否把类直接或间接调用其他类的子程序的数量减少到最少了?
  • 类是否只在绝对必要时才与其他的类相互协作?
  • 是否在构造函数中初始化了所有的数据成员 (防御)
  • 除非拥有经过测量的、创建浅层复本的理由,类是否都被设计为当做生成副本使用?

与语言相关的问题

  • 你是否研究过所用编程语言里和类相关的各种特有问题?

要点

  • 类的接口应提供一致的抽象。很多问题都是由于违背该原则而引起的。
  • 类的接口应隐藏一些信息——如某个系统接口、某项设计决策、或一些实现细节
  • 包含往往比继承更为可取——除非你要对is a 的关系建模
  • 继承是一种有用的工具,但它却会增加复杂度,这有违于软件的首要技术使命——管理复杂度
  • 类是管理复杂度的首选工具。要在设计类时给予足够的关注,才能实现这一目标
posted @ 2018-04-03 23:35  Tacey Wong  阅读(422)  评论(0编辑  收藏  举报