设计模式王维雄_第1页
设计模式王维雄_第2页
设计模式王维雄_第3页
设计模式王维雄_第4页
设计模式王维雄_第5页
已阅读5页,还剩34页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、软件设计模式(软件设计模式(design patternsdesign patterns) 可复用面向对象软件的基础内部培训 王维雄等内容概括1. 设计模式介绍2. 常用设计模式分别讲(由简入深)3. 案例4. 交流为什么要学习设计模式?成为牛人! 为什么一个相似的功能,大牛一会儿就搞定,然后悠闲地品着下午茶逛淘宝;而自己加班加点搞到天亮还做不完。 为什么用户提出需求变更后,大牛只需潇洒地敲敲键盘,改改配置;而自己将代码改了又改,删了又建,几乎晕厥,最后只能推翻重来。 为什么大牛写完的程序测试上线后,几乎完美运行,用户无懈可击;而自己的程序bug重重,改好一个却又引出另一个,按下葫芦浮起瓢,几

2、近崩溃。为什么要学习设计模式?复用解决方案: 通过复用已经公认的设计,能够在解决问题时取得先发优势.避免重蹈覆辙.您是是否也有类似疑虑:几个项目下好。确定通用术语: 开发中的交流和协作都需要共同的词汇其础和对问题的共识.如果交流双方都学习过设计模式交流起来就会十分的舒服.不知道你有没有想表达又表达不清楚的设计 思路,或者自己表达得明白但对方又误解了你的意思了呢?看了设计模式你也许可以找到你想要的答案。改善团队的沟通和个人学习。一个团队一起学习设计模式,有助于团队战斗力的提高。代码更易于修改与维护。 因为设计模式都是久经考验的解决方案,它们的结构都是经过长期的发展形成的,善于应对变化。模式有助于

3、提高思考层次。学习模式后,就算不用模式中的方法,也会更好的采取更好的策略去解决问题。1.1 设计模式介绍 - 什么是设计模式?设计模式(design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。1970年建筑设计大师亚力山大。软件设计模式这个术语是在1990年代由erich gamma等4人引入,用来解决同一问题的不同表相。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。 毫无疑问,设计模式于己于他人于系统都是多赢的,设计模式使代码编制真正工程化,设计模式是软件工程的基石,如同大厦的一块块砖石一样。项目中合理的运用设计模式可以完美的

4、解决很多问题,每种模式在现在中都有相应的原理来与之对应,每一个模式描述了一个在我们周围不断重复发生的问题,以及该问题的核心解决方案,这也是它能被广泛应用的原因。1.2 设计模式介绍 - 23种设计模式创建型创建对象时,不再由我们直接实例化对象;而是根据特定场景,由程序来确定创建对象的方式,从而保证更大的性能、更好的架构优势。创建型模式主要有简单工厂模式(并不是23种设计模式之一)、工厂方法、抽象工厂模式、单例模式、生成器模式、原型模式。结构型用于帮助将多个对象组织成更大的结构。结构型模式主要有适配器模式、桥接模式、组合器模式、装饰器模式、门面模式、亨元模式和代理模式。行为型用于帮助系统间各对象

5、的通信,以及如何控制复杂系统中流程。行为型模式主要有命令模式、解释器模式、迭代器模式、中介者模式、备忘录模式、观察者模式、状态模式、策略模式、模板模式和访问者模式。1.3 设计模式的六大原则1、单一职责定义:不要存在多于一个导致类变更的原因。通俗的说,即一个类只负责一项职责。 问题由来:类t负责两个不同的职责:职责p1,职责p2。当由于职责p1需求发生改变而需要修改类t时,有可能会导致原本运行正常的职责p2功能发生故障。解决方案:遵循单一职责原则。分别建立两个类t1、t2,使t1完成职责p1功能,t2完成职责p2功能。这样,当修改类t1时,不会使职责p2发生故障风险;同理,当修改t2时,也不会

6、使职责p1发生故障风险。遵循单一职责原的优点有:可以降低类的复杂度,一个类只负责一项职责,其逻辑肯定要比负责多项职责简单的多;提高类的可读性,提高系统的可维护性;变更引起的风险降低,变更是必然的,如果单一职责原则遵守的好,当修改一个功能时,可以显著降低对其他功能的影响。1.3 设计模式的六大原则2、里氏代换原则(liskov substitution principle)子类可以扩展父类的功能,但不能改变父类原有的功能定义1:如果对每一个类型为 t1的对象 o1,都有类型为 t2 的对象o2,使得以 t1定义的所有程序 p 在所有的对象 o1 都代换成 o2 时,程序 p 的行为没有发生变化,

7、那么类型 t2 是类型 t1 的子类型。定义2:所有引用基类的地方必须能透明地使用其子类的对象。问题由来:有一功能p1,由类a完成。现需要将功能p1进行扩展,扩展后的功能为p,其中p由原有功能p1与新功能p2组成。新功能p由类a的子类b来完成,则子类b在完成新功能p2的同时,有可能会导致原有功能p1发生故障。解决方案:当使用继承时,遵循里氏替换原则。类b继承类a时,除添加新的方法完成新增功能p2外,尽量不要重写父类a的方法,也尽量不要重载父类a的方法。1.3 设计模式的六大原则3、依赖倒置原则定义:高层模块不应该依赖低层模块,二者都应该依赖其抽象;抽象不应该依赖细节;细节应该依赖抽象。 问题由

8、来:类a直接依赖类b,假如要将类a改为依赖类c,则必须通过修改类a的代码来达成。这种场景下,类a一般是高层模块,负责复杂的业务逻辑;类b和类c是低层模块,负责基本的原子操作;假如修改类a,会给程序带来不必要的风险。解决方案:将类a修改为依赖接口i,类b和类c各自实现接口i,类a通过接口i间接与类b或者类c发生联系,则会大大降低修改类a的几率。实际需要做到如下3点:低层模块尽量都要有抽象类或接口,或者两者都有。变量的声明类型尽量是抽象类或接口。使用继承时遵循里氏替换原则。1.3 设计模式的六大原则4、接口隔离原则定义:客户端不应该依赖它不需要的接口;一个类对另一个类的依赖应该建立在最小的接口上。

9、 问题由来:类a通过接口i依赖类b,类c通过接口i依赖类d,如果接口i对于类a和类b来说不是最小接口,则类b和类d必须去实现他们不需要的方法。解决方案:将臃肿的接口i拆分为独立的几个接口,类a和类c分别与他们需要的接口建立依赖关系。也就是采用接口隔离原则。接口设计原则:接口尽量小,但是要有限度。对接口进行细化可以提高程序设计灵活性是不挣的事实,但是如果过小,则会造成接口数量过多,使设计复杂化。所以一定要适度。为依赖接口的类定制服务,只暴露给调用的类它需要的方法,它不需要的方法则隐藏起来。只有专注地为一个模块提供定制服务,才能建立最小的依赖关系。提高内聚,减少对外交互。使接口用最少的方法去完成最

10、多的事情。1.3 设计模式的六大原则5、迪米特法则(最少知道原则)定义:一个对象应该对其他对象保持最少的了解。 问题由来:类与类之间的关系越密切,耦合度越大,当一个类发生改变时,对另一个类的影响也越大。解决方案:尽量降低类与类之间的耦合。设计原则:只与直接的朋友通信,不要和陌生人说话。过分的使用该原则,将导致系统复杂度变大。所以在采用迪米特法则时要反复权衡,既做到结构清晰,又要高内聚低耦合。1.3 设计模式的六大原则6、开闭原则定义:一个软件实体如类、模块和函数应该对扩展开放,对修改关闭。 问题由来:在软件的生命周期内,因为变化、升级和维护等原因需要对软件原有代码进行修改时,可能会给旧代码中引

11、入错误,也可能会使我们不得不对整个功能进行重构,并且需要原有代码经过重新测试。解决方案:当软件需要变化时,尽量通过扩展软件实体的行为来实现变化,而不是通过修改已有的代码来实现变化。1.4 设计模式的六大原则总结 用抽象构建框架,用实现扩展细节 抽象合理(需求变更前瞻性和预见性),派生实现类 单一职责原则告诉我们实现类要职责单一; 里氏替换原则告诉我们不要破坏继承体系; 依赖倒置原则告诉我们要面向接口编程; 接口隔离原则告诉我们在设计接口的时候要精简单一; 迪米特法则告诉我们要降低耦合。 而开闭原则是总纲,他告诉我们要对扩展开放,对修改关闭。1.4设计模式如何学习?大话设计模式 通俗易懂,笔法幽

12、默诙谐深入浅出设计模式软件秘笈:设计模式那点事第一节课 3种工厂模式简单/静态工厂模式工厂方法模式抽象工厂模式 工厂模式主要是为创建对象提供过渡接口,以便将创建对象的具体过程屏蔽隔离起来,达到提高灵活性的目的。这三种模式从上到下逐步抽象,并且更具一般性。gof 在设计模式一书中将工厂模式分为两类:工厂方法模式(factory method )与抽象工厂模式(abstract factory)。将简单工厂模式(simple factory)看为工厂方法模式的一种特例,两者归为一类,简单工厂模式更像一种编程习惯,有必要讲讲。 3.1简单工厂模式 代码无错就是优?案例:计算器3.1简单工厂模式 规范

13、后3.1简单工厂模式 活字印刷-面向对象 易维护、扩展、灵活 易复用(不是复制) 封装3.1简单工厂模式 松耦合,继承3.1简单工厂模式 创造实例、结构图3.1简单工厂模式/生产产品的工厂类 public class productfactory public static product generateproduct(int which) /这个方法是static的 if (which=1) return new producta(); else if (which=2) return new productb(); /调用工厂方法 public client public method1

14、() productfactory.generateproduct(1); /抽象产品 public interface product . /具体产品a public producta implement product producta () /具体产品b public productb implement product productb () 3.1简单工厂模式总结 不能满足实现功能,应时常考虑简练、易维护、扩展、复用。 简单工场实现了对责任的分割。 优势:让对象的调用者和对象创建过程分离,当对象调用者需要对象时,直接向工厂请求即可。从而避免了对象的调用者与对象的实现类以硬编码方式耦合

15、,以提高系统的可维护性、可扩展性。 缺陷:当产品修改时,工厂类也要做相应的修改,比如要增加一种操作类,如求m数的n次方,就得改case,修改原有类,违背了开放-封闭原则。3.2 工厂方法模式 解决简单工厂模式的扩展问题3.2 工厂方法模式 factory method请mm去麦当劳吃汉堡,不同的mm有不同的口味,要每个都记住是一件烦人的事情,我一般采用factory method模式,带着mm到服务员那儿,说“要一个汉堡”,具体要什么样的汉堡呢,让mm直接跟服务员说就行了。 工厂方法模式:核心工厂类不再负责所有产品的创建,而是将具体创建的工作交给子类去做,成为一个抽象工厂角色,仅负责给出具体工

16、厂类必须实现的接口,而不接触哪一个产品类应当被实例化这种细节。 3.2 工厂方法模式(4个角色)/抽象产品:产品 plant接口 public interface plant /具体产品:planta,plantb public class planta implements plant public planta () system.out.println(create planta !); public void dosomething() system.out.println( planta do something .); public class plantb implements

17、plant public plantb () system.out.println(create plantb !); public void dosomething() system.out.println( plantb do something .); / 抽象工厂(工厂方法的核心):(工厂方法的核心): public interface abstractfactory public plant createplant(); /具体工厂: public class factorya implements abstractfactory public plant createplant()

18、 return new planta(); public class factoryb implements abstractfactory public plant createplant() return new plantb(); /客户端客户端调用工厂方法 public client public method1() abstractfactory instancea = new factorya(); instancea.createplant(); abstractfactory instanceb = new factoryb(); instanceb.createplant()

19、; 3.2工厂方法模式总结 优势:克服了简单工厂模式违背开放-封闭的原则,保持了封装对象创建过程的优点。 缺陷:当增加产品时,就得增加一个产品工厂的类,增加额外的开发量。避免不了分支判断的问题。 办法:反射3.2 工厂方法模式和简单工厂模式比较1. 结构复杂度从这个角度比较,显然简单工厂模式要占优。简单工厂模式只需一个工厂类,而工厂方法模式的工厂类随着产品类个数增加而增加,这无疑会使类的个数越来越多,从而增加了结构的复杂程度。2.代码复杂度代码复杂度和结构复杂度是一对矛盾,既然简单工厂模式在结构方面相对简洁,那么它在代码方面肯定是比工厂方法模式复杂的了。简单工厂模式的工厂类随着产品类的增加需要

20、增加很多方法(或代码),而工厂方法模式每个具体工厂类只完成单一任务,代码简洁。3.客户端编程难度工厂方法模式虽然在工厂类结构中引入了接口从而满足了ocp,但是在客户端编码中需要对工厂类进行实例化。而简单工厂模式的工厂类是个静态类,在客户端无需实例化,这无疑是个吸引人的优点。4.管理上的难度扩展。工厂方法模式完全满足ocp,即它有非常良好的扩展性。那是否就说明了简单工厂模式就没有扩展性呢?答案是否定的。简单工厂模式同样具备良好的扩展性扩展的时候仅需要修改少量的代码(修改工厂类的代码)就可以满足扩展性的要求了。尽管这没有完全满足ocp,但我们认为不需要太拘泥于设计理论。维护。假如某个具体产品类需要

21、进行一定的修改,很可能需要修改对应的工厂类。当同时需要修改多个产品类的时候,对工厂类的修改会变得相当麻烦(对号入座已经是个问题了)。反而简单工厂没有这些麻烦,当多个产品类需要修改是,简单工厂模式仍然仅仅需要修改唯一的工厂类(无论怎样都能改到满足要求吧?大不了把这个类重写)。3.2 改良方法:简单工厂+反射添加类productc并实现iproduct接口,这是使用任何模式都无法避免的改变。在配置文件中多添加一条关于productc的配置信息。3.3 抽象工厂模式概念:供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。 案例:abstract factory 追mm少不了请吃饭了,

22、麦当劳的套餐和肯德基的套餐都是mm爱吃的东西,虽然口味有所不同,但不管你带mm去麦当劳或肯德基,只管向服务员说“两个b套餐”就行了。麦当劳和肯德基就是b套餐的abstract factory, b套餐里含有汉堡, 鸡翅和饮料. 麦当劳或肯德基会根据b套餐的规格, 让汉堡factory, 鸡翅factory, 饮料factory分别生产对应b套餐的材料.抽象工厂模式:客户类和工厂类分开。消费者任何时候需要某套产品集合时,只需向抽象工厂请求即可。抽象工厂会再向具体的工厂生产出符合产品集规格的产品.3.3 抽象工厂模式3.3 抽象工厂模式3.3 抽象工厂模式/ 抽象产品蔬菜: vegetable接口

23、 public interface vegetable /具体产品vegetablea,vegetablebpublic class vegetablea implements vegetable public vegetablea () public class vegetableb implements vegetable / 抽象产品水果: fruit接口 public interface fruit /具体产品fruita,fruitb public class fruita implements fruit public class fruitb implements fruit /

24、 /抽象工厂方法抽象工厂方法 public interface abstractfactory public plant createplant(); public fruit createfruit(); /具体工厂方法具体工厂方法 public class factorya implements abstractfactory public plant createvegetable() return new vegetablea(); public fruit createfruit() return new fruita(); public class factoryb impleme

25、nts abstractfactory public plant createvegetable() return new vegetableb(); public fruit createfruit() return new vegetableb(); 3.3 抽象工厂模式 优缺点 支持多种观感标准的用户界面工具箱。游戏开发中的多风格系列场景,比如道路,房屋,管道等。系统要在三个不同平台上运行,比如windows、linux、android上运行,你会怎么设计?分别设计三套不同的应用?通过抽象工厂模式屏蔽掉操作系统对应用的影响。三个不同操作系统上的软件功能、应用逻辑、ui都应该是非常类似,唯

26、一不同的是调用不同的工厂方法,由不同的产品类去处理与操作系统交互的信息 需要创建的对象是一系列相互关联或相互依赖的产品族时,便可以使用抽象工厂模式。假如各个等级结构中的实现类之间不存在关联或约束,则使用多个独立的工厂来对产品进行创建,则更合适一点。3.3 抽象工厂模式 适用场景 支持多种观感标准的用户界面工具箱。游戏开发中的多风格系列场景,比如道路,房屋,管道等。系统要在三个不同平台上运行,比如windows、linux、android上运行,你会怎么设计?分别设计三套不同的应用?通过抽象工厂模式屏蔽掉操作系统对应用的影响。三个不同操作系统上的软件功能、应用逻辑、ui都应该是非常类似,唯一不同的是调用不同的工厂方法,由不同的产品类去处理与操作系统交

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论