前言
“杀死一个程序员不需要用枪,改三次需求就可以了”,虽然这是一句话笑话,但也从侧面描述出了软件的可维护性重要性
知名软件大师Robert C.Martin认为一个可维护性(Maintainability)较低的软件设计,通常由于以下4个原因造成
1)过于僵化(Rigidity):设计难以修改
2)过于脆弱(Fragility):设计易遭到破坏(需要修改的时候,容易牵一发而动全身,不该受到影响的代码也被迫的破坏掉)
3)牢固性(Immobility):复用率低(当想使用一些功能时会发现里面的某些代码不是他想要的,想把这些代码去掉时,发现没办法去掉,原因是代码耦合度太高了)
4)粘度过高(Viscosity):难以做正确事情(维护的过程中想进行修改某些代码,但是发现没有办法进行修改,原因就是粘度太高)
软件工程和建模大师PeterCoad认为,一个好的系统设计应该具备如下三个特性:
1)可扩展性(Extendibility)
2)灵活性(Flexibility)
3)可插入性(Pluggability)
面向对象设计原则和设计模式也是对系统进行合理重构,重构是在不改变软件现有功能的基础上,通过调整代码改善软件的质量、性能,使其程序的设计模式和架构更趋合理性,提高软件的扩展性和维护性。
七种原则并不是孤立存在的,他们相互依赖,相互补充。
1.单一职责原则(重要性4颗星)
概述:
类的职责要单一,不能将太多的职责放在一个类中
定义:
一个对象应该只包含单一的职责,并且该职责被完整地封装在一个类中(另一种定义是就一个类而言,应该仅有一个引起它变化的原因。)
原则分析:
1)一个类承担的职责越多,它被复用的可能性越小,而且如果一个类承担的职责过多,就相当于将这些职责耦合在一起,当其中一个职责变化时,可能会影响其他职责的运作。
2)类的职责主要包括俩个方面:数据职责和行为职责,数据职责通过其属性来体现,而行为职责通过其方法来体现。(注重行为职责)
3)单一职责原则是实现高内聚,低耦合的指导方针,在很多代码重构手段中都能找到它的存在,它是最简单又最难运用的原则,需要实际人员发现类的不同职责将其分离,而发现类的多重职责需要设计人员具有较强的分析设计能力和相关重构经验。
实例说明:
登录功能通过如下登录类(Login)实现:
init方法是对登录页面进行初始化的方法
display方法是显示登录界面
validate方法是对登录的账户和密码的合法性进行验证(页面上的语法验证)
getConnertion和findUser方法对账户和密码的合法性进行具体验证
main方法是程序的入口
设计分析:
前三个是页面的方法,后面俩个是业务上的方法,最后一个是程序的入口,几个方法都属于不同方面的,说明承担的职责有些多。一个类应该只有一个点变化点,应该各司其职,不能因为某个原因而导致类发生改变,反之就表明这个类承担的职责太多了。打个比方说如果页面发生改变,init方法就需要进行更改;再打个比方说验证规则发生变化,validate方法需要更改等;这些都是变化点。所以说Login是不符合单一职责原则的(所以说,我们可以通过变化点来判断是否符合单一职责原则)。
现使用单一职责原则对其进行重构。
设计分析:
将Login进行分解为MainClass(负责程序的入口)LoginForm(界面视图),UserDAO(和用户对象打交道的类),DBUtil(负责和数据库进行连接的类)这样的四个类。我们可以看出这四个是不同的变化点,它们之间都是无关的,大打个比方说,如果界面需要改变,我们只需要将LoginForm类里面的方法,不需要更改其他类的方法,因此这样的分解是真正符合单一职责原则。
总结:
如果遵循单一职责原则的思想的话,我们就可以将一个复杂(或承担过多职责)的类按照业务逻辑这种思想把它进行分解,拆分成一个个高内聚低耦合的这样的一个类,最终目的是提高软件(或者这个类)的可维护性(或者可复用性),所以说这个思想是非常简单,但是我们在做的时候却是很难的。从这里我们应该也能看出来结构是非常重要的。所以我们在平时的练习中有意识的往这方面靠近,一定要认真的遵循这个原则。
2.开闭原则(重要性5颗星)
概述:
软件实现对扩展是开放的,但对修改是关闭的,即在不修改一个软件实体的基础上去扩展其功能
定义:
也就是说在设计一个模块的时候,应对这个模块可以在不被修改的前提下被扩展,即实现在不修改源代码的情况下改变这个模块的行为。
原则分析:
1)开闭原则由Bertand Meyer于1988年提出的,它是面向对象设计中最重要的原则之一。
2)在开闭原则的定义中,软件实体可以指一个软件模块、一个由多个类组成的局部结构或一个独立的类。
3)抽象化是开闭原则的关键。
注:
抽象是指一个类或者多个类里面共性的东西抽取出来。
抽象的最大好处就是稳定的、可靠的‘不容易发生改变的。
4)开闭原则还可以通过一个更加具体的“对可变性封装原则“来描述,对可变性原则要求找到系统的可变因素并将其封装起来。
实例说明:
某图形界面系统提