面向对象设计模式-原则
czl923
贡献于2011-06-23
3311
1
0
面向对象设计模式-原则
下载需要
15
金币
[ 金币充值 ]
服务器/托管费、人工审核、技术维护等都需要很多费用,请您支持深度开源的发展
下载PPT
标签:
PPT 内容
1. 面向对象设计模式—基本原则单一职责原则 开放—封闭原则 依赖倒置原则 迪米特法则 里氏替换原则 接口隔离原则 组合/聚合复用原则1
2. 2单一职责原则SRP(Single Responsibility Principle ) 单一职责很容易理解,也很容易实现。所谓单一职责,就是一个设计元素只做一件事。什么是“只做一件事”?简单说就是少管闲事。现实中就是如此,如果要你专心做一件事情,任何人都有信心可以做得很出色。但如果,你整天被乱七八糟的事所累,还有心思和精力把每件事都作好么?
3. 3单一职责原则 “单一职责”不是指具有单一功能(而是只因一个原因变化);应该有且只有一个原因引起类的变更!!! 1.对象颗粒大小不同,对小颗粒对象应用单一职责是不合适的:小颗粒对象如小公司的员工,需要一人兼数职。如果应用单一职责,小颗粒对象又将分解成更多更小颗粒的对象,数量越来越多,给我们命名、使用、维护带来麻烦。 2.“单一职责原则”更适于中大型系统,系统越小使用该原则越不划算:一超个小系统就一个界面,面象对象都不必使用。
4. 4单一职责原则调制解调器 这是一个调制解调器最基本的功能,但是这个类事实上完成了两个职责:连接的建立和中断、数据的发送和接收。显然,这违反了SRP。这样做会有潜在的问题:当仅需要改变数据连接方式时,必须修改Modem类,而修改Modem类的结果就是使得任何依赖Modem类的元素都需要重新编译,不管它是不是用到了数据连接功能。
5. 5单一职责原则解决的办法: 重构Modem类,从中抽出两个接口,一个专门负责连接、另一个专门负责数据发送。依赖Modem类的元素也要做相应的细化,根据职责的不同分别依赖不同的接口。最后由ModemImplementation类实现这两个接口。
6. 6单一职责原则从这个例子中,我们不难发现,违反SRP通常是由于过于“真实”地设计了一个类所造成的。因此,解决办法是往更高一层进行抽象化提取,将对某个具体类的依赖改变为对一组接口或抽象类的依赖。当然,这个抽象化的提取应该根据需要设计,而不是盲目提取。比如刚才这个Modem的例子中,如果有必要,还可以把DataChannel抽象为DataSender和DataReceiver两个接口。
7. 7单一职责原则单一职责的好处: 1.类的复杂性降低,实现什么职责都有清晰明确的定义; 2.可读性提高,复杂性降低,可维护性自然就提高了; 3.可维护性提高,可读性提高,那当然可扩展性就提高了; 4.变更引起的风险降低,变更是必不可少的,如果一个接口的单一职责做的好,一个接口的修改只对相应的实现类有影响,对其他接口无影响,对系统的扩展性、维护性都有很大的帮助
8. 8开放—封闭原则OCP(Open Closed Principle) 我们在做任何系统的时候,都不要指望系统一开始就需求确定,这是不现实也是不科学的想法,既然需求一定是会变化的,那么我们如何在面对需求变化时,设计的软件可以保持相对容易修改,保持相对稳定,不至于新的需求到来,整个推倒重做。只要保持开放封闭原则就可以做到。 面对新需求的到来,要完成新的需求,对程序的改动是通过新增加代码完成的,不是通过修改现有代码完成的。
9. 9开放—封闭原则开放封闭原则 要求"软件实体(类、模块以及功能等)对扩展是开放的,对修改是封闭的。 "一个对象一旦被定义好,并公开给其他对象调用,我们就不能轻易地修改它。这里所谓的"修改",可以分为两个层次来分析。一个层次是对抽象定义的修改,如对象公开的接口,包括方法的名称、参数与返回类型。我们必须保证一个接口,尤其要保证被其他对象调用的接口的稳定;否则,就会导致修改蔓延,牵一发而动全身。
10. 10开放—封闭原则对修改封闭: 做到避免对源代码的修改,即使仅修改具体实现,也需要慎之又慎。这是因为具体实现的修改,可能会给调用者带来意想不到的结果,这一结果并非我们预期的,甚至可能与预期相反。如果确实需要修改具体的实现,就需要做好达到测试覆盖率要求的单元测试。但是设计要做到完全对修改封闭,几乎是不可能完成的任务。我们只能尽量将代码修改的影响降到最低,其核心指导原则就是封装与充分的测试。
11. 11开放—封闭原则对扩展开放: "对扩展开放"的关键是"抽象",而对象的多态则保证了这种扩展的开放性。开放原则首先意味着我们可以自由地增加功能,而不会影响原有系统。这就要求我们能够通过继承完成功能的扩展。其次,开放原则还意味着实现是可替换的。只有利用抽象,才可以为定义提供不同的实现,然后根据不同的需求实例化不同的实现子类。
12. 12开放—封闭原则例如排序算法的调用,对照图1与图2之间的区别。
13. 13开放—封闭原则从某种程度上讲,接口就是标准,要保障接口的稳定,就应该对对象进行合理的封装。一般的设计原则之所以强调方法参数尽量避免基本类型,原因正在于此。比较如下两个方法定义: //定义1 bool Connect(string userName, string password, string ftpAddress, int port); //定义2 bool Connect(Account account); public class Account { public string UserName { get; set; } public string Password { get; set; } public string FtpAddress { get; set; } public string int Port { get; set; } }
14. 14开放—封闭原则 开放封闭原则是说,你设计软件的时候,时刻要把需求的变化考虑全面了,尽量的让这个类足够好,写好了就不去修改它,如果新的需求来了,增加一些类来完成新的需求,原来的代码能不动则不动。 一:首先,一个人不可能把所有的问题考虑全面了,如果什么问题都考虑到了,就不是人了,是先知了。 二:其次,一个类怎么可能写好了就再也不去修改呢。
15. 15开放—封闭原则如何解决: 在我们最开始写程序的时候,假设需求变化不会发生,但当发生需求变化时,我们就立即(当发生小变化时,就及早的去想办法应对发生大变化的可能)构造抽象来隔离以后发生的同类变化。不能等到开发工作进行到一半了或很久了,在考虑抽象,考虑分离,那时候就很困难了。
16. 16开放—封闭原则开放封闭原则的好处: 遵循这个原则可以带来面向对象技术中声称的可维护,可扩展,可复用,灵活性好这些好处。 开放封闭原则的注意事项: 不要对应用程序中的每个部分都刻意的进行抽象,应该对应用程序中出现频繁变化的那部分构造抽象。
17. 17依赖倒置原则DIP (Dependence Inversion Principle ) 传统的软件开发方法,比如结构化分析和设计,总是倾向于创建一些高层模块依赖于低层模块、策略依赖于细节的软件结构。实际上这些方法的目的之一就是要定义子程序层次结构,该层次结构描述了高层模块怎样调用低层模块。然而一个设计良好的面向对象的程序,其依赖程序结构相对于传统的过程式方法设计的通常结构而言就是被“倒置”了。
18. 18依赖倒置原则请考虑依赖于低层模块的高层模块意味着什么。正是高层模块包含了应用程序中重要的策略选择和业务模型。这些高层模块使得其所在的应用程序区别于其它。然而,如果这些高层模块依赖于低层模块,那么对低层模块的改动就会直接影响到高层模块,从而迫使它们依次作出改动。 这种情形是非常荒谬的!本应该是高层的策略设置模块去影响低层的细节实现模块的。 包含高层业务规则的模块应该优先并独立于包含实现细节的模块。无论如何高层模块都不应该依赖于低层模块。
19. 19依赖倒置原则简单的层次化架构:
20. 20依赖倒置原则合理的层次化架构:
21. 21依赖倒置原则简单的DIP示例: 依赖倒置可以应用于任何存在一个类向另一个类发送消息的地方。 例如,Button 对象和Lamp 对象之间的情形。 Button 对象接收 Poll 消息,判断按钮是否被按下,接着简单地发送 TurnOn 或者 TurnOff 消息给 Lamp 对象
22. 22依赖倒置原则 通过倒置对 Lamp 对象的依赖关系可以改进上图 可以看到 Button 现在和一个称为 ButtonServer 的接口关联起来了,Button 可以使用它来开启或者关掉一些东西。Lamp 实现了 ButtonServer 接口。这样,Lamp 现在是依赖于别的东西了,而不是被依赖了。
23. 23依赖倒置原则 所谓依赖倒置原则就是要依赖于抽象,不要依赖于具体。简单的说就是要求对抽象进行编程,不要对实现进行编程,这样就降低了客户与实现模块间的耦合。 1.高层模块不应该依赖底层模块,两者都应该依赖其抽象; 2.抽象不应该依赖细节;细节应该依赖抽象;
24. 24依赖倒置原则 依赖倒置原则的本质就是通过抽象(抽象类或者接口)使各个类或模块的实现彼此独立,不互相影响,实现模块间的松耦合,如果需要使用该规则,需要遵循以下规则: 每个类尽量都有接口或者抽象类,或者抽象类和接口两者都具备(这个是该原则的基本要求,接口和抽象类都是抽象,有了抽象才可能依赖倒置)
25. 25基本原则总结单一职责原则 ----应该有且只有一个原因引起类的变更。 开放封闭原则 ----对扩展是开放的,对修改是封闭的。 依赖倒置原则 ----高层模块不应依赖底层模块,两者都应该依赖其抽象; ----抽象不应该依赖细节;细节应该依赖抽象。
26. 26迪米特法则 LOD( Law of Demeter) 又叫做最少知识原则(LeastKnowledge Principle 简写LKP),也就是说,一个对象应当对其他对象尽可能少的了解,不和陌生人说话。
27. 27迪米特法则 狭义的迪米特法则是指:如果两个类不必彼此直接通信,那么这两个类就不应当发生直接的相互作用。如果其中一个类需要调用另一类的某一个方法的话,可以通过第三者转发这个调用。 广义的迪米特法则是指:一个模块设计的好坏的一个重要标志就是该模块在多大程度上将自己的内部数据与实现的有关细节隐藏起来。 一个软件实体应当尽可能少的与其他实体发生相互作用!!!
28. 28迪米特法则 在运用迪米特法则到系统的设计中时,要注意以下几点: 第一:在类的划分上,应当创建弱耦合的类,类与类之间的耦合越弱,就越有利于实现可复用的目标。 第二:在对其他类的应用上,一个对象对其他类的对象的应用应该降到最低。
29. 29迪米特法则 类与类之间尽量不直接通信,如果类之间需要通信就通过第三方转发的方式,这就直接导致了系统中存在大量的中介类,这些类存在的唯一原因是为了传递类与类之间的相互调用关系,这就毫无疑问的增加了系统的复杂度。
30. 30迪米特法则如何解决: 使用依赖倒转原则(通俗的讲就是要针对接口编程,不要针对具体编程),这要就可以是调用方和被调用方之间有了一个抽象层,被调用方在遵循抽象层的前提下就可以自由的变化,此时抽象层成了调用方的朋友。
PPT 图集
相关PPT
面向对象设计模式-原则
第2章 面向对象设计原则
Java面向对象程序设计
《C++面向对象程序设计》第2章 类和对象
05.面向对象程序设计 2
《C++面向对象程序设计》第3章 面向对象程序设计概述
Java面向对象设计-接口
UML面向对象建模与设计第一章ppt
04.面向对象程序设计1
Java面向对象程序设计第4章_类与对象