1。软件的可维护性与可复用性 软件的维护就是软件的再生。系统的设计目标: 可扩展性,灵活性,可插入性。 可扩展性: 新的功能很容易集成到现有的系统中去,而不影响到系统的其余模块。 灵活性: 容许代码修改平稳的发生。当修改一处时不至于影响到另外一处,这样能够缩小维护的代价。 可插入性: 容易用一个类替换已经存在的类。只要接口一致,更改实现类不影响类的使用者。 软件的复用能够提升软件的生产率,而且恰当的复用能够提升软件的可维护性。 在之前,复用主要是代码,函数,结构的复用,而如今复用主要针对类,接口,组件等等。可是复用并不必定会保证软件的可维护性。不能由于代码的重复等缘由就复用,须要根据具体的状况来分析。要想经过复用来增强系统的可维护性,必须保证复用是支持可维护性的复用。 下面的一些设计原则能够用来指导实践。 2。开-闭 原则(OCP) 开闭原则是面向对象可复用的基石。它主要指:一个软件实体对扩展开放,对修改关闭。在设计一个模块的时候,应当是这个模块在不被修改前提下被扩展。知足这个原则的系统在一个较高层次上实现了复用,也是易于维护的。 那如何才能知足开闭原则呢?抽象化是关键。要区分开抽象层和实现层。在一个软件系统中,抽象层应该是相对稳定的,而实现层是能够改变扩展的。 开闭原则也是对可变性的封装原则。找到系统的可变因素,并将其封装起来。把一种可变性封装为一个对象,那么这种可变性的不一样表象就是这个类的具体子类。 3。里氏代换原则(LSP) 里氏代换原则是继承复用的基石:在任何父类出现的地方均可以用它的子类来替代。例如正方形和长方形。正方形是一种特殊的长方形。可是正方形却不能做为长方形的子类。因对长方形的操做并不必定能套用在正方形上。如:resize().若是正方形做为长方形的子类的话,那么就会出现不少问题。不符合里氏代换原则,正方形就不能做为长方形的子类,应该把正方形和长方形都做为四边形的子类。在实际,设计类的阶层系结构时,这是一条很重要的原则。不该该做为子类不能硬套。 4。依赖倒转原则(DIP) 依赖倒转原则是:要依赖于抽象,不要依赖于具体的实现。 为何叫依赖倒转原则呢? 在传统的过程性系统中,高层的模块依赖于低层次的模块,抽象层次依赖于具体层次。这样致使了底层的任何改变都会影响到上层。这样的软件系统没有可维护性而言。 抽象层次应该不依赖于具体的实现细节,这样才能保证系统的可复用性和可维护性,这也就是所谓的倒转。 在实际中如何应用这一原则呢? 要针对借口编程,而不针对实现编程。那么当实现变化时,不会影响到其余的地方。 在java中应当使用接口和抽象类来进行变量的类型声明, 参数的类型声明,方法的返回值类型,等等。好比: List list = new Linkedlist(); 以抽象的方式进行耦合是依赖倒转原则的关键。 依照依赖倒转原则,在系统中会出现大量的类,如抽象类和接口,由于它假定全部的具类都是有可能变化的。但实际上这也不老是正确的。有些具体类是很是稳定的,就不须要为他发明一种新的类型。 5。 接口隔离原则(ISP) 使用多个专门的借口老是比使用单一的总接口要好。一个接口应该仅表明一个角色,而不该该把全部的操做都封装到一个接口当中。准确地划 分角色和其所对应的接口,不该该把没有关系的接口合并到一块儿。 6。合成/聚合复用原则 聚合: 表示拥有或总体与部分的关系。 合成:更强的聚合关系。总体负责部分的生命周期,总体和部分是不可分的,部分是不能被共享的。好比孙悟空 ,他的四肢, 和他的武器。 悟空和四肢的关系就是合成,而和武器之间的关系就是聚合。 在面向对象中,有继承和合成/聚合两种基本服用方法。合成/聚合是将已有对象做为本身的成员,新对象调用对象已有的功能。这有不少优势: 1) 这种复用是黑箱操做,把成员对象的细节封装起来。 2)这种复用能够动态的改变,新对象能够动态的引用其余的同类对象。 继承复用有以下的优势和缺点。 1)容易实现。 2)继承复用破坏了包装,将超类的实现细节暴露给子类。 3)同时若是超类发生改变,子类也不得不跟着改变。 4)继承是静态的。 尽可能使用和成/聚合而不是继承来实现复用。而区分这两种关系,区分”Has-A”和“Is-A”的关系。能正确的区分二者,应该就能正确的使用 这两种复用方式。例如:人和角色。一般使用继承,能够把每一个角色做为人的子类。如学生,雇员,经理等。可是继承是静态的,一旦一我的有了一个角色后就不能再拥有其余的角色。好比一我的是经理,但它也是雇员,也多是学生。这显然是不合理的。应该采用合成/聚合复用则。实际上人与角色是“Has-A”而不是” Is-a”的关系,而且只有当知足里氏代换原则的时候才能使“Is-a”的关系。 在java api中 Properties 继承 Hashtable。Proterties具备了Hashtable的全部行为。实际上,Properties根本就不是一种Hashtable.更严重是把Properties能够向上转型为Hashtable,,绕过Properties接口,调用Hashtable的方法来对Properties操做,会致使Properties的内部矛和崩溃。他们之间能够是“Has-a”,但不能是”Is-a”的关系。在实际中,决不能由于代码和功能上的复用而滥用继承,使用继承时必定要知足里氏代换原则。 7。迪米特法则(LoD) 迪米特法则: 一个对象应当对其余对象尽量少的了解。如下是一些表述: 1) 只和你直接的朋友通讯 2) 不要和陌生人讲话。 3)每个软件单位都对其余单位只有最少的知识。 其目的就是下降各个单元的耦合,提升系统的可维护性。在模块之间,其通讯应该只经过彼此的API来通讯,而不理会模块的内部工做原理。它可使各个模块耦合程度降到最低,促进软件的复用。 本文转自程式先锋网站 www.javabiz.cn