面向对象设计原则ppt课件.ppt

上传人(卖家):三亚风情 文档编号:2227872 上传时间:2022-03-23 格式:PPT 页数:37 大小:258KB
下载 相关 举报
面向对象设计原则ppt课件.ppt_第1页
第1页 / 共37页
面向对象设计原则ppt课件.ppt_第2页
第2页 / 共37页
面向对象设计原则ppt课件.ppt_第3页
第3页 / 共37页
面向对象设计原则ppt课件.ppt_第4页
第4页 / 共37页
面向对象设计原则ppt课件.ppt_第5页
第5页 / 共37页
点击查看更多>>
资源描述

1、面向对象设计原则目标 重新认识一下面向对象 了解面向对象设计原则重新认识面向对象 通过面向对象编程语言(OOPL)认识到的面向对象, 并不是面向对象的全部,甚至只是浅陋的面向对象 不是使用了面向对象语言就是实现了面向对象的设计和开发 我们不能依赖编程语言的面向对象机制来掌握面向对象 OOPL的三大机制“封装、继承、多态”可以表达面向对 象的概念,但是没有刻画出面向对象的核心精神。 可以用这三大机制做出好的“面向对象设计”也可以做出差的“面向对象的设计”.重新认识面向对象 OOPL没有回答面向对象的根本性问题-我们为什么要面向对象?我们应该怎样实现好的面向对象?我们应该遵循什么样的原则? 任何一

2、个严肃的面向对象程序员都要系统的学习面向对象知识,单纯从编程语言上获得的面向对象知识,不能够胜任面向对象设计与开发.举一个例子示例场景: 我们需要设计一个人事管理系统,其中的一个功能是对各种不同的类型员工,计算其当月的工资-不同类型的员工,拥有不同的薪金计算制度。机构化做法1。 获得人事系统中所有可能的员工类型2。 根据不同的员工类型所对应的不同薪金制度,计算其工资 enum EmployeeType Engineer; Sales; Manager; /计算工资程序If(type=EmployeeType.Enginner)else if (type=EmployeeType.Sales)面

3、向对象设计1 根据不同员工设计不同的类,并使这些类继承自一个Employee抽象类,其中有一个抽象方法getSalary.2 在各个不同的员工中,根据自己的薪金制度,重写(override)getSalary方法abstract class Employee public abstract int getSalary();class Sales extends Employeepublic int getSalary().class Engineer extends Employeepublic int getSalary()/ 显示工资程序Employee e = emFactory.get

4、Employee(id);System.out.println(e.getSalary();现在需求变了示例场景: 随着业务的规模的拓展,又出现了更多类型的员工,比如钟点工、计件工等等,这对系统提出了新的挑战原有的程序要改变。结构化做法: 几乎所有涉及到员工类型的地方都要做改变这些代码都要重新编译重新部署面向对象做法: 只要添加新的员工类,让其继承自Employee抽象方法,并重写getSalary()方法,然后在EmployeeFactory.getEmployee()方法中根据相关条件产生新的员工类型就可以了。其他地方不需要改变.重新认识对于前面的例子,从宏观上看,面向对象的构建方式跟更能

5、适应软件的变化,能将变化所带来的影响减小到最小。从微观层面来看,面向对象的方式更强调各个类的“责任”,新增员工类型不会影响原来员工类型的实现代码这是符合真实世界的,也更能控制变化所影响的范围,毕竟Engineer类不应该为新增的“钟点工”来买单对象是什么? - 从概念层面讲,对象是某种责任的抽象。 - 从规格层面讲,对象是一系列可以被其他对象使用的接口(API)。 - 从语言实现层面来看,对象封装了代码和数据(行为和状态)。有了这些认识之后,怎样才能设计“好的面向对象”? - 遵循一定的面向对象设计原则 - 熟悉一些经典的面向对象设计模式.面向对象设计原则 针对接口编程,而不是针对实现编程 -

6、客户无需知道所使用对象的特定类型,只需知道对象拥有客户所期望的接口 有限使用组合,而不是类继承 -类继承通常为“白箱复用”,对象组合通常成为“黑箱复用”。继承在某种程度上破坏了封装性,子类父类耦合度高;而对象组合则只要求被组合对象具有良好定义的接口,耦合度低。 封装变化点 - 使用封装来创建对象之间的分界层,让设计者可以在分界层的一侧进行修改,而不会对另一侧产生不良的影响,从而实现层次间的松耦合。具体的设计原则 单一职责原则(SRP) 开放封闭原则(OCP) Liskov 替换原则(LSP) 依赖倒置原则(DIP) 接口隔离原则(ISP) 单一职责原则l就一个类而言应该仅有一个引起它变化的原因

7、。 当需求变化时,该变化就会反映为类的职责变化。如果一个类承担了多个职责,那么引起它变化的原因就有多个。 如果一个类承担的职责过多,就等于把这些职责耦合在了一起。一个职责的变化就可能会削弱,或者抑制这个类完成其他职责的能力. 如果需求变化总是引起多个职责同时变化,那么我们就不必分离它们 推论:只有变化实际发生时才有意义.开放封闭原则 OCP软件实体(类、模块、函数等等)应该是可以扩展的,但是不可以修改的 - 对扩展是开放的。当需求 变化时,我们可以对模块进行扩展,使其具有能够满足那些变化的行为。 - 对更改是封闭的。对模块进行修改时不必改动模块的源代码(并非绝对,但是应该是最小限度)例子Int

8、erface Shapepublic void draw()class Square extends Shapepublic void draw()class Circle extends Shapepublic void draw()class Test public static void main(String args) List shapes = /绘制所有图形 Iterator iter = shapes.iterator();while(iter.hasNext() (Shape)iter.next().draw(); 如果要绘制一个新的形状,只需要增加一个新的Shape的派生类

9、就行了.(系统的其他地方会有一些改动,但是这里没有改动)我说谎了! 上面的例子并不是100%封闭的。如果我们要求所有的圆必须在正方形之前绘制,我们就要改动Test的代码了。 一般而言,无论模块多么“封闭”,都会存在一些无法对之封闭的变化。没有对所有情况都贴切的模型。如何对待? 设计人员必须对于他设计的模块应对哪种变化封闭做出选择。必须先猜测出最有可能发生变化的种类,然后构造抽象来隔离那些变化。 有时不容易做到,代价有时会比较高,我们希望把OCP应用限定在可能发生的变化上。结论 开发人员应该仅仅对程序中呈现出频繁变化的那些部分做出抽象。拒绝不成熟的抽象和抽象本身一样重要。(对变化进行封装)Lis

10、kov(里氏)替换原则(LSP)子类型必须能够替换掉它们的基类型一个微妙的违规正方形是矩形(is-a 关系)。正方形继承矩形。public class Rectangle private double h; private double w; public void setHeight(double h) this.h = h; public void setWidth(double w) this.w = w; public double getHeight() return this.h; public double getWidth() return this.w; public dou

11、ble area() return this.getHeight()*this.getWidth(); public class Square extends Rectangle private double h; private double w; public void setHeight(double h) this.h = h; this.w = h; public void setWidth(double w) this.w = w; this.h = w; public double getHeight() return this.h; public double getWidth

12、() return this.w; public class Test public void fun(Rectangle r)r.setHeight(1);r.setWidth(2);System.out.println(r.area();public static void main(String args) Rectangle r = new Rectangle();Rectangle s = new Square();Test t = new Test();/t.fun(r);t.fun(s);如果 fun方法的参数Rectangle 指向的是一个正方形 ,产生的结果就会让人产生迷惑。

13、结果是4! 对于写fun方法的人来讲,他会认为应该是2.IS-A 是关于行为的 Square对象的行为方式和函数fun所期望的Rectangle对象的行为方式不相容. 对象的行为方式才是软件真正所关注的问题.(关心是不是想象中的那种行为) OOD中IS-A关系是就行为方式而言的.接受缺陷 大多数情况下,接受一个多态行为中的微妙错误会比试着修改设计使之完全符合LSP更为有利. 接受缺陷而不是去追求完美是一个工程上权衡的问题. 好的工程师知道如何接受缺陷比追求完美更有利 不过,不应该轻易放弃LSP原则 我们经常用的例子struts类类RequestProcessor 里面的代码:protected

14、 ActionForward processActionPerform(HttpServletRequest protected ActionForward processActionPerform(HttpServletRequest request,request, HttpServletResponse response, Action action, ActionForm form, ActionMapping mapping) throws IOException, ServletException throws IOException, ServletException try t

15、ry return (return (action.execute(mapping, form, request, response)action.execute(mapping, form, request, response); ); catch (Exception e) catch (Exception e) return (processException(request, response, e, form, mapping);return (processException(request, response, e, form, mapping); 注意红色部分依赖倒置原则 DI

16、P 要依赖于抽象不要依赖于具体 抽象不应该依赖于细节,细节应该依赖于抽象 另一种说法:要对接口编程,不要针对实现编程.另一种说法的解释 应当使用java接口和抽象java类进行变量的类型声明,参量的类型声明,方法的返回类型声明,以及数据类型的转换等.Vector employees = new Vector(); 应该声明为 List employees = new Vector(); 好处是,将Vector类型转会为ArrayList 需要最小的改动.怎样做到 以抽象方式耦合是依赖倒转原则的关键. 一个抽象耦合关系总要涉及具体类从抽象类继承,并且保证任何引用到基类的地方都可以换成其子类,因此

17、里氏替换原则是依赖倒置原则的基础.并非完美 抽象层次上的耦合虽然有灵活性,但也带来了额外的复杂性. 如果一个具体类发生变化的可能性非常小,那么抽象耦合发挥的好处便十分有限,这时使用具体耦合反而会更好接口隔离原则ISP 接口的污染,一个没有经验的设计师往往想节省接口的数目,将几个功能相近或功能相关的接口合并,并将这看成是代码优化的一部分.接口隔离原则ISP 定义: 从一个客户类的角度来讲:一个类对另外一个类的依赖性应当是建立在最小接口上的.使用多个专门的接口比使用单一的总接口要好.例子例子(单一职责)总结 “开-闭”原则(OCP) 对可变性封装 里氏替换原则(LSP) 如何进行继承 依赖倒置原则(DIP) 针对接口编程 接口隔离原则(ISP) 恰当的划分接口和角色我所理解的好软件 满足需求 能够应对变化结束谢谢我所理解的好软件 满足需求 能够应对变化结束谢谢

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

当前位置:首页 > 办公、行业 > 各类PPT课件(模板)
版权提示 | 免责声明

1,本文(面向对象设计原则ppt课件.ppt)为本站会员(三亚风情)主动上传,163文库仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。
2,用户下载本文档,所消耗的文币(积分)将全额增加到上传者的账号。
3, 若此文所含内容侵犯了您的版权或隐私,请立即通知163文库(发送邮件至3464097650@qq.com或直接QQ联系客服),我们立即给予删除!


侵权处理QQ:3464097650--上传资料QQ:3464097650

【声明】本站为“文档C2C交易模式”,即用户上传的文档直接卖给(下载)用户,本站只是网络空间服务平台,本站所有原创文档下载所得归上传人所有,如您发现上传作品侵犯了您的版权,请立刻联系我们并提供证据,我们将在3个工作日内予以改正。


163文库-Www.163Wenku.Com |网站地图|