设计模式6大原则:里氏置换原则

1. 里氏替换原则

里式替换原则(Liskov Substitution Principle,LSP),全部引用基类的地方必须可以透明的使用其子类对象。也就是说,只要父类出现的地方都能替换为子类,不会产生异常。可是反过来,子类出现的地方,替换为父类就可能出现问题。 也就是子类能够扩展父类的功能,但不能改变父类的功能。 通俗的讲:类须要扩展功能时,新类继承旧类,使用新类替换旧类不会形成故障。 
1. 子类能够实现父类的抽象方法,但不能覆盖父类的非抽象方法; 
2. 子类中能够增长本身持有的方法; 
3. 当子类的方法重载父类的方法时,方法的前置条件(即方法的形参)要比父类方法的输入参数更宽松; 
4. 当子类的方法实现父类的抽象方法是,方法的后置条件(即方法的返回值)要比父类更严格。html

2. 单一职责原则

单一职责原则(Single Responsibility Principle, SRP), 
There should never be more than one reason for a class to change. (应该有且仅有一个缘由引发类的变动) 
如下摘自:http://blog.csdn.net/vebasan/article/details/8003102 
有时候,开发人员设计接口的时候,将用户的属性和用户的行为放在一个接口中声明。这就形成业务对象和业务逻辑放在一块儿了。 
例子:web

public interface Itutu {
    //height
    void setHeight(double height);    void getHeight();    //weight
    void setWeight(double weight);    void getWeight();    //eat
    void eat(boolean hungry);    //surf in internet
    void internet(boolean buy);
}

单一职责的意义 
1. 下降类的复杂性,实现什么样的职责都有清晰的定义; 
2. 提升可读性和可维护性; 
3. 下降变动引发的风险,对系统扩展性和维护性颇有帮助。编程

3. 依赖倒置原则

依赖倒置原则(Dependency Inversion Principle, DIP) 
Definition: High level modules should not depend upon low level modules, Both should depend upon abstractions. Abstractions should not depend upon details, details should depend upon abstractions.框架

即:高层模块不该该依赖低层模块,两者都应该依赖其抽象。抽象不该该依赖细节,细节应该依赖抽象。工具

抽象:即抽象类或接口,是不可以实例化的。this

细节:即具体的实现类,实现接口或者继承抽象类所产生的类,能够经过关键字new直接被实例化。spa

每个逻辑的实现都是由原子逻辑组成的,不可分割的原子逻辑就是低层模块,原子逻辑的再组装就是高层模块。.net

面向接口编程 
如下摘自http://www.cnblogs.com/cbf4life/archive/2009/12/15/1624435.html设计

讲了这么多,估计你们对“倒置”这个词仍是有点不理解,那到底什么是“倒置”呢?咱们先说“正置”是什么意思,依赖正置就是类间的依赖是实实在在的实现类间的依赖,也就是面向实现编程,这也是正常人的思惟方式,我要开奔驰车就依赖奔驰车,我要使用笔记本电脑就直接依赖笔记本电脑,而编写程序须要的是对现实世界的事物进行抽象,抽象的结果就是有了抽象类和接口,而后咱们根据系统设计的须要产生了抽象间的依赖,代替了人们传统思惟中的事物间的依赖,“倒置”就是从这里产生的。code

依赖倒转原则的本质就是经过抽象(接口或抽象类)使各个类或模块的实现彼此独立,不互相影响,实现模块间的松耦合,咱们怎么在项目中使用这个规则呢?只要遵循如下的几个规则就能够:

每一个类尽可能都有接口或抽象类,或者抽象类和接口二者都具有。 
这是依赖倒置的基本要求,接口和抽象类都是属于抽象的,有了抽象才可能依赖倒置。

变量的显示类型尽可能是接口或者是抽象类。 
不少书上说变量的类型必定要是接口或者是抽象类,这个有点绝对化了,好比一个工具类,xxxUtils通常是不须要接口或是抽象类的。还有,若是你要使用类的clone方法,就必须使用实现类,这个是JDK提供一个规范。

任何类都不该该从具体类派生。 
若是一个项目处于开发状态,确实不该该有从具体类派生出的子类的状况,但这也不是绝对的,由于人都是会犯错误的,有时设计缺陷是在所不免的,所以只要不超过两层的继承都是能够忍受的。特别是作项目维护的同志,基本上能够不考虑这个规则,为何?维护工做基本上都是作扩展开发,修复行为,经过一个继承关系,覆写一个方法就能够修正一个很大的Bug,何须再要去继承最高的基类呢?

尽可能不要覆写基类的方法。 
若是基类是一个抽象类,并且这个方法已经实现了,子类尽可能不要覆写。类间依赖的是抽象,覆写了抽象方法,对依赖的稳定性会产生必定的影响。

4. 开闭原则

抽象层肯定后再也不修改。经过抽象层导出多个新的具体类实现扩展。

5. 接口隔离原则

客户端不该该不依赖它不须要的接口,一个类对另外一个类的依赖应该创建在最小的接口上。使用多个专门的接口比使用单一的总接口要好。 
一个类对另一个类的依赖性应当是创建在最小的接口上的。 
一个接口表明一个角色,不该当将不一样的角色都交给一个接口。没有关系的接口合并在一块儿,造成一个臃肿的大接口,这是对角色和接口的污染。 
“不该该强迫客户依赖于它们不用的方法。接口属于客户,不属于它所在的类层次结构。”这个说得很明白了,再通俗点说,不要强迫客户使用它们不用的方法,若是强迫用户使用它们不使用的方法,那么这些客户就会面临因为这些不使用的方法的改变所带来的改变。

接口隔离原则的含义是:创建单一接口,不要创建庞大臃肿的接口,尽可能细化接口,接口中的方法尽可能少。也就是说,咱们要为各个类创建专用的接口,而不要试图去创建一个很庞大的接口供全部依赖它的类去调用。本文例子中,将一个庞大的接口变动为3个专用的接口所采用的就是接口隔离原则。在程序设计中,依赖几个专用的接口要比依赖一个综合的接口更灵活。接口是设计时对外部设定的“契约”,经过分散定义多个接口,能够预防外来变动的扩散,提升系统的灵活性和可维护性。

说到这里,不少人会觉的接口隔离原则跟以前的单一职责原则很类似,其实否则。其一,单一职责原则原注重的是职责;而接口隔离原则注重对接口依赖的隔离。其二,单一职责原则主要是约束类,其次才是接口和方法,它针对的是程序中的实现和细节;而接口隔离原则主要约束接口接口,主要针对抽象,针对程序总体框架的构建。

采用接口隔离原则对接口进行约束时,要注意如下几点:

接口尽可能小,可是要有限度。对接口进行细化能够提升程序设计灵活性是不挣的事实,可是若是太小,则会形成接口数量过多,使设计复杂化。因此必定要适度。 
为依赖接口的类定制服务,只暴露给调用的类它须要的方法,它不须要的方法则隐藏起来。只有专一地为一个模块提供定制服务,才能创建最小的依赖关系。 
提升内聚,减小对外交互。使接口用最少的方法去完成最多的事情。 
运用接口隔离原则,必定要适度,接口设计的过大或太小都很差。设计接口的时候,只有多花些时间去思考和筹划,才能准确地实践这一原则。

6. 迪米特法则

也称为最少知识原则(LeastKnowledge Principle, LKP): 一个软件实体应当尽量少的与其余实体发生相互做用。当一个模块发生修改时,尽可能少地影响其余模块。

迪米特法则还有几种定义形式,包括:不要和“陌生人”说话、只与你的直接朋友通讯等,在迪米特法则中,对于一个对象,其朋友包括如下几类:(1) 当前对象自己(this);(2) 以参数形式传入到当前对象方法中的对象;(3) 当前对象的成员对象;(4) 若是当前对象的成员对象是一个集合,那么集合中的元素也都是朋友;(5) 当前对象所建立的对象。

相关文章
相关标签/搜索