设计模式6个基本原则学习和总结

网上这个相关内容有很多,但是大都说的太复杂了,所以这里我想用一篇来对这六个原则做以概括和总结,本文有部分内容摘自网络,由于本人水平有限,错误在所难免,如果我个人的理解有什么不对、不到位的地方,恳请各位高手指出。

1、单一职责原则(SRP:Single Responsibility Principle)

关键句:一个类只负责一个职责

看例子理解:

class Animal{(String animal){System.out.println(animal+”用肺呼吸”);} } public class Client{(String[] args){Animal animal = new Animal();animal.breathe(“牛”);animal.breathe(“羊”);animal.breathe(“猪”);} }

运行结果不必多说,但是后面我们发现这个Animal类还会包括鱼,animal.breathe(“鱼”),显然常见的鱼并不是通过肺来呼吸的,这时我们就需要修改了。这里也就发生了职责扩散,职责扩撒就是由于某种原因,职责需要细分为职责1和职责2 我们可能会这样改:

(1)修改Animal类的breathe方法:(不建议的修改方式)

(String animal){if(“鱼”.equals(animal)){System.out.println(animal+”用鳃呼吸”);}else{System.out.println(animal+”用肺呼吸”);}}

上面这种修改方式是很简单,但是存在进一步的风险,假如往后的某一天,我们知道了某些鱼还会用其他方式呼吸,这样我们又要进一步修改这个类,这时我们的修改可能就会影响到 牛 羊 等呼吸方式。这也违背了单一职责原则,所以这种方式不可取。

(2)增加Animal类新的breathe方法:(根据实际情况确定是否使用)

class Animal{(String animal){System.out.println(animal+”用肺呼吸”);}(String animal){System.out.println(animal+”用鳃呼吸”);} }

上面修改方式,在方法级别符合单一职责原则,因为它并没有动原来方法的代码。类级别是违背单一职责原则。这种方式在类中方法足够少的情况下可以考虑使用。

(3)细分Animal类:(标准的,不违反单一职责的方式)

class Terrestrial{(String animal){System.out.println(animal+”用肺呼吸”);} } class Aquatic{(String animal){System.out.println(animal+”用鳃呼吸”);} }

上面修改的方式,修改花销是很大的,除了将原来的Animal类分解之外,还需要修改客户端。即:

Terrestrial terrestrial = new Terrestrial();terrestrial.breathe(“牛”);Aquatic aquatic = new Aquatic();aquatic.breathe(“鱼”);

所以,上面(2)(3)修改方式需要综合项目的复杂程度等选择使用(如何选择使用上面已经有说到)

2、里氏替换原则(LSP:Liskov Substitution Principle)

关键句:子类可以扩展父类的功能,但不能改变父类原有的功能

这个原则主要是针对继承而言的,因为继承往往有这样的含义:父类中已经实现的方法,其实也就是针对该类部分行为的描述和定义。而若子类对这个方法进行任意修改,那么就会造成继承体系的破坏。 实际编程中,我们常常会通过重写父类的方法来完成新的功能,这样写起来虽然简单,但是整个继承体系的代码的可复用性会比较差。

如果非要重写父类的方法,比较通用的做法是:原来的父类和子类都继承一个更通俗的基类,原有的继承关系去掉,采用依赖、聚合,组合等关系代替。

3、依赖倒置原则(DIP:Dependency Inversion Principle)

关键句:细节应该依赖抽象,面向接口编程

看例子理解这个原则:

class Book{public String getContent(){return “很久很久以前有一个阿拉伯的故事……”;} } class Mother{(Book book){System.out.println(“妈妈开始讲故事”);System.out.println(book.getContent());} } public class Client{(String[] args){Mother mother = new Mother();mother.narrate(new Book());} }

上面的例子有一个Mother类,有一个Book类,Book类作为一个参数传入到Mother类中,这样,Mother类就完成了对Book类的读取。 但是这时候,要增加一个需求,Mother要读报纸,与Book类相似,Newspaper类如下:

class Newspaper{public String getContent(){return “林书豪38+7领导尼克斯击败湖人……”;} }

这时候我们就发现,Mother类的narrate方法只接受Book的对象,并不会读Newspaper,所以我们考虑如下修改方式: (1)Mother类增加narrate1方法,传入Newspaper。 绝对的坑爹设计,以后如果还有 杂志、小说要读,那是不是会有更多方法需要增加,Mother类需要不断修改。 (2)面向接口编程,引入接口IReader。

interface IReader{public String getContent(); }

Mother类与接口IReader发生依赖关系,而Book和Newspaper都属于读物的范畴,他们各自都去实现IReader接口,这样就符合依赖倒置原则了,代码修改为:

IReader {public String getContent(){return “林书豪17+9助尼克斯击败老鹰……”;} } IReader{public String getContent(){return “很久很久以前有一个阿拉伯的故事……”;} } narrate(IReader reader){System.out.println(“妈妈开始讲故事”);System.out.println(reader.getContent());} } {main(String[] args){Mother mother = new Mother();mother.narrate(new Book());mother.narrate(new Newspaper());} }

遵循依赖倒置原则可以降低类之间的耦合性,提高系统的稳定性,降低修改程序造成的风险。

4、接口隔离原则(ISP:Interface Segregation Princeple)

关键句:客户端不应该依赖它不需要的接口;一个类对另一个类的依赖应该建立在最小的接口上

旅行,有一种苍凉,“浮云游子意,落日故人情”,

设计模式6个基本原则学习和总结

相关文章:

你感兴趣的文章:

标签云: