3.4 在开发中使用设计模式
现在,我们应该对设计模式的本质以及它们的组织方式有了初步的认识,并且能够理解ROPES过程在整体设计中的作用。通过之前章节对“体系结构”及其五个视图的探讨,我们打下了坚实的基础。初步了解了UML的基本构建模块后,我们现在可以开始深入学习本书介绍的模式,并探讨如何将它们应用到我们的应用开发工作中。接下来,让我们简要讨论一下如何在日常工作中有效地运用这些设计模式。
首先,我们需要了解模式的适用范围。模式一般适用于以下场景:
- 解决具有相似问题的设计问题
- 提高系统的可重用性、可扩展性、可维护性等
- 提高系统的性能、安全性等
3.4.1 模式孵化:找到正确的模式

当我们面临设计问题时,如何找到解决这个特定问题的模式呢?图3.10给出了本书推荐的多步方法。
1. 熟悉模式
在开始设计之前,你必须熟悉有关模式的各种文献。有许多书籍、文章、网站都讨论了模式在各个领域的应用。本书只介绍了一部分,其他的模式可查参考文献。一旦你掌握了更多的模式词条,特别是和你的应用域密切相关的模式词条,面对设计挑战时,就有了更多智力弹药。
2. 学会思考
“学会思考”是指刻画你面临的设计问题的本质。问题的范围是什么?是做体系结构、某个机制,还是详细设计?最切题的服务质量问题是什么?是性能、可复用性、安全性、可移植性,还是内存使用?将这些按紧要程度分类。有时一旦你做了这一步,本身可能暗示某种设计的解决方案。
3. 模式匹配
模式匹配是指将你的设计问题与已知的模式进行比较,寻找相似之处。这是很好玩的一步。大脑皮层是一架奇妙的模式匹配机,它按学会的思考自动运作处理。这是你在洗澡、睡觉、吃饭时随时都可能体验到“我知道了!”的原因。一旦会用“学会思考”的步骤,你的模式匹配机就有足够的信息下意识地连续运作。
4. 奇迹发生
在设计模式的实践中,“奇迹发生”时刻是一个标志性的转折点。此时,经过一系列的模式匹配努力,我们终于捕捉到了一个潜在的解决策略。这个策略可能并不完美,也许未曾明确地形成通用的解决方案,但它与我们期望的特性紧密相连,为未来的发展和迭代提供了一个有希望的起点。
5. 评估解决方案
你需要评估它是否可行。这包括考虑模式的适用性、解决方案的完整性和可靠性等因素。如果这个解决方案很好,转向步骤6,采用它;如果不好,在澄清以后转向步骤3,甚至转向步骤2。
6. 实例化模式
实例化模式是指将模式的抽象概念转化为具体的设计元素。这包括拆开、合并对象,重新派定协作的职责,或引入新的元素补全等。
7. 测试解决方案
在实例化模式后,你需要测试解决方案是否满足需求。这包括用协作元素再现分析场景,证实它们是否满足功能和行为需求。一旦你满意协作做的事,就可度量所希望的服务质量,如有必要,还需保证这些模式能达到你的服务质量目标。性能和资源利用目标更应如此。

3.4.2 模式挖掘:打磨出自己的模式
创建自己的模式是一种非常有用的设计技巧,尤其是当你对某个特定领域的优化问题有了深刻的体验和理解,对解决方案的一般性质有了足够广泛的理解,足以将它们抽象为泛化的解决方案时。我们把这称为模式挖掘。
模式挖掘并不是多么了不起的发明创造,它只是简单地将在某个上下文中的解决方案与另一个上下文中的解决方案进行比较,找出它们的相似之处,并抽象出这些相似之处。
要想做出一个有用的模式,它必须满足以下条件:
- 它必须能够在不同的上下文中重复使用。
- 它必须能够为一个或多个服务质量带来有用的改进。
3.4.3 模式实例化:在设计中运用模式
模式实例化是模式挖掘的逆过程。它将模式应用于某个特定的协作,以发挥模式的效益。
模式通常用于对象协作。协作是对象的集合。协作的范围可以很大或很小,小到底层对象,达到子系统和构件。模式实例化的目的是用模式来组织已经存在的协作方案,或者对其进行改进。
在设计中应用或实例化模式,就是定义元素来满足协作中的角色。对于某些模式,可以创建超类来表示角色,然后再使用子类来实例化模式。对于另一些模式,可以使用应用域中的某些元素来替换模式元素,并添加所需的操作和行为。还可以选择性地创建某些对象,就像它们存在于模式中一样。

相关文章:
3.4 在开发中使用设计模式
现在,我们应该对设计模式的本质以及它们的组织方式有了初步的认识,并且能够理解ROPES过程在整体设计中的作用。通过之前章节对“体系结构”及其五个视图的探讨,我们打下了坚实的基础。初步了解了UML的基本构建模块后,我们现在可以…...
docker搭建SSH镜像、systemctl镜像、nginx镜像、tomcat镜像
目录 一、SSH镜像 二、systemctl镜像 三、nginx镜像 四、tomcat镜像 五、mysql镜像 一、SSH镜像 1、开启ip转发功能 vim /etc/sysctl.conf net.ipv4.ip_forward 1sysctl -psystemctl restart docker 2、 cd /opt/sshd/vim Dockerfile 3、生成镜像 4、启动容器并修改ro…...
[linux] git clone一个repo,包括它的子模块submodule
How do I "git clone" a repo, including its submodules? - Stack Overflow git clone git://github.com/foo/bar.git cd bar git submodule update --init --recursive...
K8S中使用helm安装MinIO
注意事项 使用helm部署MinIO分为两部分 helm部署MinIO operator,用来管理tenant(K8S集群中只能部署一个)helm部署MinIO tenant,真实的MinIO Cluster(K8S集群中可以部署多个) 使用helm部署到K8S集群&…...
寒假刷题第六天
PTA甲级 1030 Travel Plan 迪杰斯特拉 #include<iostream> #include<vector> #include<cstring>using namespace std;const int N 510 , INF 0x3f3f3f3f3f; int n , m , s , d; int g[N][N] , cost[N][N] , dist[N] , min_cost[N]; bool st[N]; int pat…...
深度学习笔记(七)——基于Iris/MNIST数据集构建基础的分类网络算法实战
文中程序以Tensorflow-2.6.0为例 部分概念包含笔者个人理解,如有遗漏或错误,欢迎评论或私信指正。 截图和程序部分引用自北京大学机器学习公开课 认识网络的构建结构 在神经网络的构建过程中,都避不开以下几个步骤: 导入网络和依…...
Windows启动MongoDB服务报错(错误 1053:服务没有及时响应启动或控制请求)
问题描述:修改MongoDB服务bin目录下的mongod.cfg,然后在任务管理器找到MongoDB服务-->右键-->点击【开始】,启动失败无提示: 右键点击任务管理器的MongoDB服务-->点击【打开服务】,跳转到服务页面-->找到M…...
Android Framework 常见解决方案(25-2)定制CPUSET解决方案-system修改及编译部分调整
1 原理说明 这个方案有如下基本需求: 构建自定义CPUSET,/dev/cpuset中包含一个全新的cpuset分组。且可以通过set_cpuset_policy和set_sched_policy接口可以设置自定义CPUSET。开机启动后可以通过zygote判定来对特定的应用进程设置CPUSET,并…...
OpenAI推出GPT商店和ChatGPT Team服务
🦉 AI新闻 🚀 OpenAI推出GPT商店和ChatGPT Team服务 摘要:OpenAI正式推出了其GPT商店和ChatGPT Team服务。用户已经创建了超过300万个ChatGPT自定义版本,并分享给其他人使用。GPT商店集结了用户为各种任务创建的定制化ChatGPT&a…...
3D建模素材分层渲染怎么操作?
在3D建模素材分层渲染过程中,需要将场景中的元素分到不同的层里,然后分别进行渲染。以下是一个简单的方法: 1、打开要渲染的3D建模素材。 2、在场景中选择要分层的元素,然后在软件的图层面板中新建图层,将元素拖拽到新…...
SAICP(模拟退火迭代最近点)的实现
SAICP(模拟退火迭代最近点)的实现 注: 本系列所有文章在github开源, 也是我个人的学习笔记, 欢迎大家去star以及fork, 感谢! 仓库地址: pointcloud-processing-visualization 总结一下上周的学习情况 ICP会存在局部最小值的问题, 这个问题可能即使是没有实际遇到过, 也或多…...
FineBI实战项目一(23):订单商品分类词云图分析开发
点击新建组件,创建订单商品分类词云图组件。 选择词云,拖拽catName到颜色和文本,拖拽cat到大小。 将组件拖拽到仪表板。 结果如下:...
DOS命令
当使用DOS命令时,可以在命令提示符下输入各种命令以执行不同的任务。以下是一些常见DOS命令的详细说明: dir (Directory): 列出当前目录中的文件和子目录。 用法: dir [drive:][path][filename] [/p] [/w] cd (Change Directory): 更改当前目录。 用法: …...
【Python】torch中的.detach()函数详解和示例
在PyTorch中,.detach()是一个用于张量的方法,主要用于创建该张量的一个“离断”版本。这个方法在很多情况下都非常有用,例如在缓存释放、模型评估和简化计算图等场景中。 .detach()方法用于从计算图中分离一个张量,这意味着它创建…...
二级域名分发系统源码 对接易支付php源码 全开源
全面开源的易支付PHP源码分享:实现二级域名分发对接 首先,在epay的config.php文件中修改您的支付域名。 随后,在二级域名分发网站上做相应修改。 伪静态 location / { try_files $uri $uri/ /index.php?$query_string; } 源码下载&#…...
二分查找与搜索树的高频问题(算法村第九关白银挑战)
基于二分查找的拓展问题 山峰数组的封顶索引 852. 山脉数组的峰顶索引 - 力扣(LeetCode) 给你由整数组成的山脉数组 arr ,返回满足 arr[0] < arr[1] < ... arr[i - 1] < arr[i] > arr[i 1] > ... > arr[arr.length - 1…...
Python爬虫快速入门
Python 爬虫Sutdy 1.基本类库 request(请求) 引入 from urllib import request定义url路径 url"http://www.baidu.com"进行请求,返回一个响应对象response responserequest.urlopen(url)读取响应体read()以字节形式打印网页源码 response.read()转码 编码 文本–by…...
部署MinIO
一、安装部署MINIO 1.1 下载 wget https://dl.min.io/server/minio/release/linux-arm64/minio chmod x minio mv minio /usr/local/bin/ # 控制台启动可参考如下命令, 守护进程启动请看下一个代码块 # ./minio server /data /data --console-address ":9001"1.2 配…...
RK3566环境搭建
环境:vmware16,ubuntu 18.04 安装依赖库: sudo apt-get install repo git ssh make gcc libssl-dev liblz4-tool expect g patchelf chrpath gawk texinfo chrpath diffstat binfmt-support qemu-user-static live-build bison flex fakero…...
精确掌控并发:滑动时间窗口算法在分布式环境下并发流量控制的设计与实现
这是《百图解码支付系统设计与实现》专栏系列文章中的第(15)篇,也是流量控制系列的第(2)篇。点击上方关注,深入了解支付系统的方方面面。 上一篇介绍了固定时间窗口算法在支付渠道限流的应用以及使用redis…...
C++实现分布式网络通信框架RPC(3)--rpc调用端
目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中,我们已经大致实现了rpc服务端的各项功能代…...
【Linux】shell脚本忽略错误继续执行
在 shell 脚本中,可以使用 set -e 命令来设置脚本在遇到错误时退出执行。如果你希望脚本忽略错误并继续执行,可以在脚本开头添加 set e 命令来取消该设置。 举例1 #!/bin/bash# 取消 set -e 的设置 set e# 执行命令,并忽略错误 rm somefile…...
Linux链表操作全解析
Linux C语言链表深度解析与实战技巧 一、链表基础概念与内核链表优势1.1 为什么使用链表?1.2 Linux 内核链表与用户态链表的区别 二、内核链表结构与宏解析常用宏/函数 三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势5.1 插入效率5.2 安全…...
java_网络服务相关_gateway_nacos_feign区别联系
1. spring-cloud-starter-gateway 作用:作为微服务架构的网关,统一入口,处理所有外部请求。 核心能力: 路由转发(基于路径、服务名等)过滤器(鉴权、限流、日志、Header 处理)支持负…...
《Qt C++ 与 OpenCV:解锁视频播放程序设计的奥秘》
引言:探索视频播放程序设计之旅 在当今数字化时代,多媒体应用已渗透到我们生活的方方面面,从日常的视频娱乐到专业的视频监控、视频会议系统,视频播放程序作为多媒体应用的核心组成部分,扮演着至关重要的角色。无论是在个人电脑、移动设备还是智能电视等平台上,用户都期望…...
Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例
使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件,常用于在两个集合之间进行数据转移,如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model:绑定右侧列表的值&…...
理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端
🌟 什么是 MCP? 模型控制协议 (MCP) 是一种创新的协议,旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议,它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...
转转集团旗下首家二手多品类循环仓店“超级转转”开业
6月9日,国内领先的循环经济企业转转集团旗下首家二手多品类循环仓店“超级转转”正式开业。 转转集团创始人兼CEO黄炜、转转循环时尚发起人朱珠、转转集团COO兼红布林CEO胡伟琨、王府井集团副总裁祝捷等出席了开业剪彩仪式。 据「TMT星球」了解,“超级…...
Cinnamon修改面板小工具图标
Cinnamon开始菜单-CSDN博客 设置模块都是做好的,比GNOME简单得多! 在 applet.js 里增加 const Settings imports.ui.settings;this.settings new Settings.AppletSettings(this, HTYMenusonichy, instance_id); this.settings.bind(menu-icon, menu…...
2025 后端自学UNIAPP【项目实战:旅游项目】6、我的收藏页面
代码框架视图 1、先添加一个获取收藏景点的列表请求 【在文件my_api.js文件中添加】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口(适配服务端返回 Token) export const login async (code, avatar) > {const res await http…...
