《图解设计模式》笔记(一)适应设计模式
图灵社区 - 图解设计模式 - 随书下载
评论区
雨帆 2017-01-11 16:14:04
对于设计模式,我个人认为,其实代码和设计原则才是最好的老师。理解了 SOLID,如何 SOLID,自然而然地就用起来设计模式了。Github 上有一个 tdd-training,里面就是教你如何设计重构的。换句话说,此书可能不是很推荐。
设计模式的学习还是要靠 kata 练习
https://github.com/Pragmatists/tdd-trainings
一、Iterator模式:一个一个遍历
示例程序类图
public static void main(String[] args) {BookShelf bookShelf = new BookShelf(4);bookShelf.appendBook(new Book("Around the World in 80 Days"));bookShelf.appendBook(new Book("Bible"));bookShelf.appendBook(new Book("Cinderella"));bookShelf.appendBook(new Book("Daddy-Long-Legs"));Iterator it = bookShelf.iterator();while (it.hasNext()) {Book book = (Book)it.next();System.out.println(book.getName());}
}
角色
-
Iterator(迭代器)
定义按顺序逐个遍历元素的接口(APl)。
在示例程序中,Iterator接口扮演这个角色,它定义了两个方法:hasNext(判断是否存在下一个元素)和next(获取该元素)。
-
Concretelterator(具体的迭代器)
负责实现Iterator角色所定义的接口(API)。
在示例程序中,BookShelfIterator类扮演这个角色。该角色中包含了遍历集合所必需的信息。
在示例程序中,BookShelf类的实例保存在bookShelf字段中,被指向的书的下标保存在index字段中。
-
Aggregate(集合)
负责定义创建Iterator角色的接口(API)。这个接口(API)是一个方法,会创建出”按顺序访问保存在我内部元素的人“。
在示例程序中,Aggregate接口扮演这个角色,它里面定义了iterator方法。
-
ConcreteAggregate(具体的集合)
负责实现Aggregate角色所定义的接口(API)。它会创建出具体的Iterator角色,即Concretelterator角色。
在示例程序中,由BookShelf类扮演这个角色,它实现了iterator方法
扩展思路的要点
不管实现如何变化,都可以使用lterator
不用for循环,而使用Iterator模式的一个重要的理由:引入Iterator后可以将遍历与实现分离开来。
请看下面的代码。
while (it.hasNext()) {Book book =(Book)it.next();System.out.println(book.getName());
}
这里只使用了Iterator
的hasNext()
和next()
,并没有调用BookShelf
的方法。
即:这里的while循环并不依赖于BookShelf的实现。
那么管理书本就可以不用数组,可以换成java.util.Vector
和ArrayList
等别的形式。
不管BookShelf如何变化,只要BookShelf的iterator方法能正确地返回Iterator的实例就行,对于BookShelf的调用者很友好。
设计模式的作用就是帮助我们编写可复用的类。
所谓“可复用”,就是指将类实现为“组件”,当一个组件发生改变时,不需要对其他的组件进行修改或是只需要很小的修改即可应对。
难以理解抽象类和接口
不要只使用具体的类来解决问题,很容易导致类之间的强耦合,这些类也难以作为组件被再次利用。
为了弱化类之间的耦合,进而使得类更加容易作为组件被再次利用,我们需要引入抽象类和接口。
Aggregate 和 Iterator 的对应
如何把BookShelfIterator类定义为BookShelf类的Concretelterator角色的:BookShelfIterator类知道BookShelf是如何实现的。因此,我们才能调用用来获取下一本书的getBookAt方法。
也就是说,如果BookShelf的实现发生了改变,即getBookAt方法这个接口(API)发生变化时,必须修改BookShelfIterator类。
正如Aggregate和Iterator这两个接口对应的一样,concreteAggregate和ConcreteIterator这两个类也是对应的。
多个 Iterator
“将遍历功能置于Aggregate角色之外”是Iterator模式的一个特征。根据这个特征,可以针对一个ConcreteAggregate角色编写多个Concretelterator角色。
迭代器的种类多种多样
在示例程序中展示的Iterator类只是很简单地从前向后遍历集合。可以改成从后向前、双向遍历、根据条件跳跃式遍历等。
不需要 deletelterator
在Java中,没有被使用的对象实例将会自动被删除(垃圾回收,GC)。因此,在iterator中不需要与其对应的deleteIterator方法。
相关的设计模式
Visitor模式(第13章)
Iterator模式是从集合中逐个取出元素进行遍历,但并没有在Iterator接口中声明对取出的元素进行何种处理。
Visitor模式则是在遍历元素集合的过程中,对元素进行相同的处理。
Composite模式(第11章)
Composite模式是具有递归结构的模式,在其中使用Iterator模式比较困难。
Factory Method模式(第4章)
在iterator方法中生成Iterator的实例时可能会使用Factory Method模式。
二、Adapter模式:加个“适配器”以便于复用
示例程序类图
继承的方式
委托的方式
public static void main(String[] args) {Print p = new PrintBanner("Hello");p.printWeak();p.printStrong();
}
角色
-
Target(对象)
负责定义所需的方法。
类比让笔记本电脑正常工作所需的直流12伏特电源。
在示例程序中,由Print接口(使用继承时)和Print类(使用委托时)扮演此角色。
-
Client(请求者)
负责使用Target 角色所定义的方法进行具体处理。
类比直流12伏特电源所驱动的笔记本电脑。
在示例程序中,由Main类扮演此角色。
-
Adaptee(被适配)
注意不是Adapt-er(适配)角色,而是Adapt-ee(被适配)角色。
Adaptee是一个持有既定方法的角色。
类比交流220伏特电源。
在示例程序中,由Banner类扮演此角色。
如果Adaptee角色中的方法与Target角色的方法相同(也就是说家庭使用的电压就是12伏特直流电压),就不需要接下来的Adapter角色了。
-
Adapter(适配)
Adapter模式的主人公。使用Adaptee角色的方法来满足Target角色的需求,这是Adapter模式的目的,也是Adapter角色的作用。
类比将交流100伏特电压转换为直流12伏特电压的适配器。
在示例程序中,由PrintBanner类扮演这个角色。
在类适配器模式中,Adapter角色通过继承来使用Adaptee角色,而在对象适配器模式中,Adapter角色通过委托来使用Adaptee角色。
拓展思路的要点
什么时候使用Adapter模式
如果某个方法就是我们所需要的方法,那么直接在程序中使用不就可以了吗?为什么还要考虑使用Adapter模式呢?
很多时候,我们并非从零开始编程,经常会用到现有的类。特别是当现有的类已经被充分测试过了,Bug很少,而且已经被用于其他软件之中时,我们更愿意将这些类作为组件重复利用。
Adapter模式会对现有的类进行适配,生成新的类。通过该模式可以很方便地创建我们需要的方法群。
当出现Bug时,由于我们很明确地知道Bug不在现有的类(Adaptee角色)中,所以只需调查扮演Adapter角色的类即可,方便排查代码问题。
如果没有现成的代码
使用Adapter模式可以在完全不改变现有代码的前提下使现有代码适配于新的接口(API)。
此外,在Adapter模式中,并非一定需要现成的代码。只要知道现有类的功能,就可以编写出新的类。
版本升级与兼容性
版本升级时常会出现“与旧版本的兼容性”问题。现实中往往很难完全抛弃旧版本。
这时,可以使用Adapter模式使新旧版本兼容,以便同时维护新版本和旧版本。
例如,假设我们今后只想维护新版本。这时可以让新版本扮演Adaptee角色,旧版本扮演Target角色。接着编写一个扮演Adapter角色的类,让它使用新版本的类来实现旧版本的类中的方法。
功能完全不同的类
当然,当Adaptee角色和Target角色的功能完全不同时,Adapter模式是无法使用的。就如同我们无法用交流100伏特电压让自来水管出水一样。
相关的设计模式
Bridge模式(第9章)
Adapter模式用于连接接口(API)不同的类,而Bridge模式则用于连接类的功能层次结构与实现层次结构。
Decorator模式(第12章)
Adapter模式用于填补不同接口(API)之间的缝隙,而 Decorator模式则是在不改变接口(API)的前提下增加功能。
相关文章:
![](https://img-blog.csdnimg.cn/direct/0f81360553fe473f9c7bcaf5e3aa21e9.png#pic_center)
《图解设计模式》笔记(一)适应设计模式
图灵社区 - 图解设计模式 - 随书下载 评论区 雨帆 2017-01-11 16:14:04 对于设计模式,我个人认为,其实代码和设计原则才是最好的老师。理解了 SOLID,如何 SOLID,自然而然地就用起来设计模式了。Github 上有一个 tdd-training&…...
![](https://img-blog.csdnimg.cn/direct/04fa76db49bc4d068bd4cf37ee03856a.png)
图文说明Linux云服务器如何更改实例镜像
一、应用场景举例 在学习Linux的vim时,我们难免要对vim进行一些配置,这里我们提供一个vim插件的安装包: curl -sLf https://gitee.com/HGtz2222/VimForCpp/raw/master/install.sh -o./install.sh && bash ./install.sh 但是此安装包…...
![](https://img-blog.csdnimg.cn/20210109141525666.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzMyMjM4NjEx,size_16,color_FFFFFF,t_70)
RabbitMQ学习整理————基于RabbitMQ实现RPC
基于RabbitMQ实现RPC 前言什么是RPCRabbitMQ如何实现RPCRPC简单示例通过Spring AMQP实现RPC 前言 这边参考了RabbitMQ的官网,想整理一篇关于RabbitMQ实现RPC调用的博客,打算把两种实现RPC调用的都整理一下,一个是使用官方提供的一个Java cli…...
![](https://img-blog.csdnimg.cn/direct/c99b1b8a9493499f8fa3bbce63569c18.png)
Linux-基础知识(黑马学习笔记)
硬件和软件 我们所熟知的计算机是由:硬件和软件组成。 硬件:计算机系统中电子,机械和光电元件等组成的各种物理装置的总称。 软件:是用户和计算机硬件之间的接口和桥梁,用户通过软件与计算机进行交流。 而操作系统…...
![](https://img-blog.csdnimg.cn/img_convert/38c081dbe62aae2a8cc9056272b468ab.png)
SpringBoot项目启动报java.nio.charset.MalformedInputException Input length = 1解决方案
报错详情 SpringBoot启动报错java.nio.charset.MalformedInputException: Input length 1 报错原因 出现这个的原因,就是解析yml文件时,中文字符集不是utf-8的原因,这是maven在项目编译时,默认字符集编码是GBK。 解决方式 检…...
![](https://img-blog.csdnimg.cn/direct/cfd1d8a3e37a465ea6965f4874735e4b.png)
【Unity2019.4.35f1】配置JDK、NDK、SDK、Gradle
目录 JDK NDK SDK 环境变量 Gradle JDK JDK:jdk-1.8版本Java Downloads | Oracle 下载要登录,搜索JDK下载公用账号:Oracle官网 JDK下载 注册登录公共账号和密码_oracle下载账号-CSDN博客 路径:C:\Program Files\Java\jd…...
![](https://www.ngui.cc/images/no-images.jpg)
MySQL中的高级查询
通过条件查询可以查询到符合条件的数据,但如同要实现对字段的值进行计算、根据一个或多个字段对查询结果进行分组等操作时,就需要使用更高级的查询,MySQL提供了聚合函数、分组查询、排序查询、限量查询、内置函数以实现更复杂的查询需求。接下…...
![](https://www.ngui.cc/images/no-images.jpg)
leetcode383赎金信
用字符数组ch来记录magazine每个字母出现频率,用ransomNote的字母减去字符数组ch对应的字符出现频率,如果该字符对应的频率小于0,则不够,无法组成ransomNote! class Solution { public:bool canConstruct(string rans…...
![](https://img-blog.csdnimg.cn/direct/4feb89973ba24add86d3885f79ab2de0.png)
【Unity3D】ASE制作天空盒
找到官方shader并分析 下载对应资源包找到\DefaultResourcesExtra\Skybox-Cubed.shader找到\CGIncludes\UnityCG.cginc观察变量, 观察tag, 观察代码 需要注意的内容 ASE要处理的内容 核心修改 添加一个Custom Expression节点 code内容为: return DecodeHDR(In0, In1);outp…...
![](https://img-blog.csdnimg.cn/direct/911a6f63d1c5499ebde51c8ff799266c.png)
MyBatisPlus常用注解
目录 一、TableName 二、TableId 三、TableField 四、TableLogic 一、TableName 在使用MyBatis-Plus实现基本的CRUD时,我们并没有指定要操作的表,只是在Mapper接口继承BaseMapper时,设置了泛型User,而操作的表为user表 由此得出…...
![](https://www.ngui.cc/images/no-images.jpg)
Putty中运行matlab文件
首先使用命令 cd /home/ya/CodeTest/Matlab进入路径:到Matlab文件夹下 然后键入matlab,进入matlab环境,如果main.m文件在Matlab文件夹下,直接键入main即可运行该文件。细节代码如下: Unable to use key file "y…...
![](https://img-blog.csdnimg.cn/direct/c3b0a9f181d84fbfb66244147908fad6.png)
ES6 | (一)ES6 新特性(上) | 尚硅谷Web前端ES6教程
文章目录 📚ES6新特性📚let关键字📚const关键字📚变量的解构赋值📚模板字符串📚简化对象写法📚箭头函数📚函数参数默认值设定📚rest参数📚spread扩展运算符&a…...
![](https://img-blog.csdnimg.cn/direct/a97ccad548e6481c97833b5c623b75d4.png)
生产环境下,应用模式部署flink任务,通过hdfs提交
前言 通过通过yarn.provided.lib.dirs配置选项指定位置,将flink的依赖上传到hdfs文件管理系统 1. 实践 (1)生产集群为cdh集群,从cm上下载配置文件,设置环境 export HADOOP_CONF_DIR/home/conf/auth export HADOOP_CL…...
![](https://img-blog.csdnimg.cn/direct/62e73a30ca574bf1aac93cd3e9d309cc.png)
【lesson59】线程池问题解答和读者写者问题
文章目录 线程池问题解答什么是单例模式什么是设计模式单例模式的特点饿汉和懒汉模式的理解STL中的容器是否是线程安全的?智能指针是否是线程安全的?其他常见的各种锁 读者写者问题 线程池问题解答 什么是单例模式 单例模式是一种 “经典的, 常用的, 常考的” 设…...
![](https://www.ngui.cc/images/no-images.jpg)
【LeetCode每日一题】单调栈316去除重复字母
题目:去除重复字母 给你一个字符串 s ,请你去除字符串中重复的字母,使得每个字母只出现一次。需保证 返回结果的字典序最小(要求不能打乱其他字符的相对位置)。 示例 1: 输入:s “bcabc” 输…...
![](https://img-blog.csdnimg.cn/direct/08fc05b6034f4cadab1ae2d8d790c418.png)
【Git】Gitbash使用ssh 上传本地项目到github
SSH Git上传项目到GitHub(图文)_git ssh上传github-CSDN博客 前提 ssh-keygen -t rsa -C “自己的github电子邮箱” 生成密钥,公钥保存到自己的github的ssh里 1.先创建一个仓库,复制ssh地址 git init git add . git commit -m …...
![](https://img-blog.csdnimg.cn/direct/954074786a82467893a11dee7dff5910.png)
activeMq将mqtt发布订阅转成消息队列
1、activemq.xml置文件新增如下内容 2、mqttx测试发送: 主题(配置的模糊匹配,为了并发):VirtualTopic/device/sendData/12312 3、mqtt接收的结果 4、程序处理 package comimport cn.hutool.core.date.DateUtil; imp…...
![](https://www.ngui.cc/images/no-images.jpg)
Go语言教程
一、引言 Go(又称Golang)是由Google开发的一种静态类型、编译型的开源编程语言。它旨在提供简单、快速和可靠的软件开发体验。Go语言结合了动态语言的开发效率和静态语言的安全性能,特别适用于网络编程、系统编程和并发编程。本教程将介绍Go…...
![](https://img-blog.csdnimg.cn/direct/f16378d3b5594012806012a33833cbad.png)
分布式锁的应用场景及实现
文章目录 分布式锁的应用场景及实现1. 应用场景2. 分布式锁原理3. 分布式锁的实现3.1 基于数据库 分布式锁的应用场景及实现 1. 应用场景 电商网站在进行秒杀、特价等大促活动时,面临访问量激增和高并发的挑战。由于活动商品通常是有限库存的,为了避免…...
![](https://img-blog.csdnimg.cn/direct/3536c11f75514f7bbce04d9bedd52906.png)
嵌入式Linux中apt、apt-get命令用法汇总
在Linux环境开发过程中接触ubuntu虚拟机时,在安装软件或者更新软件时apt和apt-get命令使用相对较频繁,下面对这两个命令的用法进行汇总。 apt(Advanced Package Tool)和 apt-get 是用于在基于 Debian 的 Linux 发行版中进行软件包…...
![](https://img-blog.csdnimg.cn/direct/1971a814d76a454caf513766c43acc47.png#pic_center)
Unity之ShaderGraph如何实现水面波浪
前言 这几天通过一个水的波浪数学公式,实现了一个波浪效果,感觉成就感满满,下面给大家分享一下 首先先给大家看一下公式; 把公式转为ShaderGraph 第一行公式:waveType = z*-1*Mathf.Cos(wave.WaveAngle/360*2*Mathf.PI)+x*Mathf.Sin(WaveAngle/360*-2*Mathf.PI) 转换…...
![](https://img-blog.csdnimg.cn/direct/0160862e8ce8484d8777d8648d7985e8.png#pic_center)
无线局域网(WLAN)简单概述
无线局域网 无线局域网概述 无限局域网(Wireless Local Area Network,WLAN)是一种短距离无线通信组网技术,它是以无线信道为传输媒质构成的计算机网络,通过无线电传播技术来实现在空间传输数据。 WLAN是传输范围在1…...
![](https://img-blog.csdnimg.cn/direct/686090334d9d4da7867b34d2ac76930d.png)
学习数仓工具 dbt
DBT 是一个有趣的工具,它通过一种结构化的方式定义了数仓中各种表、视图的构建和填充方式。 dbt 面相的对象是数据开发团队,提供了如下几个最有价值的能力: 支持多种数据库通过 select 来定义数据,无需编写 DML构建数据时&#…...
![](https://img-blog.csdnimg.cn/img_convert/27a471ac440908c9c433584a913535d5.png)
高录用快见刊【最快会后两个月左右见刊】第三届社会科学与人文艺术国际学术会议 (SSHA 2024)
第三届社会科学与人文艺术国际学术会议 (SSHA 2024) 2024 3rd International Conference on Social Sciences and Humanities and Arts *文章投稿均可免费参会 *高录用快见刊【最快会后两个月左右见刊】 重要信息 会议官网:icssha.com 大会时间:202…...
![](https://img-blog.csdnimg.cn/direct/800ed7d539d4407aad2bed12339d45e8.jpeg)
C语言-指针初学速成
1.指针是什么 C语言指针是一种特殊的变量,用于存储内存地址。它可以指向其他变量或者其他数据结构,通过指针可以直接访问或修改存储在指定地址的值。指针可以帮助我们在程序中动态地分配和释放内存,以及进行复杂的数据操作。在C语言中&#…...
![](https://www.ngui.cc/images/no-images.jpg)
MQL语言实现单元测试
文章目录 一、单元测试是什么二、单元测试的过程三、为什么需要单元测试四、MQL测试代码实现 一、单元测试是什么 单元测试是对软件中最小可测单元(如类或函数)进行独立验证和检查的过程。它是由开发工程师完成的,旨在确保每个单元的功能和逻…...
![](https://img-blog.csdnimg.cn/direct/27f727e5f7634cbfadf88eb33a7c60e0.png)
Redis信创平替之TongRDS(东方通),麒麟系统安装步骤
我的系统: 银河麒麟桌面系统V10(SP1)兆芯版 1.先进入东方通申请使用 2.客服会发送一个TongRDS包与center.lic给你(我这里只拿到.tar.gz文件,没有网上的什么安装版) 3.上传全部文件到目录中 4.服务节点安装,并启动 tar -zxvf TongRDS-2.2.1.2_P3.Node.tar.gz cd pmemdb/bin/…...
![](https://img-blog.csdnimg.cn/direct/55cc4a1b3ea842a988319cb103e88ea3.jpeg)
nginx服务
“欢唱吧,呼唤它,回来啊~” Web服务器简介 Web服务器,一般是指“网站服务器”,其本质就是驻留于互联网中,某一台机器(计算机)上的进程(程序)。Web服务器通常就是为用户提供信息浏览服务,更可以放置数据文件…...
![](https://img-blog.csdnimg.cn/direct/116b1554b77e41e4a0f962f6f656f027.png)
多数pythoneer只知有列表list却不知道python也有array数组
数组和列表 Python中数组和列表是不同的,我敢断言大多数的pythoneer只知道有列表list,却不知道python也有array数组。列表是一个包含不同数据类型的元素集合,而数组是一个只能含相同数据类型的元素集合。 Python的array库是一个提供数组操作…...
![](https://www.ngui.cc/images/no-images.jpg)
【Rust】——控制流(if-else,循环)
🎃个人专栏: 🐬 算法设计与分析:算法设计与分析_IT闫的博客-CSDN博客 🐳Java基础:Java基础_IT闫的博客-CSDN博客 🐋c语言:c语言_IT闫的博客-CSDN博客 🐟MySQL:…...
![](/images/no-images.jpg)
四川润邦建设工程设计有限公司网站/电商seo
/** 切片函数,非常重要,这里一定要牢记beginIndex是开始位置,endIndex是结束位置,区别于以前学的offset是开始位置,而count或length是个数和长度* 比如说,new String("abcdefg",1,3)得到的是bcd*…...
![](/images/no-images.jpg)
备案后修改网站名称/一点优化
堆和栈是两种内存分配的统称。 一.栈 栈会存放函数的局部变量,函数的返回地址等。栈有"LIFO"(后进先出)的特点。栈由操作系统分配,自动回收.栈的大小受到限制。在x86体系下,栈一般通过esp 指向栈帧顶部,ebp指向底部不…...
![](https://img-blog.csdnimg.cn/31c6375c206f48b8aeb9fdd90e8f902e.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6Iqd6bq75byA6ZeoMjAxNQ==,size_17,color_FFFFFF,t_70,g_se,x_16)
做愛視頻网站/seo流量的提升的软件
前段时间配置Java环境 将Path配置错误了 计算机 右键点击属性 高级系统设置 ->环境变量 系统变量 编辑Path 添加语句 ;C:\Windows\System32 重新打开cmd ping www.baidu.com netstat -a 出现上图 表示配置成功...
![](/images/no-images.jpg)
网站接入查询/seo优化推广业务员招聘
《信息技术试讲《计算机信息加工的一般过程》教案》由会员分享,可在线阅读,更多相关《信息技术试讲《计算机信息加工的一般过程》教案(4页珍藏版)》请在人人文库网上搜索。1、信息技术试讲计算机信息加工的一般过程教案一、教学目标【知识与技能】理解信…...
![](/images/no-images.jpg)
电子商务网站制作/郑州网站定制
一、事务的基本原理Spring事务 的本质其实就是数据库对事务的支持,没有数据库的事务支持,spring是无法提供事务功能的。对于纯JDBC操作数据库,想要用到事务,可以按照以下步骤进行: 获取连接 Connection con Driver…...
![](https://images2015.cnblogs.com/blog/1110462/201704/1110462-20170410140340297-485596952.png)
网页设计与网站规划/磁力搜索器 磁力猫
1.flume是分布式的日志收集系统,把收集来的数据传送到目的地去。2.flume里面有个核心概念,叫做agent。agent是一个java进程,运行在日志收集节点。通过agent接收日志,然后暂存起来,再发送到目的地。3.agent里面包含3个核…...