03设计模式六大原则PPT课件
- 格式:ppt
- 大小:1.23 MB
- 文档页数:43
设计模式六⼤设计原则设计模式到底是什么?它是对整个软件系统的拆分,组装,并决定模块间关系以及如何互动、通信的某种模式。
究其本质,设计模式就是以语⾔特性(⾯向对象三⼤特性)为硬件基础,再加持六⼤设计原则的灵魂组合⽽,总结出的⼀系列套路,本章要讲地就是灵魂。
单⼀职责 我们知道功能完备的软件系统是复杂的,系统的拆分与模块化是不可或缺的,⽽⾯向对象是以类来划分模块边界的,也就是说每个类都代表着⼀个功能⾓⾊模块,其职责应该是单⼀的,不是⾃⼰分内的事不应该负责,这就是单⼀职责原则。
举个例⼦,灯泡⼀定是可以亮和灭的,我们定义⼀个灯泡类并且包含“功率属性”以及“通电”和“断电”两个功能⽅法,这便是对灯泡的封装,⼀对⼤括号“{}”定义了其类模块的边界。
虽然说我的领域我做主,但绝不可肆意妄为。
⽐如现在客户要求这个灯泡可以闪烁的霓虹灯效果,我们该怎样实现?直接在电灯类⾥再封装⼀堆逻辑电路控制其闪烁,⽐如新加⼀个flash()⽅法,并不停来回调⽤通电断电?这显然是错误的,灯泡就是灯泡,它只能亮和灭,能不能闪烁不是灯泡的职责,既然进⾏分类,就不要不伦不类。
所以我们需要把闪烁控制电路独⽴出来,它们之间的通信应该通过接⼝去调⽤,划清界限,各司其职,这才是类封装的意义。
单⼀职责原则规定,对任何类的修改只能有⼀个原因,这是由罗伯特·C·马丁(Robert C. Martin)提出的,这是什么意思呢?例如我们的灯泡类,它的职责就是照明,与其⽆关的⼀切修改动机都不予考虑。
所以说灯泡绝不能封装与其本⾝职责不相⼲的功能,这样就保证其职责的单⼀性原则,类与类之间有明确的职责划分,同时也保持⼀种协作的关系,分与合,对⽴与统⼀的辩证关系。
最典型的例⼦例如我们之前讲过的”责任链模式“中环环相扣审批⼈的职责范围就是很好的例⼦,各顾各的、不管闲事,职责的单⼀性保证了类的⾼内聚、低耦合,如此便提⾼了代码的易读性、易维护性、易测试性、易复⽤性等等。
一、开闭原则开闭原则(Open Closed Principle)是Java世界里最基础的设计原则,它指导我们如何建立一个稳定的、灵活的系统。
定义:一个软件实体如类、模块和函数应该对扩展开放,对修改关闭。
Softeware entities like classes,modules and functions should be open for extension but closed for modifications.开闭原则的含义是说一个软件实体应该通过扩展来实现变化,而不是通过修改已有代码来实现变化。
软件实体包括以下几个部分:∙项目或软件产品中按照一定的逻辑规则划分的模块∙抽象和类∙方法开闭原则是为软件实体的未来事物而制定的对现行开发设计进行约束的一个原则。
注意:开闭原则对扩展开放,对修改关闭,并不意味着不做任何修改,低层模块的变更,必然要有高层模块进行耦合,否则就是一个孤立无意义的代码片段了。
变化的类型:∙逻辑变化∙子模块变化∙可见试图变化一个项目的基本路径应该是这样的:项目开发、重构、测试、投产、运维,其中的重构可以对原有的设计和代码进行修改,运维尽量减少对原有代码修改,保持历史代码的纯洁性,提高系统的稳定性。
开闭原则的重要性:∙开闭原则对测试的影响开闭原则可是保持原有的测试代码仍然能够正常运行,我们只需要对扩展的代码进行测试就可以了。
∙开闭原则可以提高复用性在面向对象的设计中,所有的逻辑都是从原子逻辑组合而来的,而不是在一个类中独立实现一个业务逻辑。
只有这样代码才可以复用,粒度越小,被复用的可能性就越大。
∙开闭原则可以提高可维护性∙面向对象开发的要求如何使用开闭原则:∙抽象约束第一,通过接口或者抽象类约束扩展,对扩展进行边界限定,不允许出现在接口或抽象类中不存在的publ ic方法;第二,参数类型、引用对象尽量使用接口或者抽象类,而不是实现类;第三,抽象层尽量保持稳定,一旦确定即不允许修改。
一、设计模式的六大原则1、开闭原则(Open Close Principle)开闭原则就是说对扩展开放,对修改关闭。
在程序需要进行拓展的时候,不能去修改原有的代码,实现一个热插拔的效果。
所以一句话概括就是:为了使程序的扩展性好,易于维护和升级。
想要达到这样的效果,我们需要使用接口和抽象类。
开闭原则是面向对象的可复用设计的第一块基石。
开闭原则的关键是抽象化。
2、里氏代换原则(Liskov Substitution Principle)里氏代换原则(Liskov Substitution Principle LSP)面向对象设计的基本原则之一。
里氏代换原则中说,任何基类可以出现的地方,子类一定可以出现。
LSP是继承复用的基石,只有当衍生类可以替换掉基类,软件单位的功能不受到影响时,基类才能真正被复用,而衍生类也能够在基类的基础上增加新的行为。
里氏代换原则是对“开-闭”原则的补充。
实现“开-闭”原则的关键步骤就是抽象化。
而基类与子类的继承关系就是抽象化的具体实现,所以里氏代换原则是对实现抽象化的具体步骤的规范。
面向对象的设计关注的是对象的行为,它是使用“行为”来对对象进行分类的,只有行为一致的对象才能抽象出一个类来。
我经常说类的继承关系就是一种“Is-A”关系,实际上指的是行为上的“Is-A”关系,可以把它描述为“Act-As”。
3、依赖倒转原则(Dependence Inversion Principle)这个是开闭原则的基础,具体内容:真对接口编程,依赖于抽象而不依赖于具体。
4、接口隔离原则(Interface Segregation Principle)这个原则的意思是:使用多个隔离的接口,比使用单个接口要好。
还是一个降低类之间的耦合度的意思,从这儿我们看出,其实设计模式就是一个软件的设计思想,从大型软件架构出发,为了升级和维护方便。
所以上文中多次出现:降低依赖,降低耦合。
5、迪米特法则(最少知道原则)(Demeter Principle)最少知道原则,就是说:一个实体应当尽量少的与其他实体之间发生相互作用,使得系统功能模块相对独立。
设计模式六⼤规则1.单⼀职责原则(六⼤规则中的⼩萝莉,⼈见⼈爱):描述的意思是每个类都只负责单⼀的功能,切不可太多,并且⼀个类应当尽量的把⼀个功能做到极致。
2.⾥⽒替换原则(六⼤原则中最⽂静的姑娘,但却不太招⼈喜欢):这个原则表达的意思是⼀个⼦类应该可以替换掉⽗类并且可以正常⼯作。
3. 接⼝隔离原则(六⼤原则当中最挑三拣四的挑剔⼥,胸部极⼩):也称接⼝最⼩化原则,强调的是⼀个接⼝拥有的⾏为应该尽可能的⼩。
4.依赖倒置原则(六⼤原则中最⼩鸟依⼈的姑娘,对抽象的东西⾮常依赖):这个原则描述的是⾼层模块不该依赖于低层模块,⼆者都应该依赖于抽象,抽象不应该依赖于细节,细节应该依赖于抽象。
5.迪⽶特原则(六⼤原则中最害羞的姑娘,不太爱和陌⽣⼈说话):也称最⼩知道原则,即⼀个类应该尽量不要知道其他类太多的东西,不要和陌⽣的类有太多接触。
6.开-闭原则(六⼤原则中绝对的⼤姐⼤,另外五姐妹⼼⽢情愿⾂服):最后⼀个原则,⼀句话,对修改关闭,对扩展开放。
《简介》说到设计模式,当初第⼀次听到时,第⼀反应就是很深奥,完全理解不了这个概念到底是什么意思,下⾯我先从⽹上摘录⼀份定义。
设计模式(Designpattern)是⼀套被反复使⽤、多数⼈知晓的、经过分类编⽬的、代码设计经验的总结。
上⾯是百度当中的解释,来解释⼀下这句简单的话的含义,⼏个关键词。
反复使⽤:这个不⽤过多解释,设计模式被使⽤太多了,上个系列spring源码当中就出现了很多模式,记忆中⽐较深刻的有模板模式,代理模式,单例模式,⼯⼚模式等等。
多数⼈知晓:这个就不需要过多解释了。
分类编⽬:就是说可以找到⼀些特征去划分这些设计模式,从⽽进⾏分类。
代码设计经验:这句很重要,设计经验的总结,也就是说设计模式,是为了指导设计⽽从经验中总结出来的套路。
还有⼀种说法是说,设计模式是可以解决特定场景的问题的⼀系列⽅法,其实我觉得这个解释更贴切⼀点。
《为何学习设计模式》上⾯简单的介绍,是让各位⾸先搞清楚设计模式是什么,下⾯我们来说说为什么要学习设计模式,学习总要有个驱动⼒。
设计模式---六⼤原则背景:听说设计模式是进⼊BAT的必经之路。
First、何谓设计模式:设计模式(Design Pattern)是⼀套被反复使⽤、多数⼈知晓的、经过分类的、代码设计经验的总结。
设计模式的好处&学习⽬的:1、为了代码可重⽤⾏、让代码更易被他⼈理解、保证代码的可靠性、使代码编写真正实现⼯程化;2、设计模式便于我们维护项⽬,增强系统的健壮性和可扩展性;3、设计模式还可以锻炼码农的设计思维、升华代码质量等。
六⼤指导原则:程序设计模式有六⼤基本指导原则,但规则毕竟都是⼈定的,So我们要灵活遵守、灵活运⽤这六⼤原则。
⼀、开-闭原则:1、开闭原则顾名思义就是对修改关闭,对扩展开放;2、开闭原则是六⼤原则的核⼼,即我们之后做的任何改变都不需要修改原有的代码,只需要加⼊⼀些新的实现即可达到⽬的;3、开闭原则也是任何⼀个系统设计期望达到的理想境界。
⼆、单⼀职责原则:单⼀职责即每个类都只负责单⼀的功能,莫要太贪⼼,除此之外尽量把⼀个类的功能完善到极致,可以⽤final来修饰的程度。
下⾯就有⼀个例⼦类Scientific 从⼀个⽂件中读取两个数,并返回两者之和,如此设计可以很明显的看到它们之间的职责问题存在太多耦合了。
如图:上图中显⽰的Scientific 类并没有错,但是我们要是读取⽂件的地址改变了呢?要是结果改为两者之差、两者之积或两者之商或者是两者之模呢?然后,我们需要复制许多份相同的代码,想想这种设计就不合理;这时我们就要考虑下“单⼀职责原则”,分离出⼀个类ReadFile 来读取数据,再分离出⼀个类DesignScientific 对读取到的数据进⾏处理(加减乘除等)。
1import java.io.BufferedReader;2import java.io.FileReader;3public class ReadFile {45private int numOne;6private int numTwo;78public ReadFile(String path) throws Exception {9 BufferedReader br = new BufferedReader(new FileReader(path));10 numOne = Integer.valueOf(br.readLine());11 numTwo = Integer.valueOf(br.readLine());12 System.out.println("numOne is: "+numOne+" && "+"numTwo is: "+numTwo);13 }1415public int getNumOne() {16return numOne;17 }1819public int getnumTwo() {20return numTwo;21 }22 }如此,将⼀个类拆为两个,既不会有那么多重复的代码,也多了跟多结果的选择性,也恰恰体现了单⼀职责原则是我们设计模式最应该遵守的原则之⼀。
设计模式值六⼤原则——接⼝隔离原则(ISP)
接⼝隔离原则 Interface Segregation Principle
定义:
客户端不应该依赖它不需要的接⼝
类间的依赖关系应该建⽴在最⼩的接⼝上
我们可以把这两个定义概括为⼀句话:建⽴单⼀接⼝,不要建⽴臃肿庞⼤的接⼝。
再通俗⼀点讲:接⼝尽量细化,同时接⼝中的⽅法尽量少。
提供给每个模块的都应该是单⼀接⼝,提供给⼏个模块就应该有⼏个接⼝,⽽不是建⽴⼀个庞⼤的臃肿的接⼝,容纳所有的客户端访问。
接⼝是我们设计时对外提供的契约,通过分散定义多个接⼝,可以预防未来变更的扩散,提⾼系统的灵活性和可维护性。
含义:
接⼝要尽量⼩
这是接⼝隔离原则的核⼼定义,不出现臃肿的接⼝(Fat Interface),但是“⼩”是有限度的,⾸先就是不能违反单⼀职责原则。
根据接⼝隔离原则拆分接⼝时,⾸先必须满⾜单⼀职责原则。
接⼝要⾼内聚
⾼内聚就是要提⾼接⼝、类、模块的处理能⼒,减少对外的交互。
具体到接⼝隔离原则就是,要求在接⼝中尽量少公布public⽅法,接⼝是对外的承诺,承诺地越少对系统开发越有利,变更的风险也就越少,同时也有利于降低成本。
定制服务
定制服务就是单独为⼀个个体提供优良的服务。
接⼝设计是有限度的
接⼝的设计粒度越⼩,系统越灵活,这是不争的事实。
但是,灵活的同时也带来了结构的复杂化,开发难度增加,可维护性降低,这不是⼀个项⽬或产品所期望看到的,所以接⼝设计⼀定要注意适度,这个度只能根据经验和常识判断,没有⼀个固化或可测量的标准。
六大设计原则和23种设计模式
设计原则是设计模式的基础,六大设计原则是SOLID原则和DRY原则。
SOLID是单一职责原则(Single Responsibility Principle,SRP)、开闭原则(Open Closed Principle,OCP)、里氏替换原则(Liskov Substitution Principle,LSP)、接口隔离原则(Interface Segregation Principle,ISP)和依赖反转原则(Dependency Inversion Principle,DIP)。
DRY原则是不要重复自己(Don't Repeat Yourself)。
设计模式是软件设计中常用的解决问题的模式,常见的23种设计模式包括:
1. 创建型模式,工厂方法模式、抽象工厂模式、建造者模式、原型模式、单例模式。
2. 结构型模式,适配器模式、桥接模式、组合模式、装饰者模式、外观模式、享元模式、代理模式。
3. 行为型模式,责任链模式、命令模式、解释器模式、迭代器模式、中介者模式、备忘录模式、观察者模式、状态模式、策略模
式、模板方法模式、访问者模式。
这些设计原则和设计模式在软件开发中起着重要的作用。
设计原则有助于编写具有良好结构和可维护性的代码,而设计模式则提供了解决特定问题的经过验证的解决方案。
通过遵循这些原则和模式,开发人员可以编写出高质量、可扩展和易于维护的软件系统。
同时,这些原则和模式也有助于促进团队之间的沟通和协作,使得软件开发过程更加高效和可靠。
设计模式之设计六大原则1. 单一职责原则(SRP)定义:就一个类而言,应该仅有一个引起它变化的原因。
从这句定义我们很难理解它的含义,通俗讲就是我们不要让一个类承担过多的职责。
如果一个类承担的职责过多,就等于把这些职责耦合在一起,一个职责的变化可能会削弱或者抑制这个类完成其他职责的能力。
这种耦合会导致脆弱的设计,当变化发生时,设计会遭受到破坏。
比如我经常看到一些Android开发在Activity中写Bean文件,网络数据处理,如果有列表的话Adapter 也写在Activity中,问他们为什么除了好找也没啥理由了,把他们拆分到其他类岂不是更好找,如果Activity过于臃肿行数过多,显然不是好事,如果我们要修改Bean文件,网络处理和Adapter都需要上这个Activity来修改,就会导致引起这个Activity变化的原因太多,我们在版本维护时也会比较头疼。
也就严重违背了定义“就一个类而言,应该仅有一个引起它变化的原因”。
当然如果想争论的话,这个模式是可以引起很多争论的,但请记住一点,你写代码不只是为了你也是为了其他人。
2. 开放封闭原则(ASD)定义:类、模块、函数等等等应该是可以拓展的,但是不可修改。
开放封闭有两个含义,一个是对于拓展是开放的,另一个是对于修改是封闭的。
对于开发来说需求肯定是要变化的,但是新需求一来,我们就要把类重新改一遍这显然是令人头疼的,所以我们设计程序时面对需求的改变要尽可能的保证相对的稳定,尽量用新代码实现拓展来修改需求,而不是通过修改原有的代码来实现。
假设我们要实现一个列表,一开始只有查询的功能,如果产品又要增加添加功能,过几天又要增加删除功能,大多数人的做法是写个方法然后通过传入不同的值来控制方法来实现不同的功能,但是如果又要新增功能我们还得修改我们的方法。
用开发封闭原则解决就是增加一个抽象的功能类,让增加和删除和查询的作为这个抽象功能类的子类,这样如果我们再添加功能,你会发现我们不需要修改原有的类,只需要添加一个功能类的子类实现功能类的方法就可以了。
六⼤设计原则六⼤设计原则1. 单⼀职责原则:对于⼀个类,应该只有⼀个引起它变化的原因;【功能内聚】2. ⾥⽒代换原则:⼦类必须能够替换掉它们的⽗类型;【减⼩继承耦合】3. 开放-封闭原则:对于扩展是开放的;对于修改是封闭的。
4. 依赖倒置原则:程序的⾼层模块不应该依赖于底层模块,两者应依赖于抽象;抽象不应该依赖于具体斜街,⽽细节应该依赖于抽象。
【⾯向接⼝编程,⽽不是针对实现编程】【耦合具有⽅向性差异,稳定与变化之间的耦合,接⼝稳定⽽具体易变化】5. 合成/聚合复⽤原则:尽量不使⽤类继承,⽽尽量使⽤合成/聚合【避免类爆炸】6. 迪⽶特法则:如果两个类之间不必直接通信,则这个类不应该发⽣直接相互作⽤。
如果其中⼀个类需要调⽤另⼀个类的某个⽅法,可以通过第三⽅转发这个调⽤。
【体现在顺序图中,跨“朋友/友元”调⽤“陌⽣”对象,进⾏改进】⼀、单⼀职责原则举例:超⼈只维护世界原因:易于维护和⾼度的可复⽤性是⾯向对象开发的⽐较突出的两个优点。
若职责过于庞⼤,则维护困难,可复⽤性也随之降低,与⾯向对象的思想背道⽽驰。
好处:降低类的复杂度,⼀个类只负责⼀项职责,其逻辑肯定⽐负责多项职责简单;提⾼类的可读性,提⾼系统的可维护性。
⼆、⾥⽒代换原则举例:超⼈只维护世界符合:鲨鱼是鱼,⽼⽊匠徒弟替⽼⽊匠打家具;违反:正⽅形是长⽅形【如何修改,构造⼀个抽象的四边形类】作⽤:使得使⽤⽗类类型的模块在⽆需修改的情况下,就可以通过使⽤不同的⼦类拓展。
⾥⽒代换规则是对实现抽象化的具体步骤的规范。
【⾥⽒代换原则是对开闭原则的进⼀步规范】三、开放-封闭原则(OCP)----⾯向对象设计的主要⽬标原因:封装变化、降低耦合效果:开闭原则提供了⼀个使系统在⾯对需求变更时,可以保持系统相对稳定的解决⽅案。
举例:符合:动物-猫-咪咪(继承/多态复⽤,并拓展)对⽐:1. 银⾏业务员(存款、取款、转账、进⾏基⾦申购)2. 银⾏业务员接⼝,存款业务员、取款业务员、负责转账业务员、基⾦业务员//其实这⾥的改写也体现了单⼀职责原则,依赖于抽象的银⾏业务员接⼝利于扩展核⼼思想:只依赖于抽象,⾯向抽象编程,⽽不是⾯向具体编程。