面向对象设计实践指南

面向对象设计,难;有效的测试,很难;编写可更改的代码,更难!

从本书中,我学会了SOLID设计原则、以消息为中心、用对象扮演角色、以及如何有效地测试对象。

有的代码比其他代码不稳定,而测试就是重用,测试不稳定的代码必将产出不稳定的测试。为了降低测试成本,首先,得写出松耦合、可重用的代码;其次,则是测试公有接口、有选择地测试私有接口。

文摘

面向对象设计与依赖关系管理相关,它是一套对依赖关系进行编排,以便各个对象能够容忍更改的编码技术。

设计的目的是允许你以后可以进行设计,而设计的首要目标是降低变化所带来的成本。设计是保留可变性的艺术,而非达到完美性的行为。

面向对象系统的基础是消息,但最明显的组织结构是

  • 透明性(Transparent):在所更改的代码,以及在远处依赖于它的代码里,更改所产生的后果应该显而易见。

  • 合理性(Reasonable):任何更改所产生的成本都应该与更改所要带来的效益成正比。

  • 可用性(Usable):现有代码在新的环境和意想不到的环境里都能使用。

  • 典范性(Exemplary):代码本身应该鼓励那些为延续这些特点而对它进行的更改。

将额外的责任从方法里提取出来,将类里的额外职责隔离起来。

因为精心设计的类都具有单一职责,所以需要通过合作来完成复杂的任务。为实现合作,一个对象必须要知道其他对象的某些情况,这种“知道”便创建了一种依赖关系。

依赖那些变化情况比你所作的更改还要少的事物,这一思想建立在以下三个事实之上:

  • 有些类比其他类更容易发生需求变化;

  • 具体类比抽象类更容易发生变化;

  • 更改拥有许多依赖关系的类会造成广泛的影响;

消息是面向对象应用程序的中心,它们会在对象之间沿着公共接口传递。鸭子类型能将公共接口与特定类分离开来,并创建出“根据其做什么,而非是什么进行定义”的虚拟类型。

继承的核心是一种用于实现“消息自动委托”的机制。子类是其父类的特殊化,创建只有一个子类的抽象父类几乎没有什么意义。

有些问题需要在其他不相关的对象之间共享行为,这种公共行为对类来说是正交的,它是对象所扮演的角色

编写可更改的代码是一门艺术,其实践依赖于:深入理解面向对象设计、良好的重构能力以及编写有效测试的能力。