- 博客(64)
- 收藏
- 关注
原创 Visitor 访问器模式
在软件构建过程中,由于需求的改变,某些类层次结构中常常需要添加新的行为(方法),如果直接在基类中做这样的更改,将会给子类带来很繁重的变更负担,甚至破坏原有设计。现在, 需要执行操作的原始对象将作为参数被传递给访问者中的方法, 让方法能访问对象所包含的一切必要数据。所有节点的类中都必须添加导出至 XML 文件的方法, 但如果在修改代码的过程中引入了任何缺陷, 那么整个程序都会面临风险。你可将该行为抽取到单独的访问者类中, 只需实现接收相关类的对象作为参数的访问者方法并将其他方法留空即可。
2026-02-05 21:12:43
603
原创 Command 命令模式
此外还有额外的好处, 现在你能在运行时切换连接至发送者的命令对象, 以此改变发送者的行为。这一改变也带来了许多有趣的应用: 你可以将命令作为方法的参数进行传递、 将命令保存在其他对象中, 或者在运行时切换已连接的命令等。是一种行为设计模式, 它可将请求转换为一个包含与请求相关的所有信息的独立对象。在这种情况下, 命令用于对目标对象执行各种不同的操作, 备忘录用来保存一条命令执行前该对象的状态。假如你正在开发一款新的文字编辑器, 当前的任务是创建一个包含多个按钮的工具栏, 并让每个按钮对应编辑器的不同操作。
2026-02-03 19:36:24
732
原创 Chain of Resposibility 职责链模式
最近, 你刚为自己的电脑购买并安装了一个新的硬件设备。因此在这种情况下, 每个请求要么最多有一个处理者对其进行处理, 要么没有任何处理者对其进行处理。最后, 接听人员将你的电话转接给了工程师, 他或许正缩在某幢办公大楼的阴暗地下室中, 坐在他所深爱的服务器机房里, 焦躁不安地期待着同一名真人交流。例如, 当用户点击按钮时, 按钮产生的事件将沿着 GUI 元素链进行传递, 最开始是按钮的容器 (如窗体或面板), 直至应用程序主窗口。收到请求后, 每个处理者均可对请求进行处理, 或将其传递给链上的下个处理者。
2026-02-01 11:04:45
731
原创 Iterator 迭代器模式
如果你需要采用特殊方式来遍历集合, 只需创建一个新的迭代器类即可, 无需对集合或客户端进行修改。无论集合的构成方式如何, 它都必须提供某种访问元素的方式, 便于其他代码使用其中的元素。在你的集合类中实现集合接口。如果你在代码中使用了这些接口, 那么将其他实现了这些接口的集合和迭代器传递给它时, 它仍将可以正常运行。不过由于集合提供不同的元素访问方式, 你的代码将不得不与特定集合类进行耦合。可以同时使用访问者模式和迭代器来遍历复杂数据结构, 并对其中的元素执行所需操作, 即使这些元素所属的类完全不同。
2026-01-31 09:08:17
990
原创 Composite 组合模式
对于盒子,它会逐一查看盒子里的每个物品,询问价格,然后返回该盒子的总价。如果其中一个盒子较小,盒子也会开始查看其内容物,依此类推,直到计算出所有内部组件的价格。你可以试试直接的方法:拆开所有箱子,检查所有产品,然后计算总额。订单中可能包含没有包装的简单产品,也可以是装满产品的盒子......以及其他箱子。在这种情况下,当叶节点组件收到请求时,它可能会通过所有父组件的链条传递到对象树的根节点。结构是一种结构设计模式,允许你将物体组合成树状结构,然后将它们视为独立的物体来处理。,因为叶类中的方法将是空的。
2026-01-28 19:12:05
683
原创 Memento 备忘录模式
之后,当用户决定回退某个动作时,应用会从历史中获取最新的快照,并用它恢复所有对象的状态。其他对象必须通过有限的接口与memomentos通信,该接口可能允许获取快照的元数据(创建时间、执行作名称等),但无法获取快照中原始对象的状态。在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。看护者,无论代表命令对象、历史,还是完全不同的事物,都应知道何时向原始者请求新的纪念品,如何存储它们,以及何时用特定纪念品恢复原始者。同时,发起者可以访问纪念品内部的所有字段,允许随意恢复之前的状态。
2026-01-26 19:44:19
674
原创 State 状态模式
基于条件句的状态机最大的弱点是在我们开始向类中添加越来越多的状态和依赖状态的行为时显现出来的。在任何唯一状态内,程序的行为不同,程序可以瞬间从一个状态切换到另一个状态。在状态模式中,特定状态可能彼此知晓,并发起从一个状态到另一个状态的转移,而策略几乎从不了解彼此。std::cout << "[售罄状态] 错误:商品已售罄,无法投币" << std::endl;std::cout << "[售罄状态] 错误:商品已售罄,无法出货" << std::endl;对于每个实际状态,创建一个源自状态接口的类。
2026-01-24 09:05:26
876
原创 Mediator 中介模式
通过直接在表单元素的代码中实现这种逻辑,这些元素的类在应用的其他形式中更难重复使用。例如,你无法在另一个表单中使用该复选框类,因为它与狗的文本字段耦合。相反,这些组件必须间接协作,通过调用一个特殊的中介对象将调用重定向到合适的组件。更改组件的代码,使其调用调解器的通知方法,而不是调用其他组件的方法。很可能,对话类已经知道它所有的子元素,所以你甚至不需要在这个类中引入新的依赖关系。由于组件间的所有关系都包含在中介器内部,通过引入新的中介类,可以轻易定义这些组件全新的协作方式,而无需更改组件本身。
2026-01-22 20:13:32
755
原创 Adapter 适配器模式
为了解决格式不兼容的问题,你可以为代码直接使用的分析库中每个类别创建XML转JSON适配器。当适配器接收调用时,它会将接收的XML数据转换为JSON结构,并将调用传递给相应的包裹分析对象的方法。然后你会在适配器内包裹缺少特征的对象,动态获得所需的特征。为了实现这一点,目标类必须有一个共同接口,适配器的字段也应遵循该接口。通过适配器,你可以通过不同的接口访问已有的对象。更糟的是,你可能根本无法访问库的源代码,这使得这种方法变得不可能。该实现采用对象组合原则:适配器实现一个对象的接口,并封装另一个对象。
2026-01-21 19:20:13
770
原创 Proxy 代理模式
如果没有预设的服务接口,就创建一个让代理对象和服务对象可以互换。由于代理实现了与原始类相同的接口,它可以传递给任何期望使用真实服务对象的客户端。然后你更新你的应用,让代理对象传递给原对象的所有客户端。当收到客户端的请求时,代理会创建一个真实的服务对象,并将所有工作委托给它。在面向对象系统中,有些对象由于某种原因(比如对象创建的开销很大,或者某些操作需要安全控制,或者需要进程外的访问等),直接访问会给使用者,或者系统结构带来很多麻烦。与Facade不同,代理与其服务对象具有相同的接口,这使得它们可以互换。
2026-01-20 19:24:46
820
原创 Facade 门面模式
例如,一个上传带有猫咪的短视频的应用,可能会使用专业的视频转换库。例如,当子系统升级到新版本时,你只需修改界面中的代码。为子系统中的一组接口提供一个一致(稳定)的界面,Facade模式定义了一个高层接口,这个接口使得这一子系统更加容易使用(复用)。Facade 定义了一个简化的界面,指向一个对象子系统,但它没有引入任何新功能。当你需要将应用与拥有数十种功能的复杂库集成时,拥有一个界面非常有用,但你只需要它一点点功能。结果是,你的类的业务逻辑会与第三方类的实现细节紧密耦合,导致理解和维护变得困难。
2026-01-19 19:47:46
686
原创 FlyWeight 享元模式
在我们的情况下,它是存储场中所有粒子的主要对象。因此,你需要的这些对象会更少,因为它们仅在内在状态上有所不同,而内在状态的变化远少于外在状态。该方法接受客户端的目标蝇重的内在状态,寻找与该状态匹配的现有蝇重对象,若找到则返回该对象。cout << "在坐标(" << x << "," << y << ") 落下【" << color << "棋】" << endl;在软件系统采用纯粹对象方案的问题在于大量细粒度的对象会很快充斥在系统中,从而带来很高的运行时代价——主要指内存需求方面的代价。
2026-01-18 22:17:01
576
原创 Singleton 单例模式
由于单例类的构造子是私有的,且大多数语言中无法覆盖静态方法,你需要想出一种有创意的方法来模拟单例。虽然它们非常方便,但也非常不安全,因为任何代码都有可能覆盖这些变量的内容,导致应用崩溃。原理是这样的:想象你创建了一个对象,但过了一段时间后决定创建一个新的。你不会收到一个全新的物品,而是你已经创建好的那个。如果你的代码能访问单例类,那么它就能调用单例的静态方法。是一种创建设计模式,允许你确保一个类只有一个实例,同时提供对该实例的全局访问点。保证一个类仅有一个实例,并提供一个该实例的全局访问点。
2026-01-15 21:39:27
651
原创 构建器模式
通过重复相同的步骤,你会得到第一个建造者建造的普通房屋,第二个建造者建造一座小城堡,第三个建造者建造一座宫殿。这种方法不能在构建界面中声明的原因在于,不同的构建者可能构建的产品没有统一界面。要建造一栋简单的房子,你需要建造四面墙和一层地板,安装一扇门,安装一对窗户,并建造一个屋顶。由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合在一起的算法却相对稳定。因此,你会让构造函数过载,创建多个参数更少的短版本。在这种情况下,你可以创建多个不同的建造者类别,实现相同的建造步骤,但方式不同。
2026-01-14 21:54:42
676
原创 Prototype 原型模式
因为你必须知道对象的类才能创建复制品,你的代码就依赖于那个类。有时你只知道对象所遵循的接口,却不知道具体的类,例如,当某个方法中的参数接受任何遵循某个接口的对象时。该方法创建当前类的对象,并将旧对象的所有字段值带入新对象。如果你想存储在历史中的对象状态相当简单,没有外部资源链接,或者链接容易重新建立,这种方法就适用。首先,你必须创建一个同类的新对象。由于需求的变化,这些对象经常面临着剧烈的变化,但是他们却拥有比较稳定一致的接口。当你需要像你配置的那样的对象时,只需克隆一个原型,而不是从零开始构建新对象。
2026-01-13 20:37:54
710
原创 抽象工厂模式
这样你可以更改传递给客户端代码的工厂类型,以及客户端代码接收的产品变体,而不破坏实际客户端代码。// ====================== 4. 具体工厂层:实现抽象工厂,生产对应产品族 ======================// ====================== 3. 抽象工厂层:声明创建产品族的接口 ======================// ====================== 2. 具体产品层:实现抽象产品接口 ======================
2026-01-12 20:44:45
615
原创 工厂方法模式
客户端代码可以将参数传递给该类的工厂方法,以控制它想要接收的产品。此外,如果你以后决定在应用中添加其他类型的交通工具,可能需要再次进行所有这些调整。不过,请考虑:现在你可以在子类中覆盖工厂方法,并更改该方法生成的产品类别。通过“对象创建”模式绕开new,来避免对象创建(new)过程中所导致的紧耦合(依赖具体类),从而支持对象创建的稳定。虽然这个方法返回基类中的对象,但你让子类返回对象。覆盖子类中的工厂方法,并从基础方法中提取相应的构造代码位。如果在所有提取后,基础工厂方法已经空了,你可以把它做成抽象的。
2026-01-11 15:19:39
819
原创 Bridge 桥模式
按照这种方法,我们可以将与颜色相关的代码提取成一个包含两个子类的独立类:和。这意味着你将一个维度提取到一个独立的类层级结构中,使原始类引用新层级中的对象,而不是将所有状态和行为集中在一个类中。不过,既然你已经有两个子职业,你需要创建四个职业组合,比如和。在最坏的情况下,这个应用可能看起来像一个巨大的意大利面碗,数百个条件句将不同类型的图形界面和代码中各处的API连接起来。是一种结构设计模式,允许你将一个大型类或一组密切相关的类拆分为两个独立的层级——抽象和实现——这些层级可以独立开发。
2026-01-10 21:14:50
1044
原创 Decorator 装饰模式
该方法可以接收来自客户端的消息参数, 并将该消息发送给一系列的邮箱, 邮箱列表则是通过构造函数传递给通知器的。并且随着子类的增多(扩展功能的增多),各种子类的组合(扩展功能的组合)会导致更多子类的膨胀。由于所有的装饰都实现了与通知基类相同的接口, 客户端的其他代码并不在意自己到底是与 “纯粹” 的通知器对象, 还是与装饰后的通知器对象进行交互。这些衣服都是“延伸”你的基本行为,但不是你身体的一部分,你可以随时脱掉任何不需要的衣服。只要所有装饰都遵循相同的接口, 客户端就可以使用任意自定义的装饰来装饰对象。
2026-01-06 20:29:32
775
原创 观察者模式
如果你的应用中有多个不同类型的发布者,且希望订阅者可兼容所有发布者,那么你甚至可以进一步让所有发布者遵循同样的接口。实际应用中可能会有十几个不同的订阅者类跟踪着同一个发布者类的事件,你不会希望发布者与所有这些类相耦合的。定义对象间的一种一对多(变化)的依赖关系,以便当一个对象(Subject)的状态发生改变时,所有依赖于它的对象都得到通知并自动更新。但是, 如果你需要在现有的类层次结构中应用该模式, 则可以考虑使用组合的方式: 将订阅逻辑放入一个独立的对象, 然后让所有实际订阅者使用该对象。
2026-01-05 19:18:24
846
原创 策略Strategy模式
在实现新功能的过程中,你的团队需要修改同一个巨大的类,这样他们所编写的代码相互之间就可能会出现冲突。实际上,上下文并不十分了解策略,它会通过同样的通用接口与所有策略进行交互,而该接口只需暴露一个方法来触发所选策略中封装的算法即可。在软件构建过程中,某些对象使用的算法可能多种多样,经常改变,如果将这些算法都编码到对象中,将会使对象变得异常复杂;上下文并不执行任务,而是将工作委派给已连接的策略对象。是一种行为设计模式,它能让你定义一系列算法,并将每种算法分别放入独立的类中, 以使算法的对象能够相互替换。
2026-01-03 16:37:24
694
原创 模板方法模式
模板方法模式建议将算法分解为一系列步骤,然后将这些步骤改写为方法, 最后在 “模板方法” 中依次调用这些方法。还有另一个与使用这些类的客户端代码相关的问题:客户端代码中包含许多条件语句,以根据不同的处理对象类型选择合适的处理过程。定义一个操作中的算法的骨架(稳定),而将一些步骤延迟(变化)到子类中。在我们的例子中,子类中已有所有必要的实现,因此我们只需调整这些方法的签名,使之与超类的方法匹配即可。是一种行为设计模式,它在超类中定义了一个算法的框架,允许子类在不修改结构的情况下重写算法的特定步骤。
2026-01-02 14:51:24
829
原创 设计模式:抵御变化的编程艺术
设计模式是软件设计中常见问题的典型解决方案。它们就像能根据需求进行调整的预制蓝图,可用于解决代码中反复出现的设计问题。“每一个模式描述了一个在我们周围不断重复发生的问题,以及该问题的解决方案的核心。这样,你就能一次又一次地使用该方案而不必做重复劳动”。
2026-01-01 20:28:39
345
原创 FreeRTOS内核:核心数据结构与任务切换原理解析
RTOS(Real Time Operation System,实时操作系统)是一种能够保证任务在规定时间内完成响应的操作系统,核心优势在于和。与裸机开发的“顺序执行+中断”模式不同,RTOS通过内核调度,让多个任务“并发”运行,大幅提升系统的复杂度和可靠性。#define configMAX_PRIORITIES (32) // 最大优先级数(用户可配置)// 就绪队列数组。
2025-11-17 21:58:27
765
原创 ARM处理器指令集
RSC(Reverse Subtract with Carry)指令从从寄存器shifter_operand中减去Rn表示的数值,再减去寄存器CPSR中C条件标志位的反码[NOT (Carry flag)],并将结果保存到目标寄存器Rd中,并根据指令的执行结果设置CPSR中相应的标志位。EOR(Exclusive OR)指令将寄存器Rn中的值和shifter_operand的值执行按位“异或”操作,并将执行结果存储到目标寄存器Rd中,同时根据指令的执行结果更新CPSR中相应的条件标志位。
2025-10-16 23:35:36
532
原创 ens33: <BROADCAST,MULTICAST> mtu 1500 qdisc fq_codel state DOWN group default qlen 1000 link/eth
是Linux系统中用于网络配置的强大工具,它整合了ifconfig和route命令的功能,并提供了更多的功能和灵活性。另外,也可以检查虚拟机的网络适配器设置,确保它处于正确的模式(通常是 NAT 或桥接模式)。从提供的 ip addr 命令输出来看,你的 Ubuntu 虚拟机的网络接口 ens33 处于 DOWN 状态(未激活),这就是无法连接网络的主要原因。成功的话,你应该能看到 ens33 接口的状态变为 UP,并且会有一个 inet 开头的 IP 地址。(DHCP) 的客户端程序,用于从。
2025-09-24 21:47:16
1058
原创 Linux 信号深度解析
信号(Signal)本质上是 Linux 内核向进程发送的异步事件通知,用于告知进程发生了特定事件(如用户按下Ctrl+C、进程访问非法内存、定时器到期等)。每个信号都有唯一的编号和默认行为,进程可以通过自定义处理函数修改信号的默认响应逻辑。
2025-09-22 09:26:12
911
原创 Git常用命令和分支管理
在现代软件开发中,版本控制是保障代码安全、提升团队协作效率的核心工具,而 Git 作为当前最主流的分布式版本控制系统,更是开发者必须掌握的技能。本文将从 Git 初始化配置入手,逐步讲解本地仓库操作、常用命令优化,以及企业级分支管理策略,帮助新手快速上手并规范使用 Git。
2025-09-19 10:07:52
797
原创 高并发场景下的I/O复用
I/O 复用技术是高性能网络编程的基础,select、poll 和 epoll 各有优缺点。对于需要良好移植性的简单应用,可以选择 select 或 poll对于 Linux 平台下的高性能服务器程序,epoll 是更好的选择,尤其是 ET 模式可以提供更高的效率理解这些 I/O 复用机制的工作原理和特性,有助于我们编写更高效、更可靠的网络应用程序。
2025-09-18 14:27:03
659
原创 深入理解 Linux 系统调用
添加系统调用表项:在对应架构的系统调用表(如)中,添加 “调用号→自定义函数” 的映射;定义调用号:在中为自定义系统调用分配调用号(需确保不与现有调用号冲突);编译进内核:将自定义系统调用的实现代码放入kernel/目录下的相关文件(如),确保编译时被纳入内核映像。系统调用是 Linux 操作系统的 “神经中枢”,它连接了用户态的应用程序与内核态的底层服务,既保障了系统的安全与稳定,又为开发者提供了便捷的硬件抽象接口。
2025-09-17 15:49:38
818
原创 Git 详细安装教程
Git 作为目前最流行的分布式版本控制系统,是程序员日常开发、项目协作中不可或缺的工具。无论是个人项目版本管理,还是团队多人协作开发,掌握 Git 的安装与基础使用都是第一步。本文将以 Windows 系统为例,提供一份超详细的 Git 安装指南,从下载到验证,每一步都附带清晰说明,确保新手也能轻松完成安装。
2025-09-17 15:31:44
481
原创 一文读懂 Git
Git 是一款免费、开源的分布式版本控制系统,旨在快速高效地处理从小型个人项目到大型团队项目(如 Linux 内核)的所有版本管理需求。廉价的本地库:所有历史记录存储在本地,操作(如查看历史、回退版本)速度极快,无需联网;灵活的暂存区:引入 “暂存区”(Stage)概念,可选择性提交修改,避免 “一次提交所有改动” 的混乱;强大的分支管理:支持成千上万个并行分支,分支创建、切换、合并的成本极低,完美适配 “非线性开发”(如同时开发多个功能、修复多个 bug)。
2025-09-17 15:02:32
1045
原创 深入理解 Linux 进程调度:从策略到实现的全方位解析
从策略层:通过进程类型划分、优先级体系,为不同任务制定差异化规则;从算法层:CFS 通过 “比例公平” 和红黑树,平衡普通进程的响应性与吞吐量;从实现层:通过调度器类、上下文切换、睡眠唤醒等模块,确保调度的高效与稳定;从实时层:提供 SCHED_FIFO/SCHED_RR,满足实时任务的低延迟需求。理解 Linux 进程调度,不仅能帮助开发者优化程序性能(如通过调整 Nice 值提升关键进程优先级),更能深入体会操作系统 “资源分配与效率平衡” 的设计思想。
2025-09-17 14:24:34
875
原创 高性能服务器程序框架
高性能服务器程序的设计是一项复杂的系统工程,需要综合考虑服务器模型、I/O 模型、事件处理模式和并发模式。半同步 / 半异步模式和领导者 / 追随者模式各有优缺点,适用于不同的应用场景。此外,通过池技术、减少数据复制、优化上下文切换和锁竞争等手段,可以进一步提高服务器的性能。在实际开发中,需要根据具体的业务场景和性能需求,选择合适的技术方案,并进行持续的性能测试和优化。希望本文介绍的这些技术和方法,能为你设计和实现高性能服务器程序提供有益的参考。
2025-09-15 15:15:05
1070
原创 深入理解 DMA
解放 CPU,提升数据传输效率。它不是 “替代 CPU”,而是 “分担 CPU 的繁琐工作”,让处理器能更高效地处理核心任务。串口大量数据收发:如日志打印、传感器批量数据上传;ADC 多通道连续采样:如电压、电流、温度等多参数实时采集;SPI/I2C 高速数据传输:如与显示屏、存储芯片(SD 卡、Flash)的高速通信;存储器间数据搬运:如将 Flash 中的固件数据搬运到 SRAM 中运行(STM32F103 的 DMA2 支持)。
2025-09-14 15:03:48
1563
原创 深入理解 Linux 内核进程管理
在 Linux 系统中,进程是资源分配和调度的基本单位,内核对进程的高效管理直接决定了系统的性能与稳定性。本文将从进程描述符的结构入手,逐步剖析进程的创建、线程实现与进程终结的完整生命周期,带您深入理解 Linux 内核的进程管理机制。
2025-09-11 20:42:25
1034
原创 TCP 协议深度解析
TCP(Transmission Control Protocol,传输控制协议)是互联网中最核心的传输层协议之一,为应用程序提供可靠、有序、面向连接的字节流服务。本文将基于你提供的核心框架,补充技术细节、实际应用场景及底层原理,帮助更全面地理解 TCP 协议。
2025-09-09 20:26:52
869
原创 深入理解 IP 协议
IP 协议作为互联网的 “基石”,其设计围绕 “高效跨网络交付” 展开:无状态、无连接的特性简化了协议实现,不可靠的服务则将可靠性交给上层协议;IPv4 头部结构为数据报提供了完整的 “身份信息” 和 “传输指令”;IP 分片解决了不同链路 MTU 的兼容性问题;路由和转发机制确保数据报能找到最优路径并合法传输;ICMP 重定向则动态优化路由,提升整体网络效率。
2025-09-08 21:42:40
917
原创 10 步看懂 HTTP:从浏览器输入网址到页面加载的全过程
客户端会明确告诉服务器 “我要做什么”,比如用 “GET” 方法获取网页内容,用 “POST” 方法提交表单数据,这些方法指示符就像对话里的 “指令”,让服务器清楚本次请求的目的和所需参数。服务器和客户端断开本次连接,释放资源,让服务器能腾出 “通道”,迎接其他客户端的新请求 —— 至此,一次完整的 HTTP 流程就结束了,你也就看到了浏览器加载完成的网页。,这意味着客户端每发一次请求,都要和服务器重新建立连接,请求结束后连接就会断开,不会留下任何 “记忆”,这也是后续所有步骤的基础逻辑。
2025-09-08 08:52:13
1057
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅