HIT软件构造《设计模式》部分总结

2023-11-18

创造模式

创造模式关心的是对象类创造的过程应该遵循的原则。

里氏替换原则

继承必须确保超类所拥有的性质在子类中仍然成立

里氏替换原则(Liskov Substitution Principle,LSP)是面向对象的设计原则。通俗地讲,它指出了父类不能干的事子类也许也不能干,但父类能干的事子类必须能干。也就是说子类的规约一定要比父类强 。具体来说分为以下几个方面

  1. 子类的precondition弱于或等于父类
  2. 子类的post condition强于或等于父类
  3. 子类的异常应该与父类相等或为父类异常的子类型
例子

在面向对象编程中,正方形不是长方形的子类型,因为正方形的规约显然是强于长方形的。所以不能用正方形去继承长方形,这与大家印象中的逻辑关系是有区别的。

合成复用原则

在软件复用时,要尽量先使用组合或者聚合等关联关系来实现,其次才考虑使用继承关系来实现。

合成复用原则(Composite Reuse Principle,CRP)又叫组合/聚合复用原则(Composition/Aggregate Reuse Principle,CARP)。它也是面向对象的设计原则,为弄清这个原则表明了什么意思,我们首先得了解软件复用的方式。

软件复用

通常一个类的复用有两种实现方式:继承复用与合成复用。

  1. 继承复用:利用继承实现对父类方法的复用(需遵循LSP)。可以看到继承非常简介且易实现,但它将父类暴露给了子类,属于白盒复用,在一定程度上降低了安全性。同时由于父类与子类耦合度太高,如做修改很容易产生意想不到的后果,牵一发而动全身,灵活度不高。
  2. 合成复用:利用委托机制,利用一个待复用方法的对象来调用这个方法。也即将已有对象纳入新对象中,使之成为新对象的一部分,新对象可以调用已有对象的功能,如此达到复用的效果。可以看到这样的复用保证了类的封装性,属于黑盒复用,且复用灵活度高。

也就是说,我们应该优先用合成复用。

例子

在设计汽车类时,它拥有颜色、动力源等划分。如果使用继承复用,可以看到组合是非常多的,而且每次有一个新的颜色或动力源,就得重新创造一个类继承父类。如下图所示,这样的设计显然是不够好的。
在这里插入图片描述
而运用合成复用,通过将颜色类与动力源类封装入汽车类,可以得到划分更清晰、复用性更好的代码,如下图所示:
在这里插入图片描述

结构模式

结构模式关心的是对象类之间的结构与组成关系

适配器模式

将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类能一起工作,提供转换功能的称为适配器。

适配器模式(Adapter)是一种设计模式,它的目的是将某个类/接口转换为客户期望的其他形式,以解决接口不兼容的问题。它的关键点在于,需要开发的具有某种业务功能的组件在现有的组件库中已经存在,但它们与当前系统的接口规范不兼容,如果重新开发这些组件成本又很高,这时用适配器模式能很好地解决这些问题。

例子

用户希望输入一个长方形的左下角和右上角坐标来显示一个长方形,但接口输入却为长方形的左下角坐标与长和宽,这时候应该提供给用户一个适配器。
(这里读者应尽量说服自己:用户很难将他期望的输入方式转换为接口的输入方式,在软件构造中很多情况确实如此,尽管这个例子看起来很可笑)
在这里插入图片描述
下图为设计的适配器效果。
在这里插入图片描述

装饰模式

指在不改变现有对象结构的情况下,动态地给该对象增加一些职责(即增加其额外功能)的模式

在软件开发过程中,有时想用一些现存的组件。这些组件可能只是完成了一些核心功能。但在不改变其结构的情况下,可以动态地扩展其功能。所有这些都可以釆用装饰模式(Decorator)来实现。实现方式为将待扩展对象纳入新对象中,使之成为新对象的一部分,新对象通过委托来调用带扩展对象的基础功能,而在新对象中实现新功能。

例子

装饰模式在 Java 语言中的最著名的应用莫过于 Java I/O 标准库的设计了。例如,InputStream 的子类 FilterInputStream,OutputStream 的子类 FilterOutputStream,Reader 的子类 BufferedReader 以及 FilterReader,还有 Writer 的子类 BufferedWriter、FilterWriter 以及 PrintWriter 等,它们都是抽象装饰类。
下面代码是为 FileReader 增加缓冲区而采用的装饰类 BufferedReader 的例子,FileReader 并没有读入一行的功能,这个时候通过装饰类 BufferedReader 的装饰来扩展功能。

BufferedReader in=new BufferedReader(new FileReader("filename.txtn));
String s=in.readLine();

门面模式

通过为多个复杂的子系统提供一个一致的接口,而使这些子系统更加容易被访问的模式。

门面或外观(Facade)模式对外有一个统一接口,外部应用程序不用关心内部子系统的具体的细节,这样会大大降低应用程序的复杂度,提高了程序的可维护性。想法是很自然的,如果给用户三个或更多的接口,为什么不将这些接口封装为一个接口送给用户呢?如下图,我们只需要提供给用户房产局接口就行了。
在这里插入图片描述

例子

如下图的两个helper类,将其封装为一个HelperFacade门面类提供给用户会更方便。
在这里插入图片描述
这里可以看到使用门面可以让代码更加清晰明了且封装性更强。
在这里插入图片描述

行为模式

行为模式关心代码的功能与行为如何分配给不同的类

策略模式

定义一系列算法,并将每个算法封装起来,使它们可以相互替换,且算法的变化不会影响使用算法的客户

策略模式(Strategy)通过对算法进行封装,把使用算法的责任和算法的实现分割开来,并委派给不同的对象对这些算法进行管理。这样一来,当实现某一个功能存在多种算法或者策略,我们可以根据环境或者条件的不同选择不同的算法或者策略来完成该功能,如数据排序策略有冒泡排序、选择排序、插入排序、二叉树排序等,使client根据需要动态切换算法。

例子

这个比较好理解,我们应该给一个Strategy设计多种解决方法以便用户选择,而不是直接在Strategy中写死代码。
在这里插入图片描述

模板模式

定义一个操作中的算法骨架,而将算法的一些步骤延迟到子类中,使得子类可以不改变该算法结构的情况下重定义该算法的某些特定步骤。

模板模式(Template Method)具体是指共性的步骤在抽象类内公共实现,差异化的步骤在各个子类中实现,主要是使用继承和重写来实现模板模式。

例子

将公共部分放入OrderProcessTemplate,不同的Order实现放在不同的Order类中,通过重写来改变细微区别。
在这里插入图片描述

迭代器模式

提供一个对象来顺序访问聚合对象中的一系列数据,而不暴露聚合对象的内部表示

迭代器(Iterator)模式是指在客户访问类与聚合类之间插入一个迭代器,这分离了聚合对象与其遍历行为,对客户也隐藏了其内部细节。如 Java 中的 Collection、List、Set、Map 等都包含了迭代器。

例子

迭代器模式是很常见的模式,有的时候我们也可以自己改写迭代器来达到我们的遍历要求,也就是说迭代器模式将遍历行为与对象分离开,增强了封装性。如下图自定义迭代顺序,改写next()与hasNext():
在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

HIT软件构造《设计模式》部分总结 的相关文章

  • elasticsearch对数组进行搜索

    写在前面 我们在进行全文建搜的时候往往会添加很多前置条件 比如地区 时间 以及知识点树 我们需要在搜索之前先进行过滤在进行搜索 Array索引 es的数据类型中实际上是不包含数组类型的 在默认的情况下任何字段都可以包含0或者是更多的值 并且
  • docker配置nginx

    docker配置nginx 1 首先安装nginx镜像 docker pull nginx 安装好可以选择测试 也可以跳过 测试命令两行 docker run name nginx test p 80 80 d nginx docker s
  • OC 6702升压型恒流驱动芯片, ESOP8 封装,内置 100V 功率 MOS

    概述 OC 6702 是一款内置 100V 功率 NMOS 高效率 高精度的升压型大功率 LED 恒流驱动芯片 OC6702 采用固定关断时间的控制方 式 关断时间可通过外部电容进行调节 工作频率可根据用户要求而改变 OC6702 通过调节
  • 判断一个对象是否有空的属性值

    直接上代码 const trim str gt const newStr str 0 str str toString return newStr newStr replace s s g str 判断一个对象是否有空的属性值 const
  • 树莓派配置wifi做热点方法

    http wiki jikexueyuan com project raspberry pi wifi html
  • Java JDK8 Stream 使用详解

    Stream 流 的 筛选 去重 截取跳过映射 合并多个流 匹配 归约 简单示例 1 什么是流 2 流的特点 3 流的操作种类 4 流的操作过程 5 使用流 1 什么是流 流是Java8引入的全新概念 它用来处理集合中的数据 暂且可以把它理
  • [Err] 1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL s

    背景 想导入一个别人的项目 却发现使用navicat运行数据库批次文件时出现了错误 爆出了这样的错误 Err 1064 You have an error in your SQL syntax check the manual that c
  • uniapp的tab切换自定义组件封装

    一 创建组件 在存放组件的文件夹新建一个 vue文件 二 使用子组件
  • 并不是所有的程序员都适合做技术管理

    CSDN记者 张勇 写在之前 在CSDN博客闲逛时无意间进入一个博客 博客地址 博客里的文章质量很高 文章话题主要涉及程序员素养和管理 文章有翻译也有原创 看了几篇文章之后 突然很想和这篇博名为 呦呦鹿鸣 签名则引用孟子 穷则独善其身 达则
  • js 字符串与二维数组间的转化

    1 字符串转二维数组 var a 1 2 3 4 5 a b c d e y1 y2 y3 y4 y5 var str eval a alert str 0 3 结果 4 2 二维数组转字符串 var b 1 2 a b function
  • 云原生之使用Docker部署Dashdot服务器仪表盘

    云原生之使用Docker部署Dashdot服务器仪表盘 一 Dashdot介绍 二 检查本地系统环境 1 检查本地系统版本 2 检查docker状态 3 检查docker版本 三 下载Dashdot镜像 四 部署Dashdot应用 1 创建
  • oracle存储过程----存储过程执行简单的增删改查sql

    存储过程执行简单的增删改查sql 上一篇文章 oracle存储过程 变量的介绍及使用 PL SQL 下边是一个简单的数据库表 为了方便 我都定义成了varchar 类型 1 存储过程执行增加sql 首先写一个增加的存储过程 create o
  • MQTT学习笔记——MQTT协议使用

    http mosquitto org files source mosquitto 1 4 5 tar gz 安装出错时openssl等 需要更改 cd mosquitto 1 4vi config mk可以选择去掉SSL的功能 可以参考h
  • ES相关随手记

    ES相关随手记 一 基本操作 1 es三大属性 索引 映射 文档 1 1 索引 查看 es 中所有的索引信息 GET cat indices v 创建 索引 PUT products 创建 索引 指定库信息 PUT products set
  • 记一次关于MySQL分页查询的优化方案(聚集索引与非聚集索引)

    最近在工作中 有一段逻辑需要从一张大约70W数据的表中分页查询 最开始写的SQL是 SELECT FROM table name WHERE 1 1 ORDER BY time column DESC LIMIT 600000 10 查询时
  • 编译QT5.12.12版本WebEngine模块支持H264视频播放

    qt自带的QtWebEngine模块无法播放HTML5中的mp3 mp4 需要重新编译 提供编译好的下载 环境 QT5 12 12 VS2017 Python2 一 在64位windows系统下编译32位MSVC选择VS2017如下命令 右
  • Redis的五大数据类型(一)

    1 字符串类型 string 1 添加 查询 添加数据 set key value 如果key已存在 之前的value将会被覆盖 查询指定key的值 get key 127 0 0 1 6379 gt set name zhangsan O
  • XSS之xss-labs-level11

    文章目录 0x01 XSS Labs 0x02 实验工具 0x03 实验环境 0x04 实验步骤 0x05 实验分析 0x06 参考链接 0x01 XSS Labs XSS 跨站脚本攻击 是指恶意攻击者往Web页面里插入恶意Script代码
  • Java打印流

    java io Printstream 打印流 PrintStream为其他输出流添加了功能 使它们能够方便地打印各种数据值表示形式 Printstream特点 只负责数据的输出 不负责数据的读取 与其他输出流不同 Printstream永

随机推荐

  • Linux/Centos : gcc __attribute__关键字之visibility

    visibility用于设置动态链接库中函数的可见性 将变量或函数设置为hidden 则该符号仅在本so中可见 在其他库中则不可见 g 在编译时 可用参数 fvisibility指定所有符号的可见性 不加此参数时默认外部可见 参考man g
  • git上传文件到github

    通过git工具上传本地文件夹 1 下载git工具 2 安装 3 打开git bash exe 4 在打开的GIt Bash中输入以下命令 用户和邮箱为你github注册的账号和邮箱 git config global user name C
  • 虚拟机架云服务器,云服务器 虚拟机架设

    云服务器 虚拟机架设 内容精选 换一换 通过云服务器或者外部镜像文件创建私有镜像时 如果云服务器或镜像文件所在虚拟机的网络配置是静态IP地址时 您需要修改网卡属性为DHCP 以使私有镜像发放的新云服务器可以动态获取IP地址 本节以Windo
  • 安卓基础之Intent的用法

    Intent的用法 意图的分类和用法 隐式意图 通过指定一组数据或者动作实现 Intent intent new Intent intent setAction intent addCatogary intent setDataAndTyp
  • cim系统 是什么_CIM和IBM i:它是什么以及它如何工作

    什么是CIM 如果您对IBM i知识不熟悉CIM 那么您来对地方了 CIM提供了一种建模和公开管理信息的标准方法 从V5R4开始 通过加载IBM通用可管理性启用 UME 许可程序 在IBM i上提供了CIM 并且在IBM i 6 1和IBM
  • JavaScript 等待 body,frame,frameset,iframe,img,link,script,style加载完成操作

    body frame frameset iframe img link script style 标签有 onload事件 通过监听以上的 onload事件 可以达到 对于标签加载完成后在做一些事情 查看图片的所有属性 以及事件 conso
  • uniapp的那些坑

    1 selectedColor不起作用 1 查看位置是否写对 与lis同级 2 是否为16进制 selectedColor写的rgb不支持 3 是否被其他样式覆盖 其他地方也设置过selectedColor 可以全局搜索一下 2 pages
  • VSCode远程连接ubuntu服务器

    1 打开VSCode 安装插件 安装插件 汉化 方法如下 重启之后界面就都是中文了 因为我之前弄过了 如果你的已经是中文了 可以省去这一步 安装remote development插件 如下图 用于远程连接服务器 安装好之后 左侧多了一个
  • 计算机视觉(CV)方向今年招聘情况怎么样?是否已经人才过剩?

    编辑 Amusi https www zhihu com question 293700785 本文仅作为学术分享 如果侵权 会删文处理 计算机视觉 CV 方向今年招聘情况怎么样 是否已经人才过剩 https www zhihu com q
  • 实验五:LINUX 下C语言使用、编译与调试实验

    实验五 LINUX 下C语言使用 编译与调试实验 一 实验目的 练习并掌握Linux提供的vi编辑器来编译C程序 学会利用gcc gdb编译 调试C程序 学会使用make工具 二 实验内容 编写C语言程序 用gcc编译并观察编译后的结果 运
  • 接口的加密解密

    接口加密 1 接口参数加密 基础加密 2 接口参数加密 接口时效性验证 一般达到这个级别已经非常安全了 3 接口参数加密 时效性验证 私钥 达到这个级别安全性固若金汤 4 接口参数加密 时效性验证 私钥 Https 我把这个级别称之为金钟罩
  • iOS进阶_NSURLSession(二.断点续传)

    断点续传 从上一篇文章中 我们了解了使用NSURLSession进行文件下载 我们在其基础上继续探索NSURLSession的断点续传 在NSURLSession中 我们使用reumeData来存储下载的数据进度 import ViewCo
  • kali linux 报告工具集 faraday 忘记密码处理办法

    kali linux 报告工具集 faraday 忘记密码处理办法 第一步 切换到root 用户 执行命令 su root 第二步停止数据库服务 systemctl stop postgresql service 第三步重新启动数据库 sy
  • KMP 算法

    KMP 算法的核心是利用匹配失败后的信息 尽量减少模式串与主串的匹配次数以达到快速的匹配的目的 具体实现是通过一个next 函数来实现的 函数本身包含了模式串的局部匹配信息 KMP算法的时间复杂度O m n KMP 和 BF 唯一不一样的地
  • Pycharm如何配置解释器

    问题 安装Pycharm了就可以直接运行程序了吗 回答 不能 PyCharm是一种Python IDE 带有一整套可以帮助用户在使用Python语言开发时提高其效率的工具 比如调试 语法高亮 Project管理 代码跳转 智能提示 自动完成
  • python-自定义函数(定义调用、默认参数、返回值)

    python 自定义函数 文章目录 python 自定义函数 初识函数 函数的定义与调用 函数的定义 参数列表 函数体 函数调用 默认参数 定义默认参数 默认参数的使用 默认参数的位置 默认参数为可变对象 默认参数为None 关键字参数传递
  • Linux系统管理-audit文件太多导致du -sh命令卡死

    1 问题现象 今日查询数据库文件系统的使用情况发现如下情况 du sh 卡死 进去下基层目录使用du sh 均未出现问题 2 问题分析 而在audit文件目录中使用du sh 命令时命令卡死 发现问题所在 使用ls查看audit目录的文件也
  • zsh: bad CPU type in executable: /usr/local/bin/git

    MAC安装nvm的时候报错zsh bad CPU type in executable usr local bin git 查找原因 通过where git可以看到有2个路径 一个 usr bin git一个 usr bin local g
  • 虚拟机--无法连接网络

    情况 运行命令 ifconfig 没有看到 ens33 网络 命令 ifconfig a 可以看到 ens33 其他 关闭防火墙 systemctl stop firewalld 查看状态 systemctl status firewall
  • HIT软件构造《设计模式》部分总结

    创造模式 创造模式关心的是对象类创造的过程应该遵循的原则 里氏替换原则 继承必须确保超类所拥有的性质在子类中仍然成立 里氏替换原则 Liskov Substitution Principle LSP 是面向对象的设计原则 通俗地讲 它指出了