《面向对象设计实践指南:Ruby语言描述》—第1章 1.2节设计工具

1.2 设计工具
面向对象设计实践指南:Ruby语言描述
设计可不是遵循一套固定规则就完事的动作。它是每次沿着一条分支前进的旅行,在这条路径上早期的选择关闭了某些选择,同时又会打开其他新的选择。在设计过程中,你会徘徊于各种错综复杂的需求中,这里的每个关键时刻都代表着一个决策点,它会对将来产生影响。

像雕塑家有凿子和文稿一样,面向对象的设计师也有自己的工具—原则和模式。

1.2.1 设计原则
SOLID原则首先由Michael Feathers提出,再由Robert Martin进行了推广。它代表了5个最有名的面向对象设计原则,即单一职责原则(Single Responsibility Principle,SRB)、开闭原则(Open-Closed Principle,OCP)、里氏替换原则(Liskov Substitution Principle,LSP)、接口隔离原则(Interface Segregation Principle,ISP)以及依赖倒置原则(Dependency Inversion Principle,DIP)。另外还有其他一些原则,如Andy Hunt和Dave Thomas提出的不重复原则(Don’t Repeat Yourself,DRY),以及源于美国东北大学迪米特项目的迪米特法则(Law of Demeter,LoD)。

这些原则都贯穿于全书。现在的问题是:“它们究竟从何而来?”这些原则很有价值,有证据证明吗?或者它们只是某些人的个人观点,你甚至可以对其随意贬损,情况是如此吗?归根结底,它们究竟是谁提出来的?

所有这些原则在一开始都只是人们在编写代码时所做的一些选择。早期的面向对象程序员发现有些代码编排可以让他们的工作变得更轻松,而其他的编排则会让他们感觉更累。这些经验引导他们形成了如何编写出优秀代码的观点。

后来,学者们参与了进来。为撰写研究论文,他们于是决定要量化“什么是优秀代码”。这种想法很值得称赞。如果能对事物进行统计(如计算代码的度量指标),并将这些度量指标与应用程序质量的高低关联起来(为此,我们还需要一个客观的测量标准),那么我们就可以多做能降低成本的事情,少做会增加成本的事情。能够对质量进行测量将OO设计从争论不休的观点变成为可测量的科学。

20世纪90年代,Chidamber、Kemerer1和Basili2正好从事这方面的研究。他们收集了许多面向对象的应用程序,想尽一切办法改善这些编码的质量。他们为很多事情进行命名和测量,如类的整体尺寸、多个类之间彼此的关联度、继承层次的深度和广度,以及以任何发送消息的结果形式获得调用的方法的数量。他们选择了自己认为很重要的代码进行编排,并设计出公式来对它们进行统计,然后将最终的度量与封闭程序的量进行关联。他们的研究显示:这些技术的使用和高质量的代码之间存在显著关联。

虽然这些研究看起来是证明了设计原则的有效性,但对于任何经验丰富的程序员来说,都需要慎重选用它们。早期的研究都只是检查了由一些研究生编写的非常小型的应用程序,仅此一点就足以证明需要审慎地看待这些结论。这些应用程序里的代码不可能完全代表真实世界里的OO应用程序。

不过,事实证明这种谨慎是多余的。2001年,Laing和Coleman检查了多个NASA Goddard太空飞行中心的应用程序(火箭科学),并希望能找到“一种能生产出更便宜和高质量软件的方法” 3。他们检查了三个优劣各异的应用程序,其中一个包含1 617个类和500 000多行代码。他们的研究完全支持先前的研究成果,从而进一步证实了设计原则的重要性。

即使是你从未阅读过这些研究,也可以对他们的结论持有信心。那些实现优秀设计的原则所代表的是可测量的真理,遵循它们能改善你的代码。

1.2.2 设计模式
除了这些原则,面向对象设计还包含了许多模式。有一个所谓的“四人组”(Gang of Four, Gof),即Erich Gamma、Richard Helm、Ralph Johnson和Jon Vlissides,他们于1995年一起编写了关于模式的开创性著作。他们的书籍《设计模式》将模式描述为“在面向对象的软件设计中,针对特定问题的简单而优雅的解决方案”,你可以用它来“让自己的设计更加灵活、更具有模块化、更易重用和更易理解”。4

设计模式的概念极其强大。对常见问题进行命名,并使用常用的方法来解决这些问题,采用这种方式可以将模糊的内容聚焦在一起。设计模式为整整一代的程序员提供了交流和协作的手段。

在每位设计师的工具箱里总能见到多种模式的存在。对其所解决的问题来说,每一个无人不晓的模式都是一种近乎完美的开源解决方案。不过,模式的流行也导致有的模式被程序员新手过度滥用的问题。他们有时会热情过头,将非常优秀的模式应用到错误的问题上。模式的误用会导致代码变得非常复杂且混乱不堪,但是出现这样的结果并不是模式本身的问题。一种工具不能因其用途而受到责怪,使用者必须要掌握好这个工具。

本书不是要讨论模式,而是会想方设法让你理解它们,并且教你如何正确地选择和使用它们。

1 Chidamber, S. R., & Kemerer, C. F. (1994). A metrics suite for object-oriented design. IEEE Trans. Softw. Eng. 20(6): 476–493.
2 Basili Technical Report (1995). Univ. of Maryland, Dep. of Computer Science, College Park, MD, 20742 USA. April 1995. A Validation of Object-Oriented Design Metrics as Quality Indicators.
3 Laing, Victor & Coleman, Charles. (2001). Principal Components of Orthogonal Object-Oriented Metrics (323-08-14).
4 Gamma, E., Helm, R., Johnson, R., & Vlissides, J. (1995). Design Patterns, Elements of Reusable Object-Oriented Software. New York, NY: Addison-Wesley Publishing Company, Inc.

本文仅用于学习和交流目的,不代表异步社区观点。非商业转载请注明作译者、出处,并保留本文的原始链接。

时间: 2024-08-22 14:28:22

《面向对象设计实践指南:Ruby语言描述》—第1章 1.2节设计工具的相关文章

《面向对象设计实践指南:Ruby语言描述》目录—导读

内容提要 面向对象设计实践指南:Ruby语言描述 本书是对"如何编写更易维护.更易管理.更讨人喜爱且功能更为强大的Ruby应用程序"的全面指导.为帮助读者解决Ruby代码难以更改和不易扩展的问题,作者在书中运用了多种功能强大和实用的面向对象设计技术,并借助大量简单实用的Ruby示例对这些技术进行全面解释. 全书共9章,主要包含的内容有:如何使用面向对象编程技术编写更易于维护和扩展的Ruby代码,单个Ruby类所应包含的内容,避免将应该保持独立的对象交织在一起,在多个对象之间定义灵活的接

《面向对象设计实践指南:Ruby语言描述》—第1章 1.3节设计行为

1.3 设计行为 面向对象设计实践指南:Ruby语言描述 随着常见设计原则和模式的出现与传播,所有的OOD问题可能都已被解决.既然基础的规则都已知道,那么设计面向对象的软件还会有多难呢? 事实证明,它非常难.如果将软件理解为可定制的家具,那么原则和模式便像是木工的工具.了解软件在完成后会是什么样子,并不能让它自我构建成那个样子.应用程序之所以存在,是因为有程序员使用了这些工具.最终的结果可能是,它要么成为一个漂亮的橱柜,要么成为一张摇摇晃晃的椅子.具体是哪一种结果,则取决于程序员使用设计工具的经

《面向对象设计实践指南:Ruby语言描述》—第1章 1.1节设计赞歌

第1章 面向对象设计 面向对象设计实践指南:Ruby语言描述 世界是过程式的.时间不停在向前流动,而事件也一个接一个地逝去.你每天早上的过程或许就是:起床.刷牙.煮咖啡.穿衣,然后上班.这些活动都可以使用过程软件来建模.因为了解事件的顺序,所以你可以编写代码来完成每一件事情,然后仔细地将这些事情一个接一个地串在一起. 世界也是面向对象的.与你互动的对象可能包括有你的老伴和猫,或者是车库里的旧汽车和一大堆的自行车零件,又或者是你的那颗扑通跳动的心脏,以及用来保持健康的锻炼计划.在这些对象中,每一个

《面向对象设计实践指南:Ruby语言描述》—第1章 1.4节 面向对象编程简介

1.4 面向对象编程简介 面向对象设计实践指南:Ruby语言描述 面向对象的应用程序由对象和它们之间传递的消息构成.其中,消息相对更为重要.但在本节的简介里(以及在本书的前面几个章节里),这两个概念都同等重要. 1.4.1 过程式语言 相对于非面向对象(或过程式)的编程来说,面向对象编程是面向对象的.依据这两种风格的差异来考虑它们很有意义.假设有这么一种通用的编程语言,它可用来创建简单的脚本.在这门语言里,你可以定义变量(即组成多个名称),并将这些名字与少量的数据相关联.一旦进行了分配,便可以通

《面向对象设计实践指南:Ruby语言描述》—第1章 1.5节小结

1.5 小结 面向对象设计实践指南:Ruby语言描述 如果某个应用程序存活了很长时间(也就是说,如果它成功了),那么它最大的问题将是如何应对变化.通过代码编排有效地应对变化是设计的事情.最常见的设计要素是原则和模式.不幸的是,即使正确地运用了原则,并且也恰当地使用了模式,也无法保证能够很好地创建出易于更改的应用程序. OO度量能暴露出应用程序在遵循OO设计原则方面的情况.糟糕的度量值强烈地表明将来可能会遭遇困难:不过,好的度量值也发挥不了太大的作用.一个做法有问题的设计也可能产生出很高的度量值,

《面向对象设计实践指南:Ruby语言描述》—第8章 8.1节组合对象

第8章 组合对象 面向对象设计实践指南:Ruby语言描述 组合(composition)是指将不同的部分结合成一个复杂整体的行为,这样整体会变得比单个部分的总和还要大.例如,音乐就是组合而成的. 你可不能将软件当作是音乐,那只是一种类比.贝多芬的第五交响曲乐谱是一长串独特而又独立的记号.你只听一遍就会明白:尽管它包含的是一些记号,但它不是记号.它是另一回事. 你可以按同样的方式来创建软件,使用面向对象的组合技术来将简单.独立的对象组合成更大.更复杂的整体.在组合过程中,较大的那个对象通过"有一个

《面向对象设计实践指南:Ruby语言描述》—第8章 8.2节组合成Parts对象

8.2 组合成Parts对象 面向对象设计实践指南:Ruby语言描述 很明显,零件列表会包含一长串的单个零件.现在应该添加表示单个零件的类了.单个零件的类名显然应该为Part.不过,当你已拥有一个Parts类时,引入Part类会让交谈变得很困难.当同样的这个名字已经用于指代单个的Parts对象时,使用"parts"一词来指代一堆的Part对象很容易让人感到困惑.不过,前面的措辞说明了一种会顺带引起交流问题的技术.当在讨论Part和Parts时,你可以在类名之后带上"objec

《面向对象设计实践指南:Ruby语言描述》—第8章 8.3节制造Parts

8.3 制造Parts 面向对象设计实践指南:Ruby语言描述 回顾一下上面的第4-7行.那些Part对象存放在chain.mountain_tire等变量里面.它们都是很久以前创建的,你可能已经把它们给忘了.请仔细想想这四行所代表的知识主体.在应用程序里的某个地方,会有对象必须要知道如何创建这些Part对象.而在上面的第4-7行,在那个地方必须要知道与山地自行车一起的这四个特定对象. 这里包含了很多的知识,它很容易在应用程序里泄漏掉.这种泄漏情况,既不幸也没必要.虽然有很多不同的单个零件,但有

《面向对象设计实践指南:Ruby语言描述》—第8章 8.4节组合成Bicycle

8.4 组合成Bicycle 面向对象设计实践指南:Ruby语言描述 下面的代码展示了Bicycle使用组合的情况.它展示了Bicycle.Parts.PartsFactory,以及针对公路和山地自行车的设置数组. Bicycle有一个Parts,而Parts依次有一个Part对象集合.Parts和Part都可以以类形式存在,但包含它们的对象会把它们当成角色.Parts是一个扮演Parts角色的类,它实现了spares.而Part的角色则由OpenStruct扮演,它会实现name.descri