《绪设计模式基础》PPT课件.ppt

上传人:sh****n 文档编号:6669499 上传时间:2020-03-02 格式:PPT 页数:95 大小:3.74MB
返回 下载 相关 举报
《绪设计模式基础》PPT课件.ppt_第1页
第1页 / 共95页
《绪设计模式基础》PPT课件.ppt_第2页
第2页 / 共95页
《绪设计模式基础》PPT课件.ppt_第3页
第3页 / 共95页
点击查看更多>>
资源描述
软件设计模式 设计模式基础 面向对象基本概念接口与抽象类类图中的关系面向对象中的一些原则 机器语言助记符语言汇编语言面向机器直接控制机器的运行 面向对象技术及其发展历史 从 软件工程 的发展史看面向对象技术出现的必然性 面向机器 FORTRANBASIC面向过程描述解题过程 CPASCAL结构化程序设计以控制结构表示程序的物理层次结构 C Java面向对象程序设计程序设计过程与人类的认知过程统一 面向过程 结构化程序设计 面向对象程序设计 传统方法分析与设计之间的鸿沟 传统方法与面向对象方法的区别 1将问题划分为不同对象 2通过类比发现对象间存在的相似性 从而得到类 子类 父类等 3对属于同一个类的对象定义一组数据用以刻画该类对象的整体特征 定义一组 方法 函数 用以描述能够对该类对象进行的操作 行为 4建立对象间的联系以反映不同对象之间的相互作用 符合人类认知规律的软件开发过程 对象特征 现实世界的对象 有自己的状态 如一台空调有自己编号 摆放位置 颜色 尺寸 重量 工作状态 有自己的行为 功能 如空调的开机 关机 制冷 制热 摆风 机器世界的的对象 对象的状态用属性来维护 变量 对象的行为用方法来实现 代码 对象与类 对象与类 计算机世界 徐军 徐军 对象 学生 类 创 建 现实世界 概念世界 学生 抽 象 定义类 对应 案例 定单系统 公司需求 成立新的公司 时尚服装 每月发布商品编目 并寄给定户 客户可以发e mail或FAX定货 寄定单 对于客户的定货要检查存货清单 如缺货 得暂时搁置定单 直到供货商送到货 公司检查支票和信用卡 公司将定单下发给仓库 给客户发货 注意 同种商品每月价格不一 如果订户使用的是六个月之前的编目 价格采用当前编目价格 公司接受所有主要的信用卡 分析对象 系统是由相互作用的对象组成 任何系统需要它的对象做它的工作 案例对象 定单 服装 客户 在一个问题域中识别对象不是科学而是艺术 对象取决于人的观点 模块化 应用 从 名词 开始确定系统中的对象 对象可以是 简单的和复杂的 衬衣 银行实际的和概念的 银行出纳员 银行帐号 对象的属性和方法 确定对象的属性和方法对象属性 客户 客户号 客户名 地址 定单 定单号 定货条目 顾客 对象方法 让对象做的事情 可以对自己 也可以对其他对象 经常影响对象属性 客户 提交定单 定单 打印定单 改变条目 多态 polymorphisn 14 Person类 老师 学员 SayHi SayHi 继承 List SayHi 遍历List 循环SayHi 内容不同 将所有人都存入集合 调用两种类型的SayHi方法 15 扩展的麻烦 for inti 0 i person Count i if person i isStudent Student person i StuSayHi elseif person i isTeacher Teacher person i TeachSayHi 进行判断对象类型 调用相应类的SayHi 添加多个不同的子类 SayHi都不同增加代码复杂度如何解决 添加对象后遍历泛型集合 16 巧妙的做法 abstractclassPerson publicabstractvoidSayHi for inti 0 i person Count i person i SayHi 这种方式实现了面向对象的多态 修改Person类 添加一个未实现的方法 用关键字修饰 去除子类类型判断 17 生活中的多态 Cut 听到这个声音他们会做什么 剪断头发 切开皮肤 停止表演 不同对象对于同一个方法 Cut 调用的不同行为 理发师 外科医生 演员 18 什么是多态 指不同对象收到相同消息时 会产生不同行为 Student和Teacher类SayHi的内容不同 同一个类在不同的场合下表现出不同的行为特征 Person Student Teacher Person类 在这两种场合的行为不同 19 抽象类和抽象方法 abstractclassPerson publicabstractvoidSayHi 抽象方法 一个没有实现的方法 有抽象方法的类必然是抽象类 抽象类用来列举一个类所需要的行为抽象类不明确提供具体实现方法抽象类必须由其子类实现它的抽象方法 除非子类也具有抽象性 abstract修饰符 抽象类可以具有指向子类对象的对象引用 21 常见错误 抽象类不能被实例化 抽象类不能是密封或静态的 Personperson newPerson 编译错误 抽象类不能用sealed和static修饰 22 实现抽象方法 使用override实现抽象方法 publicoverridevoidSayHi 具体实现内容 重写 实现抽象方法 23 Dog Animal Cat Animal 抽象类的应用场合 abstractAnimal 抽象类和抽象方法实现多态性父类提供一系列规定 约束子类的行为父类可以提供一些共性的行为 猫咪喵喵叫 狗狗汪汪叫 abstract叫 是动物就要会叫 24 练习 利用多态性编写这三种职业听到 cut 时的行为 25 练习 定义一个抽象类 计算各种形状周长 面积以及体积的方法 定义三个类分别实现三角形 圆形与正方形的相关周长 面积及体积的计算方法 生活中的接口 电脑主板上的PCI插槽的规范就类似于Java接口 声卡 电视卡 网卡 每种卡的内部结构都不相同 可以把声卡 网卡 显卡都插在PCI插槽上 而不用担心哪个插槽是专门插哪个卡的 主板 接口 如果一个抽象类中的所有方法都是抽象的 就可以将这个类用另外一种方式来定义 也就是接口定义 接口是抽象方法和常量值的定义的集合 从本质上讲 接口是一种特殊的抽象类 这种抽象类中包含常量和方法的定义 而没有变量和方法的实现 例如publicinterfaceRunner intID 1 voidrun 注意 在接口中 所有的成员都是public访问类型的 而不论是否用public关键字修饰 接口里的变量都是用publicstaticfinal标识的 所以 接口中定义的变量就是全局静态常量 接口中的方法默认都是publicabstract类型的 JAVA接口 一个JAVA接口是一些方法特征的集合 但是没有方法的实现 JAVA中定义的方法在不同的地方被实现 可以具有完全不同的实现 publicinterfacePCI publicvoidstart publicvoidstop 这是Java接口 相当于主板上的PCI插槽的规范 classSoundCardimplementsPCI publicvoidstart System out println Dudu publicvoidstop System out println Soundstop classNetworkCardimplementsPCI publicvoidstart System out println Send publicvoidstop System out println Networkstop 声卡 网卡都实现了PCI插槽的规范 但行为完全不同 接口特点 写一个接口 验证以下特点 1 接口中的成员变量默认都是publicstaticfinal类型的 2 接口中的方法默认都是publicabstract类型的 3 接口没有构造方法 不允许创建接口的实例 4 接口必须通过其他类来实现它的抽象方法 5 一个类可以实现多个接口 接口的使用 一个类只能用implements关键字去实现一个接口中的所有方法classFishimplementsAnimal publicvoidrun System out println fishcanswim publicvoidbreathe System out println fishcanbreathe 我们可以定义一个新的接口 用extends关键字去继承一个已有的接口 注意 只能接口继承接口 类不能继承接口 Wepull系统 要求 打印机有多种类型 比如 黑白打印机 彩色打印机等区域可能配备其中任意一款打印机 负责信息系统要具备良好的可扩展性与可维护性 print方法 打印 彩色打印机 黑白打印机 黑白内容 区域 讲师详细信息 彩色内容 采用面向接口编程的方式实现 以下是三个步骤中的第一步 抽象出Java接口1 分析 黑白 彩色打印机都存在一个共同的方法特征 print黑白 彩色打印机对print方法有各自不同的实现2 结论 抽象出Java接口Printer 在其中定义方法print3 具体实现 publicinterfacePrinter publicvoidprint Stringcontent 采用面向接口编程的方式实现 以下是三个步骤中的第二步 publicclassColorPrinterimplementsPrinterFace publicvoidprint Stringcontent System out println 彩色打印 System out println content 实现Java接口1 分析 已经抽象出Java接口PrinterFace 并在其中定义了print方法黑白 彩色打印机对print方法有各自不同的实现2 结论 黑白 彩色打印机都实现PrinterFace接口 各自实现print方法3 具体实现 publicclassBlackPrinterimplementsPrinterFace publicvoidprint Stringcontent System out println 黑白打印 System out println content 采用面向接口编程的方式实现 以下是三个步骤中的第三步 使用Java接口1 分析 主体构架使用接口 让接口构成系统的骨架2 结论 更换实现接口的类就可以更换系统的实现3 具体实现 publicclassWepullArea3implementsIntroduceable privatePrinterFaceprinter 打印机publicvoidsetPrinter PrinterFacep this printer p publicStringdetail return 这里是Wepull区域 publicvoidprint Introduceableintro printer print intro detail publicclassWepullTest publicstaticvoidmain String args 创建区域实例WepullArea3area newWepullArea3 为该区域配备黑白打印机area setPrinter newBlackPrinter area print area 为该区域配备彩色打印机area setPrinter newColorPrinter area print area 接口与抽象类的区别 抽象类是一类事物的高度聚合 那么对于继承抽象类的子类来说 对于抽象类来说 属于 是 的关系 而接口是定义行为规范 因此对于实现接口的子类来说 相对于接口来说 是 行为需要按照接口来完成 例如 狗是对于所有狗类动物的统称 京哈是狗 牧羊犬是狗 那么狗的一般特性 都会在京哈 牧羊犬中找到 那么狗相对于京哈和牧羊犬来说 就属于这类事物的抽象类型 而对于 叫 这个动作来说 狗可以叫 鸟也可以叫 很明显 前者相当于所说的是抽象类 而后者指的就是接口 多态综合练习 动物园的饲养员为猫吃鱼 狗吃肉 大象吃香蕉 用什么实现最好 抽象类VS接口 依赖关联泛化实现 理解类之间的关系 类之间的关系 依赖 依赖依赖指的是类之间的调用关系 一个类调用了另一个类的服务 方法 如果一个类A在它的方法中调用了另一个类B的方法或属性 则可以说类A依赖类B UML用带箭头的虚线表示依赖 读者每次看书时 都要跑到图书馆借书 因此读者类依赖于图书馆类 一个人可以买车和买房 PublicclassPerson publicvoidbuy Carcar Publicvoidbuy Househouse 类之间的关系 关联 关联关联指的是类之间的特定对应关系 在面向对象程序语言角度 关联代表一个类拥有的某个属性对应着另一个类 UML用带箭头的实线表示关联关系 描述关联关系的三个维度特性 方向性多重性聚集性 关联的三大特性 方向性 单向关联 如学生与课程的关系 学生需要知道上哪些课程 但课程本身不必知道有哪些学生来听双向关联 如导师与学生的关系 关联是有方向的 方向性代表一个类是否拥有能够导航到另一个类的知识 即意味着其有一个状态来保持到对方的引用 UML中 用箭头表示关联方向 双向关联则画两个箭头 或不画箭头 关联的三大特性 多重性 关联可能是多重的 一对一关联 如一个家教只给一个学生上课一对多关联 如果一个博导可以带多个研究生 而一个研究生只有一个导师 则导师和学生之间是一对多关联多对多关联 一个学生需要修多门课程 每门课程都会有很多学生来上课 关联的三大特性 聚集性 聚集性具体可以分两种类型 聚合 Aggregate 普通聚集关系 被聚集的类或子系统允许被拆卸和替换 组合 Composite 强聚集关系 被聚集的类或子系统不能被拆卸和替换 UML以带菱形的实线表示聚集 聚集是一种特殊的关联关系 特指对象之间存在一种 整体与部分 的包含关系 类之间的关系 聚集 聚合 PC与主板 CPU 机箱 电源 显示器等 组合 集成主板与集成在上面的声卡 网卡 显卡 类之间的关系 依赖 关联 聚集 依赖 关联 聚集 代表运行时的临时相关性 代表设计时的固定相关性 代表设计时的对象包含关系 关系递进方向 相识 朋友 相恋 情人 结婚 家庭 临时相关性 固定相关性 对象包含关系 软件世界的对象关系 真实世界的 对象 关系 类之间的关系 泛化 泛化泛化指类之间的继承关系UML以带三角的实线表示泛化 类之间的关系 实现 实现实现指的是类与接口之间的关系 UML用带三角形的虚线表示实现关系 软件的可维护性与可复用性 开 闭 原则 OCP 里氏代换原则 LSP 依赖倒转原则 DIP 接口隔离原则 ISP 合成 聚合复用原则 CARP 迪米特法则 LoD 软件系统的可维护性 软件维护的费用 软件开发的费用 2软件的维护 软件的再生导致软件可维护性底的原因 过于僵硬 Rigidity 过于脆弱 Fragility 复用率低 Immobility 黏度过高 Viscosity 软件系统的设计目标 可扩展性 Extensibility 新的性能可以很容易地加入到系统中是 过于僵硬 的反面灵活性 Flexibility 可以允许代码修改平稳地发生 而不会涉及到很多其他的模块是 过于脆弱 的反面可插入性 Pluggability 可以很容易的将一个类抽出去 同时将另一个有同样接口的类加入进来是 黏度过高 的反面 系统的可复用性 复用 Reuse 重复使用软件复用的好处较高的生产效率重复使用的软件成分可以为将来的使用节省费用较高的软件质量可复用的软件成分总是比不能复用的软件成分有更多的质量保证恰当使用复用可以改善系统的可维护性 传统的复用 代码的剪贴复用算法的复用如经典的排序算法等数据结构的复用如队 栈等传统的复用方案不能增强可维护性模块A和B同时使用模块CA需要模块C增加一个功能B不能允许C增加这样一个功能 面向对象设计的复用 数据的抽象化和继承关系使得概念和定义可以复用多态性使得实现和应用可以复用抽象化和封装可以保持和促进系统的可维护性面向对象设计的复用重点的转移不再集中在函数和算法等具体实现细节上而是集中在最重要的含有宏观商业逻辑的抽象层次上 开 闭原则 定义 一个软件实体应当对扩展开放 对修改关闭Softwareentitiesshouldbeopenforextension butclosedformodification 实现该原则的关键技术 抽象化从抽象层导出一个或多个新的具体类可以改变系统的行为 因此系统的设计对扩展是开放的抽象层预见了所有的可能扩展 因此 在任何扩展情况下都不会改变 这就是对改变的关闭 举例 用面向对象的方式模拟我们回家之后开灯 离开家之后关灯的过程对象家进入操作离开操作灯打开操作关闭操作 类图描述 publicvoidEnter mLight Open publicvoidLeave mLight Close publicLightlight get returnmLight set mLight value publicvoidOpen System Console WriteLine lightturnningon publicvoidClose System Console WriteLine lightturnningoff 测试 publicclassTestMain publicstaticvoidMain Roomroom newRoom Lightlight newLight room light light room entry System Console WriteLine living room leave 现在要给房子里加上电视机 程序该怎么改 类图描述 publicvoidEnter mLight Open mTV Open publicvoidLeave mLight Close mTV Close publicLightlight get returnmLight set mLight value publicTVtv 随着生活水平不断的提高 还要不停的给家里增加衣柜 计算机 使用OCP解决代码易维护 Switch预见了所有的具有打开和关闭功能的生活用品 Switch也同时允许所有具有该接口的类扩充到系统中来 Demo 演示这种设计给系统扩充带来的便利 里氏代换原则 LSP 如果对每一个类型为T1的对象O1 都有类型为T2的对象O2 使得以T1定义的所有程序P在所有的对象O1都代换成O2时 程序P的行为没有变化 那么类型T2就是T1的子类型反过来的代换是不成立的只有当子类可以替换掉基类 软件单位的功能不受影响的时候 我们才说基类真正被复用了 比如有两个类 一个是BASE类 一个是DERIVED类 并且DERIVED类是BASE类的的子类 那么一个方法可以接受一个基类对象b的话 method Baseb 那么它必然可以接受一个子类对象d即method d 举例 长方形和正方形 如果正方形是长方形的子类 那么他们之间能满足里氏替换原则吗 长方形的定义 publicclassRectangle privatelongwidth privatelongheight publicvirtualvoidsetWidth longwidth this width width publicvirtualvoidsetHeight longheight this height height publicvirtuallonggetWidth returnwidth publicvirtuallonggetHeight returnheight 正方形的定义 publicclassSquare Rectangle privatelongside publicoverridevoidsetWidth longwidth setSide width publicoverridevoidsetHeight longheight setSide height publicoverridelonggetWidth returngetSide publicoverridelonggetHeight returngetSide publicvoidsetSide longside this side side publiclonggetSide returnside SmartTest publicclassSmartTest publicstaticvoidMain Rectangler newRectangle r setWidth 10 r setHeight 5 resize r Squares newSquare s setSide 10 resize s publicstaticvoidresize Rectangler while r getHeight r getWidth r setHeight r getHeight 1 System Console WriteLine 0 1 r getHeight r getWidth 结论 resize 方法中运行Rectangle类和运行Square类的结果完全不一样 也就是说运行Rectangle类的地方并不完全适合运行所有Rectangle的子类 这种类的设计不符合LSP原则解决问题的办法 创建一个新的抽象类 强调所有子类所能做的共同行为将继承关系改写为聚集关系这些改进方法的前提是 明确知道resize方法应该不适用于Square类 解决方法之一 resize 方法只适用于Rectangle了 两个类没有父子关系了 解决方法之二 依赖倒转原则 传统的过程性系统的设计方法倾向于使高层次的模块依赖于低层次的模块 抽象层依赖于具体层次导致 战术决定战略 偶然决定必然 依赖倒转原则 将传统的过程性系统的设计倒转 抽象层次含有宏观的和重要的商务逻辑应该由抽象层决定具体层次的实现和具体算法的改变抽象层次含有战略的决策应该由抽象层决定具体层次的战术抽象层次含有必然性的选择应该由抽象层来指导具体层次的偶然性选择 依赖倒转原则 依赖倒转原则 定义 抽象不应当依赖于细节要针对接口编程 不要针对实现编程具体措施 使用接口或者抽象类型进行变量的类型声明 参量的类型声明 方法的返还类型声明以及数据类型的转换具体的类应当只实现接口或者抽象类中声明过的方法 而不应当给出多余的方法 C 对抽象类型的支持 抽象类和接口抽象类可以提供某些方法的部分实现接口则不可以一个类最多只能继承一个抽象类一个类可以继承多个接口接口是定义混合类型的理想工具混合类型指一个类具有主要的类型之外还具有其它的次要类型System Data DataSet类的主要类型是MarshalByValueComponent 而IListSource则给出其的一个次要类型 一个例子 帐号 帐号的种类和帐号的状态 Account依赖于AccountType和AccountStatus两个抽象类型 接口隔离原则 接口污染过于臃肿的接口每一个接口都代表一个角色 实现一个接口的对象 在它的整个生命周期中都扮演这个角色将角色区分清楚就是系统设计的一个重要工作不应当将几个不同的的角色都交给同一个接口 而应当交给不同的接口定义使用多个专门的接口比使用单一的总接口要好 接口隔离原则 定制服务的出现如果客户端仅仅需要某一些方法的话 那么就应当向客户端提供这些需要的方法 而不要提供不需要的方法接口隔离原则讲的就是为同一个角色提供宽 窄不同的接口 以对付不同的客户端这样做的好处 系统的可维护性量的减少向客户端提供的public接口是一种承诺 一个public接口一旦提供 就很难撤回 合成 聚合复用原则 定义在一个新的对象里面使用一些已有的对象 使之成为新对象的一部分 新的对象通过向这些对象的委派达到复用已有功能的目的要尽量使用合成 聚合 而尽量不使用继承 合成 聚合复用原则 合成和聚合的区别合成 Composition 与聚合 Aggregation 都是关联 Association 的特殊种类聚合用来表示 拥有 关系或者整体与部分的关系 是一种弱关联关系合成用来表示一种强的多得 拥有 关系 在这个关系里 部分和整体的生命周期是一样的 合成 聚合复用原则 复用的基本种类合成 聚合复用继承复用 合成 聚合复用原则 合成 聚合复用优势新对象存取成分对象的唯一方法是通过成分对象的接口黑箱复用 成份对象的内部细节是新对象所看不见的支持包装可以在运行时间内动态进行 新对象可以动态地引用与成份对象类型相同的对象缺点管理复杂不支持多态代码量大 合成 聚合复用原则 继承复用优势 新的实现较为容易 因为超类的大部分功能可以通过继承关系自动进入子类修改或扩展继承而来的实现较为容易易于管理代码量少缺点破坏包装 因为超类的实现细节暴露给了子类如果超类的实现发生改变 那么子类的实现也不得不发生改变从超类继承而来的实现是静态的 不可能在运行时间内发生改变 合成 聚合复用原则 区分 Has A 与 Is A Is A是严格的分类学意义上的定义 意思是一个类是另一个类的 一种 男人和女人是人类冒泡排序是排序程序的一种Has A表示某一个角色具有某一项责任 也就是说一个类是另一个类的一个角色 而不是另一个类的特殊种类报警器类门类报警门错误地使用继承而不是合成 聚合实现复用的一个常见原因就是错误地把 Has A 当作 Is A 报警门类是报警器类的一个角色 而不是报警器类的一个特殊种类 合成 聚合复用原则 下面的类图合理吗 错误原因 将人 Has A 角色错误的处理成 Is A 角色 迪米特法则 描述该法则的几种表述形式只与你直接的朋友们通信不要跟 陌生人 说话每一个软件单位对其他的单位都只有最少的知识 而且局限于那些与本单位密切相关的软件单位 迪米特法则 狭义的迪米特法则如果两个类不必彼此之间直接通信 那么这两个类就不应当发生直接的相互作用如果其中的一个类需要调用另一个类的某一个方法的话 可以通过第三者转发这个调用 迪米特法则 广义的迪米特法则优先考虑将一个类设置成不变类如string即使一个类必须是可变类 在给它的属性设置赋值方法的时候也要保持吝啬的态度尽量降低一个类的访问权限尽量降低成员的访问权限 迪米特法则 思考下面的两段代码从迪米特法则的角度考察 哪个更好 从迪米特法则的角度考察下面的说法你走你的阳关道 我走我的独木桥城门失火 殃及池鱼 for IEnumeratorie vec GetEmuerator vec MoveNext IEnumeratorie vec GetEmuerator while vec MoveNext
展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 图纸专区 > 课件教案


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!