设计对象
一 、我们如何创建对象
确定类和交互常用类职责协同(Class—Responsibility—Collaboration,CRC),实现方法非常简单就是用一组3到5英寸的空白卡片,在上面书写。每张卡片描述一个类,在卡片上写的内容是:
(1)类的名字。这很重要因为名字体现了类行为的本质,所以有一目了然的作用。
(2)类的职责。它应当做什么,它可以仅由成员函数的名字描述(因为在好的设计中,这些名字是描述性的),但并不产生其他的标记。
(3)类的协同:它与哪些类有交互? “交互”是非常广泛的术语,它可以是已经存在的其它对象对这个类的对象提供的服务。协同还应该考虑这个类的观众如果创建Firecracker(鞭炮),那么谁将观察它,是Chemist(药剂师)还是Spectator(观众)?前者希望知道鞭炮由什么化学成分组成,后者对鞭炮爆炸后的颜色和形状有反应。
如果一个小卡片上装不下这么多信息,那么这个类就太复杂了(或者应当创建多个类)。理想的类应当一目了然。CRC卡片的思想是帮助我们找到设计的第一印象,使我们能得到设计的总体概念,然后提炼我们的设计。
二、对象设计的五个阶段
对象设计生命期不仅仅限于写程序的时间。实际上它出现在一系列的阶段上。接受这种观点很有好处,因为我们不再期望设计立刻尽善尽美,而是意识到,对对象做什么和它应该像什么理解,会随着时间的推移而呈现,这个观点也适应于不同类型的程序设计。特殊类型程序的设计模式是通过一次又一次的求解问题而形成的。同样,对象有自己的模式,通过理解、使用和重用组成。
(1)对象发现 这个阶段出现在程序的最初分析期间。对象可以通过寻找外部因素及边界、系统中重复的元素和最小概念单元而发现。如果已经有了一组类库,某些对象是很明显的。类之间的共同性(暗示着基类和继承关系),可以立刻出现或在设计过程的后期出现。
(2)对象装配 当我们正在建立对象时会发现一些新成员,这些新成员在对象发现时期未出现过。对象的这种内部需要可能要用新类去支持它。例如一个汽车类要用轮胎类,发动机类等零件类去支持它。
(3)系统构造 再次指出,对对象的更多要求可能出现在以后阶段。随着不断学习,我们会改进我们的对象。与系统中其他对象通信和互相连接的需要,可以改变已有的类或要求新类。例如我们可以发现需要辅助类,这些类如像一个链表,他们包含很少的状态信息或者没有状态信息,只有帮助其他类的功能。建立起对象之间的通信与联系,形成一个相互联系的集体。
(4)系统扩充 当我们向系统增添新的性能时,可能发现我们先前的设计不容易支持系统扩充。这时我们重新构造部分系统,并很可能要增加新类或层次。
(5)对象重用 这是对类真正强度的测试。如果有些人试图在全新的情况下重用它,他们也许会发现一些缺点。当我们修改一个类以适应更新的程序时,类的一般原则将变得很清楚,直到我们有了一个真正可以重用的对象。然而不要期望从一个系统设计而来的大多数对象是可重用的,大量对象是针对于特定系统的。可重用类一般共性较少,为类重用,它们必须解决更一般的问题。
三、对象开发准则
有以下步骤描述了开发类时要用到的一些准则:
(1)让特定问题生成一个类,然后在解决其它问题期间让这个类生长和成熟。
(2)记住,发现所需要的类(和它们的接口),是设计系统的主要内容。如果已经有了那些类,这个项目就不困难了。
(3)不要强迫自己在一开始就知道每一件事,应当不断学习加深。
(4)开始编程 ,让一些部分能够运行,这样就可以证明或否定已经生成的设计。不要害怕过程型大杂烩式的代码——类的隔离性可以控制他们。坏的类不会破坏好的类。
(5)尽量保持简单。具有明显用途的不太清楚地对象比复杂的接口好。选择简单的类,因为简单的类总是好一些。从小的和简单的类开始,当我们对它们有了较好的理解时再扩展这个类接口,但是很难从一个类中删去元素。