设计模式六大原则课件

上传人:我*** 文档编号:144751960 上传时间:2020-09-13 格式:PPT 页数:42 大小:1.12MB
返回 下载 相关 举报
设计模式六大原则课件_第1页
第1页 / 共42页
设计模式六大原则课件_第2页
第2页 / 共42页
设计模式六大原则课件_第3页
第3页 / 共42页
设计模式六大原则课件_第4页
第4页 / 共42页
设计模式六大原则课件_第5页
第5页 / 共42页
点击查看更多>>
资源描述

《设计模式六大原则课件》由会员分享,可在线阅读,更多相关《设计模式六大原则课件(42页珍藏版)》请在金锄头文库上搜索。

1、北风网项目培训,讲师:石曼迪,设计模式面向对象基础,本章目标,开-闭原则 单一职责原则 接口隔离原则 里氏代换原则 依赖倒转原则 组合优先于继承,面向对象诊所,系统僵化,不可修改或者扩展(修改难或扩展难)。 过分复杂或者重复代码多,往往看代码的时候不知道从哪里看起,也不知道程序会跑到哪里去。 不可复用,公共部分剥离不出来只能到处拷贝。 不够稳定,经常出错-改-出错-改. 系统运行不可靠,连自己也不敢相信自己的系统,原则的诞生,面向对象:封装、继承、多态三大支柱蕴含了用抽象来封装变化,降低耦合,实现复用的精髓。 封装:隐藏内部实现,保护内部信息 继承:实现复用,归纳共性 多态:改写对象行为,实现

2、更高级别的继承 要实现这些目的,就必须遵守一些原则:封装变化、对接口编程、少继承多聚合 实现系统的可扩展、可复用、灵活性好、维护性好,一、开-闭原则(OCP),核心思想: 对扩展开放:有新的需求或变化时,可以对现有代码进行扩展,以适应新情况。 对修改关闭:类一旦设计完成,就可以独立完成自己的工作,而不要再对类进行任何修改。 实现方式:抽象,多态,继承,接口,软件应该是可扩展,而不可修改的。,对扩展开放,对修改关闭。,实例分析,Console.Write(请输入数字A:); string A = Console.ReadLine(); Console.Write(请选择运算符号(+、-、*、/)

3、:); string B = Console.ReadLine(); Console.Write(请输入数字B:); string C = Console.ReadLine(); string D = ; if (B = +) D = Convert.ToString(Convert.ToDouble(A) + Convert.ToDouble(C); if (B = -) D = Convert.ToString(Convert.ToDouble(A) - Convert.ToDouble(C); if (B = *) D = Convert.ToString(Convert.ToDoubl

4、e(A) * Convert.ToDouble(C); if (B = /) D = Convert.ToString(Convert.ToDouble(A) / Convert.ToDouble(C); Console.WriteLine(结果是: + D);,要加运算,怎么办?,实例分析,先不论程序的健壮性,如果客户要求增加求余运算,该如何处理?,增加判断,增加分支,客户类,改进后,客户类,开闭原则小结,开闭原则适用于那些需求会经常发生变化的系统,应该努力使大部分模块满足开闭原则。开闭原则是面向对象设计的核心,满足该原则可以达到最大限度的复用和可维护性。,二、单一职责原则(SRP),(1)

5、目的:如果你有多个原因去改变一个类,那么应该把这些引起变化的原因分离开,把这个类分成多个类,每个类只负责处理一种改变。当你做出某种改变时,只需要修改负责处理该改变的类。 (2)单一职责原则 一个类应该只受一种变化的影响。 如果一个类承担的职责过多,就等于把这些职责耦合在一起,一个职责的变化可能会削弱或者抑制这个类完成其他职责的能力。这种耦合会导致脆弱的设计,当变化发生时,设计会遭到意想不到的破坏。,一个类,应该仅有一个引起它变化的原因,单一职责原则(SRP),(3)好处: 类的复杂性降低,实现什么职责都有清晰明确的定义。 可读性提高。 可维护性提高。 变更引起的风险降低。,实例,interfa

6、ce Modem public void dial(string pno); public void hangup(); public void send(char c); public void recv(); ,interface DataChannel public void send(char c); public void recv(); interface Connection public void dial(string pno); public void hangup(); ,modem接口明显具有两个职责:连接管理和数据通讯,如果应用程序变化影响连接方法,那么就需要重构,单

7、一职责原则小结,优点:消除耦合,减小因需求变化引起代码僵化性臭味 使用SRP注意点: 1、一个合理的类,应该仅有一个引起它变化的原因,即单一职责; 2、在没有变化征兆的情况下应用SRP或其他原则是不明智的; 3、在需求实际发生变化时就应该应用SRP等原则来重构代码; 4、使用测试驱动开发会迫使我们在设计出现臭味之前分离不合理代码; 5、如果测试不能迫使职责分离,僵化性和脆弱性的臭味会变得很强烈,那就应该用Facade或Proxy模式对代码重构;,三、接口隔离原则(ISP),(1)目的:当我们设计应用程序的时候,如果一个模块包含多个子模块,那么我们应该小心对该模块做出抽象。设想该模块由一个类实现

8、,我们可以把系统抽象成一个接口。但是当我们想要添加一个新的模块扩展程序时,如果要添加的模块只包含原系统中的一些子模块,那么就会强迫我们实现接口中的所有方法,并且还要编写一些哑方法。这样的接口被称为胖接口或者叫被污染的接口。 (2)接口隔离原则 接口隔离原则表明客户端不应该被强迫实现一些他们不会使用的接口,应该把胖接口中的方法分组,然后用多个接口代替它,每个接口服务于一个子模块。,客户端不应该依赖它不需要的接口,实力分析,interfaceIWorker publicvoidwork(); publicvoideat(); classWorker:IWorker publicvoidwork()

9、 /.working publicvoideat() /.eating ,这样客户端,需要吃的时候还得工作,改进后,interface IWorkable void work(); interface IFeedable void eat(); class Worker : IWorkable, IFeedable public void work() /.working public void eat() /.eating class Robot : IWorkable public void work() /.working ,接口隔离原则小结,接口的设计应该遵循最小接口原则,不要把用户不

10、使用的方法塞进同一个接口里。 如果一个接口的方法没有被使用到,则说明该接口过胖,应该将其分割成几个功能专一的接口。 过度的使用该原则将会产生大量的包含单一方法的接口,所以需要根据经验并且识别出那些将来需要扩展的代码来使用它。,四、里氏代换原则(LSP),核心思想: 在一个软件系统中,子类应该可以替换任何基类能够出现的地方,并且经过替换以后,代码还能正常工作。 目的:当我们设计程序模块时,我们会创建一些类层次结构,然后我们通过扩展一些类来创建它们的子类。我们必须确保基类的引用可以被子类替换而不影响模块的功能,否则当我们在已有程序模块中使用它们时将会产生不可预料的结果。,子类必须能够替换其基类,实

11、例 分析,class Father public string type; public Father() type = father; public void Method() ,class Son:Father public Son() type = son; public void MyMethod() ,实例分析,父类中不存在MyMethod()方法,导致子类不能替换父类,属于僵化设计,当有新类增加时,必须修改分支判断。,public static void DoSomeThing(Father f) switch (f.type) case father: f.Method(); b

12、reak; case son: (Son)f).MyMethod(); break; ,改进,class Father public string type; public Father() type = father; public virtual void Method() ,class Son:Father public Son() type = son; public override void Method() ,public static void DoSomeThing(Father f) f.Method(); ,如果Method()被实现为虚方法,并且在子类中可以被重写,则传

13、入DoSomeThing的参数既可以是父类类型也可以是子类类型,子类完全可以代替父类在此调用自己的方法。,小结,Liskov替换原则是关于集成机制的设计原则,违反了Liskov替换原则必然导致违反开闭原则。 Liskov替换原则能够保证系统具有良好的扩展性,同时实现基于多态的抽象机制,能够减少代码冗余,避免运行期间的类型判断。 子类必须满足基类和客户端对其行为的约定,客户端对行为的期望在子类和基类中必须保持一致。,五、依赖倒转原则(DIP),(1)目的:在一个应用程序中,我们有一些实现了基础的、主要的操作的底层类和一些封装了复杂逻辑的上层类。实现这种结构的很自然地方式就是,先编写底层类,完成后

14、再编写复杂的上层类。因为上层类是由其他东西定义的,所以这看起来是一种很合理的方式。但是这不是一个灵活的设计,如果我们需要替换一个底层类时会发生什么? (2)什么是依赖? 所谓依赖,举个例子说明,一个类Person,另一个类Car,如果Person的某个方法比如说drive,需要引用Car,则称Person类依赖于Car类,依赖倒转原则,实例:一个类Person,另一个类Car,Person的某个方法drive,需要引用Car:,Public Person . public void drive() Car bmw = new Car(“BMW); bmw.挂档; bmw.踩油门; bmw.打方

15、向; ,依赖倒转原则,程序有什么缺点? Person类对象依赖于Car类对象,带来耦合度高,不易维护等缺点。例如,想让Person类对象驾驶AUDI,则需要改动Person类代码。 如何更改? 将这种具体类之间的依赖,尽量转换成抽象类(或接口)依赖。 类Person应该依赖于抽象类ICar,而不是具体的类Car,依赖倒转原则,Public Person private ICar car; public Person(ICar car) this.car = car; public void drive() car.挂档; car.踩油门; car.打方向; ,BMW bmw = new BMW

16、();Person boy = new Person(bmw);boy.drive(); AUDI audi = new AUDI();Person boy = new Person(audi);boy.drive();,小结,以抽象方式耦合是依赖倒转原则的关键 依赖倒转原则假定所有的具体类都会变化,如果有些具体类就相当稳定.使用这个类的客户端就完全可以依赖这个具体类而不用再弄一个抽象类. 某种意义上,依赖倒转原则是达到“开-闭”原则的途径。,六、组合优先于继承,(1)什么是继承? 它可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展。 (2)什么是组合? 通过创建一个

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 办公文档 > PPT模板库 > PPT素材/模板

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号