通常认为,一个易于维护的系统,就是复用率较高的系统;而一个复用性较好的系统,就是一个易于维护的系统。但是实际上,可维护性和可复用性是两个独立的目标,就像两只奔跑的兔子一样,并不总是方向一致的。

对于面向对象的软件系统设计来说,在支持可维护性的同时,提高系统的可复用性是一个核心的问题。

一、软件系统的可维护性

软件开发是一个比较快速的过程,一般只需要半年时间。但是系统的维护却是一个长期的过程,需要很多年。并且在一个软件项目的周期内,花费在维护上面的钱,是花费在原始开发上面的钱的两倍。

作为一个开发人员必须要认识到,软件的维护就是软件的再生。一个好的软件设计,必须能够允许新的设计要求以较为容易和平稳的方式加入到已有的系统中去,从而使这个系统能够不断的焕发青春。 一个可维护性较好的系统,应当允许维护工作能够以容易、准确、安全和经济的形式进行。

1、一个典型的软件生命周期

一个软件项目开始了,系统设计师拿到了系统的设计要求,设计师就会开始系统设计;这个系统毫无疑问将是一个优美的系统。系统的美,首先存在于设计师的头脑中,然后存在于设计图纸上,然后变成一个原型系统,最后变成一个真实的、有血有肉、可以交付客户使用的产品。

设计师喜欢看着他运行,程序员喜欢它的每一个功能键和图形视窗,而客户终于看到花出去的钱变成了实现。这个时候,这个系统就像一个美少女一样,毫无疑问是纯净的、优美的、动人心弦的。

但是不久事情就开始发生变化。客户看了运行的系统,又提出了一些“小小的”修改要求,这些要求都是客户在提出系统设计要求的时候遗忘的一些“小”问题。设计师讨论之后,给出了一些设计上面的修改。由于这些修改于现有系统的设计并不一定相容,所以设计师不得不采取一些权宜之计,是的这些修改看上去就像一个美丽少女脸上的青春痘。但是好像所有的软件都不能避免这些“青春痘”似的东西的出现,所以一切还不是很糟。

可是事情并没有就此结束,这些小的痘痘越来越多,而且其中有一些变成了系统的肿瘤。随着时间的流逝,这些肿瘤变成了系统中最主要的组成部分,当初的美少女变成了一个丑陋不堪,日渐“腐烂”的代码,以至于没有人愿意去维护他。人们把它叫做遗留系统,而不得不去维护这个遗留系统的人们,会天天诅咒设计这个系统的设计师:是谁设计出这么丑陋的一个东西??!!

经过一段漫长的时间后,“苦难”终于要结束了!在抱怨了软件系统的维护之昂贵之后,客户决定投入一笔资金,一个新的系统将被设计出来,而这个新系统将具有这个正在死去的系统的所有功能(当然还包括一些新的功能),并且取代这个已经“腐烂”的系统。

但是仔细想想,这个新系统会面临怎样的命运呢?也许这仅仅是下一个轮回的开始。

 2、导致这种情况的真正原因

导致一个软件设计的可维护性较低,也就是说会随着性能要求的变化而“腐烂”的真正原因有四个:过于僵硬、过于脆弱、复用率低、黏度过高。

①过于僵硬:很难在一个软件系统里加入一个新的性能,哪怕是很小的都很难。这是因为加入一个新新能,不仅仅意味建造一个独立的新模块,而且因为这个新性能会波及很多其他模块,最后变成跨越几个模块的改动。使得一个起初只需要几天的工作,最后变成持续好久的作战。由于这种设计上的缺陷,使得项目经理不敢轻易向系统加入新功能。这就造成一个软件系统一旦做好,就不能增加新功能的僵化情况。

②过于脆弱:与软件过于僵硬同时存在的,是软件系统在修改已有代码时过于脆弱。对一个地方的修改,往往会导致看上去没有什么关系的另一个地方发生故障。尽管在修改之前,设计师们会竭尽所能预测可能的故障地点,地那是在修改完成之前,系统的原始设计师们甚至都无法确切预测到可能会波及到的地方。这种一碰就碎的情况,造成软件系统过于脆弱。

③复用率低:所谓复用,就是指一个软件的组成部分,可以在同一个项目的不同地方甚至另一个项目中重复使用。每当程序员发现一段代码,函数,模块所做的事情是可以在新的模块、或者新系统中使用的时候,他们总会发现,这些已有的代码依赖于一大堆其他的东西,以至于很难将他们分开。最后,他们发现最好的办法就是不去“碰”这些已有的东西,而是重新写自己的代码。他们可能会使用源代码黏贴的办法,以最原始的复用方式,节省一些时间。这样的系统就有复用率低的问题。

④黏度过高:有的时候,一个改动可以保持原始的设计意图和原始设计框架的方式进行,也可以破坏原始意图和框架的方式进行。第一种办法无疑会对系统的未来有利,第二种办法是权宜之计,可以解决短期问题,但是会牺牲中长期的利益。

如果第二种办法比第一种办法容易很多的话,程序员就有可能牺牲中长期的利益,采取权宜之计:在模块中搭建一个短路桥,或者在一个通用的逻辑中制造一个特例,以便解决眼前的需要。

一个系统设计,如果总是使得第二种办法比第一种办法容易,就叫做年度过高。一个黏度过高的系统会诱使维护它的程序员采取错误的维护方案,并惩罚采取正确维护方案的程序员。

3、设计的目标

一个好的系统设计应该有如下的性质:可扩展性、灵活性、可插入性。这三条性质就是一个系统设计应当达到的目标。

①可扩展性:新的性能可以很容易的加入到系统中去,就是可扩展性。这就是系统“过于僵硬”的属性的反面。可扩展性要求一个新系统的加入,应该不会影响原有的功能,如果不是,则这个系统就不是扩展型很好的系统。

②灵活性:可以允许代码修改平稳的发生,而不会波及到很多其他的模块,这就是灵活性。比如一辆汽车的空调发生了故障,技师修理了空调。如果空调修好之后,发现系统的发动机不能启动了,这就不是一个灵活的系统。

③可插入性:很容易的讲一个类抽出去,同时将另一个有同样接口的类加入进来,这就是可插入性。比如应该可以很容易的将一辆汽车的防撞气囊取出来,换上一个新的。如果气囊拿出来后,汽车的传动杆不工作了,那么这个系统就不是一个可插入性很好的系统。

那么,怎样才能做出一个符合这三项要求的设计呢?关键是恰当的提高软件的可维护性和可复用性。

二、系统的可复用性

1、复用的重要性

软件的复用的好处有:①较高的生产效率;②较高的软件质量;③恰当使用复用可以改善系统的可维护性。更重要的是,复用与系统的可维护性有直接的关系。

2、传统的复用

在传统的理解中,复用有一下几种方式:①代码的黏贴复用;②算法的复用;③数据结构的复用;

3、可维护性与复用的关系

传统的复用方案的一个致命缺陷就是复用常常是以破坏可维护性为代价的。比如两个模块A和B同事使用另一个模块C中的功能。那么当A需要C增加一个新的行为的时候,B有可能不需要、甚至不允许C增加这个新行为。如果坚持使用复用,就不得不以系统的可维护性为代价;而如果从保持系统的可维护性出发,就只好放弃复用。可维护性与可复用性是有共同性的两个独立特性,他们就像是两只同时在奔跑的兔子,方向并不能一直保持一致。

因此,一个重要的概念就是支持可维护性的复用,也就是在保持甚至提高系统的可维护性的同时,实现系统的复用。

4、面向对象设计的复用

在面向对象的语言中,数据的抽象化、继承、封装和多态性是几项最重要的语言特性,这些特性使得一个系统可以在更高的层次上提供可复用性。数据的抽象化和继承关系使得概念和定义可以复用;多态性使得实现和应用可以复用;而抽象化和封装可以保持和催进系统的可维护性。这样一来,复用的焦点不再集中在函数和算法等具体实现细节上,而是集中在最重要的含有宏观商业逻辑的抽象层次上。换言之,复用的焦点发生了“倒转”。

发生复用焦点的倒转并不是因为实现细节的复用不再重要,而是因为这些细节上的复用往往已经做得很好,而且抽象层次是比这些细节更值得强调的复用焦点,因为它们是在提供复用性的同时保持和提高可维护性的关键。

既然抽象层次是一个应用系统做战略性判断和决定的地方,那么抽象层次就应当是较为稳定的,应当是复用的重点。如果抽象层次的模块相对独立于具体层次的模块的话,那么具体层次内部的变化就不会影响到抽象层次的结构,所以抽象层次的模块的复用就会较为容易。

5、对可维护性的支持

首先,恰当的提高系统的可复用性,可以提高系统的可扩展性。允许一个具有同样接口的新的类替代旧的类,是对抽象接口的复用。客户端依赖于一个抽象的接口,而不是一个具体实现类,使得这个具体类可以被另一个具体类所取代,而不影响到客户端。 系统的可扩展性是有“开-闭”原则,里氏代换原则、依赖倒转原则和组合/聚合复用原则所保证的。

其次,恰当的提高系统的可复用性,可以提高系统的灵活性。在一个设计得当的系统中,每一个模块都相对于其他模块独立存在,并只保持与其他模块的尽可能少的通信。这样一来,在其中某一个模块发生代码修改的时候,这个修改的压力不会传递到其他的模块。系统的灵活性是由“开-闭”原则、迪米特法则、接口隔离原则做保证的。

最后,恰当的提高系统的可复用性,可以提高系统的可插入性。在一个符合“开-闭”原则的系统中,抽象层封装了与商业逻辑有关的重要行为,这些行为的具体实现有实现层给出。当一个实现类不再满足需要,需要以另一个实现类取代的时候,系统的设计可以保证旧的类可以被“拔出”,新的类可以被“插入”。系统的可插入性是有“开-闭”原则、里氏代换原则,组合/聚合复用原则以及依赖倒转原则保证的。

这就是说,通过设计原则的灵活运用,是可以提高一个系统的可维护性同时,提高系统的可复用性的。灵活的使用设计原则进行系统设计,就可以抓到这两只同时在奔跑的兔子。

参照:《java与模式》

软件的可维护性与可复用性相关推荐

  1. 软件的可维护性与可复用性(一)(Java与模式笔记)

    第3章 软件的可维护性与可复用性 一个家用电器的维护,只是保持或者恢复电器的某种操作性能所需要的时间和资源.一个软件的维护则不同,它不仅包括清除错误和缺陷,而且还要包括对已有性能的扩充,以满足新的设计 ...

  2. 可维护性、可复用性和可扩展性的区别

    三者是不同的软件质量属性. 可维护性.可复用性又被认为是两个最重要的用于衡量软件质量的属性. 在<Java设计模式>一书中对可维护性的定义为:指软件能够被理解.改正.适应及扩展的难易程度. ...

  3. 系统架构师论文-论软件的可维护性设计

    论软件的可维护性设计 [摘要] 2008年3月1日至12月20日,我参加了"数据安全访问平台"项目的开发,担任系统分析员的工作.该项目是某行业用户"数据中心二期" ...

  4. 软件构造——可维护性

    本文是对软件构造课程软件可维护性相关内容的整理与理解,使用的编程语言为 Java.可维护性,也就是指软件发生变化时,是否可以以很小的代价适应变化. 软件维护和演化 软件维护 软件维护(software ...

  5. 大家一起学面向对象设计模式系列Chapter 02 软件设计的基本原则

    我们为什么要使用设计模式呢?有人可能会说为了设计出"高内聚低耦合"的软件."高内聚低耦合"的软件实际上也就是本文所说的具有可维护性和可复用性的软件. 这篇文章主 ...

  6. [摘抄]软件设计模式的几个原则

    原文地址:软件设计模式的几个原则 模式是一种对现实世界的概念抽象,建筑模式,设计模式,营销模式,商业运作模式各行各业都有自己的模式. 这里说的设计模式是软件设计里的模式,主要是指面向对象的软件设计.遵 ...

  7. 设计模式与软件体系结构复习资料——设计模式

    考试题型:选择.简答.设计 目录 软件设计模式 第一章 面向对象设计概述 1. 面向对象设计的表示方法 2. 优秀软件系统特性 3. 面向对象设计原则 3.1 ==单一职责原则== 3.2 ==开闭原 ...

  8. uml 时序图_设计模式:UML是怎么回事?设计原则?

    设计模式:UML是怎么回事?设计原则? 还未毕业,想着至少大学毕业前,设计模式多多了解,所以做相关笔记. UML相关概念 UML(Unified 统一 Modeling 建模 Language 语言) ...

  9. 如何掌握并在实践中自如运用设计模式

    设计模式是面向对象编程的热门话题之一,越来越多的开发人员认识到设计模式的重要性.采用各种语言实现设计模式的文章也越来越多,但是很多开发人员发现很难将设计模式与实际开发中需要解决的具体问题相联系.因为使 ...

最新文章

  1. 微信小程序scroll-view的使用
  2. 网络工程师转售前的条件
  3. python详细安装教程环境配置-[Python] 安装及环境配置
  4. 《数学之美》——第三章 个人笔记
  5. Java生鲜电商平台-深入订单拆单架构与实战
  6. WordPress模板-ripro主题系列对接易支付通用模块插件
  7. 美团酒旅数据治理实践
  8. ASP.NET MVC模型绑定int超出范围时
  9. 十五的学习日记20160925
  10. searchBar没有光标解决方法
  11. select标签multiple属性的使用方法
  12. ASP.Net MVC开发基础学习笔记(9):查看详情、编辑数据、删除数据
  13. Linux下oracle数据库备份方案
  14. WEB安全 HTML基础
  15. 1.冯诺依曼体系结构组成及其特点
  16. ryzen linux 搭配显卡,AMD Ryzen 2600CPU搭配什么显卡比较合理?
  17. 宝塔面板重启mysql命令_宝塔linux面板命令大全
  18. 网易后端二面经验分享
  19. 基础知识 - Unicode码
  20. 从零学起-----通识篇01 进制转换

热门文章

  1. Navicat For Mysql破解
  2. Who Wants to Be a Millionaire?
  3. BeanDefinition的概述及使用
  4. Scara机器人关节空间轨迹规划-机器人工具箱函数jtraj
  5. 计算机专业不会打字怎么办,科目一考试电脑怎么用?科目一不会打字怎么办
  6. 媒体查询--自适应屏幕大小
  7. 斐波那契回调线怎么画_斐波那契回调线(黄金分割线)神级操作-经典
  8. IT工程师 毕业4年我年薪涨到30万
  9. 丹江口计算机学校,丹江口中专学校计算机网络技术寒假实习
  10. 调用小程序OCR插件识别身份证信息