设计模式王维雄.ppt

上传人:rrsccc 文档编号:8871875 上传时间:2021-01-21 格式:PPT 页数:39 大小:494.50KB
返回 下载 相关 举报
设计模式王维雄.ppt_第1页
第1页 / 共39页
设计模式王维雄.ppt_第2页
第2页 / 共39页
设计模式王维雄.ppt_第3页
第3页 / 共39页
设计模式王维雄.ppt_第4页
第4页 / 共39页
设计模式王维雄.ppt_第5页
第5页 / 共39页
点击查看更多>>
资源描述

《设计模式王维雄.ppt》由会员分享,可在线阅读,更多相关《设计模式王维雄.ppt(39页珍藏版)》请在三一文库上搜索。

1、软件设计模式(Design Patterns),可复用面向对象软件的基础,内部培训,王维雄等,内容概括,1. 设计模式介绍,为什么要学习设计模式?,成为牛人! 为什么一个相似的功能,大牛一会儿就搞定,然后悠闲地品着下午茶逛淘宝;而自己加班加点搞到天亮还做不完。 为什么用户提出需求变更后,大牛只需潇洒地敲敲键盘,改改配置;而自己将代码改了又改,删了又建,几乎晕厥,最后只能推翻重来。 为什么大牛写完的程序测试上线后,几乎完美运行,用户无懈可击;而自己的程序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时,也不会使职责P1发生故障风险。 遵循单一职责原的优

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

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

8、赖类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简

13、单工厂模式 代码无错就是优?,案例:计算器,3.1简单工厂模式,规范后,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(

14、); /调用工厂方法 public Client public method1() 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 s

17、omething .); public class PlantB implements 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 Abstrac

18、tFactory public Plant createPlant() 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 Fac

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

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

21、这没有完全满足OCP,但我们认为不需要太拘泥于设计理论。 维护。假如某个具体产品类需要进行一定的修改,很可能需要修改对应的工厂类。当同时需要修改多个产品类的时候,对工厂类的修改会变得相当麻烦(对号入座已经是个问题了)。反而简单工厂没有这些麻烦,当多个产品类需要修改是,简单工厂模式仍然仅仅需要修改唯一的工厂类(无论怎样都能改到满足要求吧?大不了把这个类重写)。,3.2 改良方法:简单工厂+反射,添加类ProductC并实现IProduct接口,这是使用任何模式都无法避免的改变。 在配置文件中多添加一条关于ProductC的配置信息。,3.3 抽象工厂模式,概念:供一个创建一系列相关或相互依赖对象

22、的接口,而无需指定它们具体的类。 案例:ABSTRACT FACTORY 追MM少不了请吃饭了,麦当劳的套餐和肯德基的套餐都是MM爱吃的东西,虽然口味有所不同,但不管你带MM去麦当劳或肯德基,只管向服务员说“两个B套餐”就行了。麦当劳和肯德基就是B套餐的Abstract Factory, B套餐里含有汉堡, 鸡翅和饮料. 麦当劳或肯德基会根据B套餐的规格, 让汉堡Factory, 鸡翅Factory, 饮料Factory分别生产对应B套餐的材料. 抽象工厂模式:客户类和工厂类分开。消费者任何时候需要某套产品集合时,只需向抽象工厂请求即可。抽象工厂会再向具体的工厂生产出符合产品集规格的产品.,3

23、.3 抽象工厂模式,3.3 抽象工厂模式,3.3 抽象工厂模式,/ 抽象产品蔬菜: Vegetable接口 public interface Vegetable /具体产品VegetableA,VegetableB public class VegetableA implements Vegetable public VegetableA () public class VegetableB implements Vegetable / 抽象产品水果: Fruit接口 public interface Fruit /具体产品FruitA,FruitB public class FruitA i

24、mplements Fruit public class FruitB implements Fruit /,/ /抽象工厂方法 public interface AbstractFactory public Plant createPlant(); public Fruit createFruit(); /具体工厂方法 public class FactoryA implements AbstractFactory public Plant createVegetable() return new VegetableA(); public Fruit createFruit() return

25、 new FruitA(); public class FactoryB implements AbstractFactory public Plant createVegetable() return new VegetableB(); public Fruit createFruit() return new VegetableB(); ,3.3 抽象工厂模式,优缺点 支持多种观感标准的用户界面工具箱。 游戏开发中的多风格系列场景,比如道路,房屋,管道等。 系统要在三个不同平台上运行,比如Windows、Linux、Android上运行,你会怎么设计?分别设计三套不同的应用?通过抽象工厂模

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

27、式屏蔽掉操作系统对应用的影响。三个不同操作系统上的软件功能、应用逻辑、UI都应该是非常类似,唯一不同的是调用不同的工厂方法,由不同的产品类去处理与操作系统交互的信息 需要创建的对象是一系列相互关联或相互依赖的产品族时,便可以使用抽象工厂模式。假如各个等级结构中的实现类之间不存在关联或约束,则使用多个独立的工厂来对产品进行创建,则更合适一点。,工厂模式总结,3种在形式和特点上极为相似,最终目的都是解耦。 将对象的创建过程进行封装,使客户端可以直接得到对象,而不用去关心如何创建对象。 工厂方法模式:用于创建复杂对象。 抽象工厂模式:用于创建一组相关或相互依赖的复杂对象。 工厂方法创建一般只有一个方

28、法,创建一种产品。抽象工厂一般有多个方法,创建一系列产品。 我们不必去在意模式到底工厂方法模式还是抽象工厂模式,因为他们之间的演变常常是令人琢磨不透的。明明使用的工厂方法模式,当新需求来临,稍加修改,加入了一个新方法后,由于类中的产品构成了不同等级结构中的产品族,它就变成抽象工厂模式了,而对于抽象工厂模式,当减少一个方法使的提供的产品不再构成产品族之后,它就演变成了工厂方法模式。,本节课题/作业,1、设计模式一般用来解决什么样的问题( ) A.同一问题的不同表相 B不同问题的同一表相 C.不同问题的不同表相 D.以上都不是 2、下列属于面向对象基本原则的是( ) A.继承 B.封装 C.里氏代

29、换 D都不是 3、Open-Close原则的含义是一个软件实体( ) A.应当对扩展开放,对修改关闭. B.应当对修改开放,对扩展关闭 C.应当对继承开放,对修改关闭 D.以上都不对 4、当我们想创建一个具体的对象而又不希望指定具体的类时,可以使用( )模式。 A.创建型 B.结构型 C行为型 D.以上都可以 5、要依赖于抽象,不要依赖于具体。即针对接口编程,不要针对实现编程,是( )的表述 A.开-闭原则 B.接口隔离原则 C.里氏代换原则 D.依赖倒转原则,本节课题/作业,6、静态工厂的核心角色是() A.抽象产品 B.具体产品 C.静态工厂 D.消费者 7、设计模式的6条基本原则是? 8、结合自己所在项目,举例工厂模式的应用,要求画出工厂模式的类图(3种模式任选)。,下节课内容,观察者模式 命令模式 单例模式 。,Thank You !,

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 社会民生


经营许可证编号:宁ICP备18001539号-1