0%

🐎 2026 马年:写给工程师的系统级祝福

2026 年,农历马年。
马,在中国文化里代表速度、力量、执行力、远行与突破

对普通人来说是祝福;
对工程师来说,是一次系统升级窗口

今天这篇,不讲鸡汤。
我们用架构思维,给自己写一份“可执行的新年祝福”。


一、愿你的系统:低耦合,高内聚

马年祝福第一条:

愿你的生活架构,完成一次“解耦重构”。

  • 情绪不要绑定在 KPI 上
  • 自我价值不要耦合在他人评价上
  • 收入结构不要单点依赖
  • 认知模型持续升级

这叫:人生的高可用架构设计


二、愿你的执行力:像 🐎 一样奔跑

在历史里,“马”往往代表军事效率。

比如:

  • 岳飞 —— 精忠报国,铁骑纵横
  • 成吉思汗 —— 骑兵构建跨洲帝国

马的核心特征不是“想得多”,
而是——动得快

对技术人来说:

  • 不要只收藏文章
  • 不要只研究趋势
  • 不要只讨论 AI 未来

写代码。
跑模型。
部署上线。
真实验证。

执行力 = 想法 × 行动频率。

马年第二条祝福:

愿你少焦虑,多提交。


三、愿你的技术栈:完成指数级升级

2026,不是普通的一年。

AI 已经从“工具”变成“生产力引擎”。

从:

  • Prompt 时代
  • 到 Agent 时代
  • 到 Autonomous System 时代

如果 2024 是 Chat,
2025 是 Copilot,
2026 可能是:系统自运行

就像:

  • OpenAI 在推动 Agent 架构
  • NVIDIA 在做算力底座

马年第三条祝福:

愿你的学习曲线,领先于行业迭代曲线。

技术人最危险的不是加班,
而是停止进化


四、愿你的现金流:持续为正

工程师最大的误区:

“技术就是一切。”

现实世界是:

1
技术 × 商业 × 时间 = 复利

如果技术没有变现路径,
那只是能力储备。

马年第四条祝福:

  • 主业升级
  • 副业尝试
  • 投资理性
  • 风险可控

现金流稳定,精神才能稳定。


五、愿你拥有“分布式人生”

单节点人生,很脆弱。

2025 年你可能发现:

  • 工作城市与家庭分离
  • 线上社交大于线下社交
  • 技术与生活割裂

真正成熟的人生,是“分布式系统”。

它有:

  • 主节点(核心能力)
  • 副节点(兴趣 / 副业)
  • 冷备节点(健康 / 家庭)
  • 监控系统(自我反思)

当一个节点失效,
整体系统仍然可运行。

这,才是人生级容灾架构


六、马年的真正含义

马不是安稳的动物。

它象征:

  • 迁移
  • 突破
  • 远征
  • 不停歇

技术行业亦然。

如果你是:

  • 3–5 年工程师 —— 今年要向架构跃迁
  • 5–10 年工程师 —— 要建立系统思维
  • 技术负责人 —— 要建立组织能力
  • 创业者 —— 要建立战略视野

马年不是躺平之年。

它是:加速之年


七、给读者的一段工程师式祝福

愿你:

架构清晰如分层系统,
思维严谨如类型系统,
心态稳定如 Raft Leader,
收入增长如指数函数,
身体健康如冗余副本,
人生成功如高可用集群。


最后一句话

2026 马年。

愿你:

  • 有速度
  • 有方向
  • 有耐力
  • 有远方

我们不只是写代码的人。
我们是在构建未来系统的人。

马蹄声起,
新的版本开始发布。

👇👇👇 扫码体验小程序 👇👇👇

ai-vibe-coding-2026210151912

👇👇👇 扫码关注公众号 👇👇👇

ai-vibe-coding-2026210151858

汉朝,是一次 Service Mesh 的成功实践嘛?

如果说:

  • 周朝像“拆了但没治理好的微服务”
  • 秦朝像“强一致性的超级单体”

那么汉朝是什么?

如果用架构语言来描述,会发现一个有意思的结构:

汉朝,是一次在分布式基础上,引入“流量治理层”的实践。

这非常接近今天的 —— Service Mesh。


一、什么是 Service Mesh?

在微服务体系中,Service Mesh 解决的不是“拆分问题”。

目前常见的Service Mesh框架:有Istio、Linkerd、Consul Connect等

它解决的是:

  • 服务间通信治理
  • 统一流量控制
  • 认证与授权
  • 熔断与限流
  • 可观测性

关键点在于:

业务服务本身不变,但通信被纳入统一治理。

Mesh 不取代服务。

它包裹服务。


二、秦 → 汉:不是回到分封,而是加了一层治理

秦的失败我们已经分析过:

单体强一致,但弹性不足。

汉朝建立时,刘邦 并没有简单复制秦的单体。

而是采用了:

1
郡县 + 诸侯国并行

这是一种混合部署模型。

一部分是中央直管(郡县),
一部分是自治节点(诸侯国)。

看起来像回到了周。

但关键不同在于:

汉朝逐步建立了“治理层”。


三、推恩令:一次优雅的流量拆分策略

汉武帝 时代推出的“推恩令”,是一个极其典型的架构操作。

逻辑是什么?

  • 诸侯死后,封地拆分给多个子嗣
  • 实力自动分散
  • 无需暴力回收

这相当于:

1
对强节点做自动水平拆分

不是删除服务。
而是降低单点权重。

这很像:

  • 流量均衡
  • 节点限权
  • 去中心化压强

它避免了“七国之乱”式的暴力冲突再次发生。

这是治理,而不是强控。


四、汉朝的 Mesh 层:监察与仲裁机制

汉朝逐渐建立了:

  • 刺史制度
  • 察举制度
  • 尚书台运转机制

这些结构的本质是:

中央对地方通信链路的监控与调度。

这非常像:

  • Sidecar 代理
  • 流量监控
  • 审计日志

地方仍有自治权。

但:

1
2
3
通信被观察
行为被记录
异常可干预

这就是 Mesh 的核心价值。


五、为什么汉朝比秦活得久?

我们对比一下:

维度
架构形态 强单体 混合架构
地方自治 有限
治理层 高压控制 逐步渗透
弹性 中高
生命周期 15年 400年

秦试图用“删除服务”解决复杂度。

汉选择:

在不彻底删除服务的情况下,引入治理层。

这是一种更柔性的控制方式。


六、Service Mesh 的一个重要特性:解耦治理与业务

在没有 Mesh 的系统里:

  • 业务逻辑承担安全
  • 服务自己实现限流
  • 各自管理认证

这会导致:

1
2
3
逻辑耦合
升级困难
不可统一管理

Mesh 的价值在于:

把治理从业务代码中抽离出来。

汉朝的治理逻辑也逐渐脱离“血缘合法性”,

转向:

  • 制度化监察
  • 官僚体系
  • 中央调度能力

治理不再依赖个人魅力。

而成为制度层。

这正是架构成熟的标志。


七、汉朝为什么仍然会走向东汉末年的混乱?

需要强调一点:

Mesh 不是万能。

当:

  • 核心节点弱化
  • 治理层被劫持
  • 内部代理节点掌握流量入口

系统仍然可能失控。

东汉后期,

外戚与宦官控制核心接口,

Mesh 层被污染。

这不是分布式问题。

是治理层退化。


八、给现代架构的启示

很多公司在经历:

  • 单体 → 微服务 → 混乱

如果只拆分,不做治理,

一定会进入“春秋战国”。

如果只集中,不留自治,

可能成为“秦”。

真正成熟的系统,需要:

分布式 + 治理层 + 动态平衡

这才是长期可持续结构。


九、结论

汉朝不是简单“比秦温和”。

汉朝真正成功的地方在于:

它意识到:
拆分与集中不是对立关系。
治理层,才是长期稳定的关键。

从架构视角看:

  • 周是分布式试验
  • 秦是强一致回滚
  • 汉是治理层升级

如果把历史当成系统演化样本,

汉朝确实更像一次:

Service Mesh 成功落地的实践。

当然,它不是完美的。

但它告诉我们一件事:

真正成熟的系统,不是选对模式。
而是在复杂度上升时,增加治理层。

👇👇👇 扫码体验小程序 👇👇👇

ai-vibe-coding-2026210151912

👇👇👇 扫码关注公众号 👇👇👇

ai-vibe-coding-2026210151858

技术圈最近几年出现一个明显趋势:

  • 过去大家疯狂拆单体,上微服务。
  • 现在很多公司开始“服务合并”,回归单应用。

于是两派争论不断:

  • 微服务派:单体是落后架构。
  • 单体派:微服务是过度设计。

但如果用系统演化的视角看,会发现一个有意思的真相:

架构从来不是先进与否的问题,
而是是否匹配当前业务复杂度。

而历史上,秦与汉的更替,恰好是一次经典的架构演化样本。


一、秦:一个高度集中的“单应用系统”

秦始皇 建立的国家结构,本质上是:

强中心、强一致、低自治的单应用架构。

核心特征:

  • 地方无自治模块(郡县制)
  • 所有关键决策汇聚中央
  • 统一协议(文字、度量衡、法律)
  • 强一致性执行

在“统一六国”的阶段,这种架构极其高效。

就像一个创业公司:

  • 创始人拍板快
  • 组织链路短
  • 方向一致
  • 执行迅猛

问题不在统一阶段。

问题在统一之后。


二、秦二世而亡:架构能力 < 业务复杂度

秦统一后,系统复杂度急剧上升:

  • 地域扩大数倍
  • 民族结构多样化
  • 边疆军事压力长期存在
  • 经济形态差异巨大

这相当于:

1
2
3
系统规模 x10
业务场景 x10
治理复杂度 xN

但架构没有升级。

仍然是:

  • 单中心决策
  • 高压执行
  • 强一致模型
  • 无自治模块

当复杂度超过架构承载能力时,会发生三件事:

1️⃣ 核心节点过载

皇帝成为唯一核心实例。

信息流、决策流全部集中。

一旦核心判断失误,影响是全局性的。


2️⃣ 局部问题无法局部消化

在单应用里:

1
模块之间高度耦合

局部民变,很快变成系统级崩溃。

没有“自治单元”可以隔离问题。


3️⃣ 无容灾机制

秦二世 继位之后,

核心实例性能下降。

但系统没有:

  • 副本机制
  • 权力缓冲层
  • 自治结构

结果就是:

单点退化 = 全局崩溃

这不是简单的“暴政问题”。

这是:

架构能力无法支撑增长后的业务复杂度。

秦的失败,本质是:

1
2
业务规模快速扩张
架构模型停留在创业阶段

三、单应用的优势与边界

单应用(Monolith)本身并不落后。

它在以下阶段非常合适:

  • 0 → 1
  • 组织规模小
  • 业务领域简单
  • 决策链短

优点非常明显:

  • 部署简单
  • 运维成本低
  • 调试方便
  • 强一致性

但问题在于:

当业务领域复杂度激增时,单体系统很难划清边界。

长期演进后会出现:

  • 模块耦合
  • 发布风险扩大
  • 团队协作冲突
  • 变更牵一发而动全身

这正是很多中大型企业的真实困境。


四、秦 → 汉:一次系统重构

刘邦 建立汉朝后,没有完全复制秦的架构。

而是做了一次关键调整:

在单中心之上,引入“局部自治模块”。

汉初:

  • 分封诸侯王
  • 地方拥有一定自主权
  • 中央与地方形成博弈关系

这相当于:

1
单体系统 → 加入模块化结构

虽然产生“七国之乱”,

但系统并未崩溃。

因为:

局部问题,可以局部解决。

后来到 汉武帝 时,

又逐步收回过度自治,

形成:

1
中心 + 受控自治

这是一种演化后的混合架构。

既避免完全单体,
也避免完全分布式失控。

汉朝寿命远超秦,

不是因为“更仁慈”。

而是因为:

架构开始匹配复杂度。


五、为什么今天很多企业在“回归单应用”?

过去十年,

企业高速增长,

组织复杂度激增,

微服务成为自然选择。

微服务解决的是:

  • 领域拆分
  • 团队并行
  • 独立扩容
  • 快速迭代

但现在很多企业面临:

  • 业务增长放缓
  • 成本压力上升
  • 团队规模收缩

这时:

1
架构复杂度 > 当前业务复杂度

于是开始合并服务。

这不是倒退。

这是规模回调。


六、真正的核心变量

架构的选择,本质上取决于:

1
业务复杂度 × 组织规模
  • 小规模 + 低复杂度 → 单应用
  • 高规模 + 多领域 → 微服务
  • 收缩期 → 适度合并

错误不在于用哪种。

错误在于:

规模变化了,架构没变。

秦的错误是:规模爆炸,架构未升级。

有些公司现在的错误是:规模收缩,架构没降级。


七、最后的思考

单应用不是落后。

微服务不是先进。

真正的问题是:

你的架构,是否还匹配当前业务阶段?

秦的教训不是“不要集权”。

而是:

当系统规模指数级增长时,
创业阶段的架构必须演化。

否则,增长本身会成为压力源。

而汉朝给我们的启示是:

架构演化,比架构选择更重要。

系统不会因为选择单体或微服务而失败。

系统会因为:

在复杂度变化时,没有及时重构。

👇👇👇 扫码体验小程序 👇👇👇

ai-vibe-coding-2026210151912

👇👇👇 扫码关注公众号 👇👇👇

ai-vibe-coding-2026210151858

在使用docker的时候,难免会遇到当前主机不支持运行docker的情况,这时可以使用运程ssh的形式连接一个已经创建了docker的主机,本地正常使用docker命令

Docker Machine Generic驱动

首先说明一下 Docker Machine Generic驱动
它可以 创建一个machines通过SSH使用已经存在的虚拟机或是主机。

Example
创建一个machine的实例,需要指定–driver generic,主机的IP地址,DNS名和SSH私钥路径去连接它.

1
2
3
4
5
docker-machine create \
--driver generic \
--generic-ip-address=203.0.113.81 \
--generic-ssh-key ~/.ssh/id_rsa \
vm

除了上述的命令,你还可以使用的选项如下

1
2
3
4
5
6
Options
--generic-engine-port:Docker Daemon使用的端口(注意:这个标识在boot2docker中无效)
--generic-ip-address:必需字段,主机IP地址.
--generic-ssh-key:SSH user的私钥路径.
--generic-ssh-user:SSH连接使用的username.
--generic-ssh-port:SSH使用的端口.

之后 eval $(docker-machine env vm)
注意 这里 vm 是你设置的 docker machine 名字

执行一个 hello world

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
docker run hello-world

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
1. The Docker client contacted the Docker daemon.
2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
(amd64)
3. The Docker daemon created a new container from that image which runs the
executable that produces the output you are currently reading.
4. The Docker daemon streamed that output to the Docker client, which sent it
to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
$ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
https://hub.docker.com/

For more examples and ideas, visit:
https://docs.docker.com/get-started/

Docker的安装是非常方便的,但是有一些细节还是要注意一下,下面打开博客了解更多内容吧。

阅读全文 »

分布式事务的背景

当系统架构使用非单体应用的时候,如采用 面向服务架构、徽服务架构的时候,会将项目拆分为不同的应用服务到单独的运行环境中,应用服务之间通讯使用的如wcf、http、rpc等等远程调用技术、每个服务中都有自己的数据库数据源和本地事务,服务之间互不影响,这种情况下就产生了分布式事务的问题。

CAP是什么

CAP定律是指在一个分布式系统中、Consistency(一致性)、 Availability(可用性)、Partition tolerance(分区容错性),三者不可得兼。

注意

1、这里说的是在一个分布式系统中才会出现的问题,在单体应用中不会出现CAP三者不可兼得的问题。

2、关于权衡,不要以为在所有时候都只能选择两个特性。在不存在网络失败的情况下(分布式系统正常运行时的必要条件),C和A能够同时保证。只有当网络失败时,才会在C和A之间做出选择。

接下来我们具体来了解CAP具体是什么?

Consistency(一致性)

对于客户端的每次读操作,要么读到的是最新的数据,要么读取失败。换句话说,一致性是站在分布式系统的角度,对访问本系统的客户端的一种承诺:要么我给您返回一个错误,要么我给你返回绝对一致的最新数据,不难看出,其强调的是数据正确。

Availability(可用性)

任何客户端的请求都能得到响应数据,不会出现响应错误。换句话说,可用性是站在分布式系统的角度,对访问本系统的客户的另一种承诺:我一定会给您返回数据,不会给你返回错误,但不保证数据最新,强调的是不出错。

Partition tolerance(分区容错性)

由于分布式系统通过网络进行通信,网络是不可靠的。当任意数量的消息丢失或延迟到达时,系统仍会继续提供服务,不会挂掉。换句话说,分区容忍性是站在分布式系统的角度,对访问本系统的客户端的再一种承诺:我会一直运行,不管我的内部出现何种数据同步问题,强调的是不挂掉。

CAP的取舍权衡

C、A、P三个特性只能满足其中两个,那么取舍的策略共有3种:

  • CA没有P;如果没有P就是没有分区的意思,这咱情况下系统没有扩展性,无法部署节点、也就无法完成分布式设计的思想。
  • CP没有A;不要可用性的情况下,每个服务器之间保持强一致性而P(分区)之间的数据同步需要一定的时间,同步期间用户会有不好的体验,有很多系统使用的是CP的方案,如 Redis、HBase等
  • AP没有C;如果没有C一致性,系统可以高可用分区的情况下,P分区情况下节点之间,节点使用本地数据提供服务,这样的方案下数据在全局来看无法达到一致性。一般在抢购的场景下会出现这种情况,如看到库存还在,但是抢购下单的时候发现库存已经不在了。牺牲数据一致的用户体验,让系统整体可以运行,不会阻塞用户的购物流程。

一般的大型互联网应用采用多主机,集群化部署的方式。这种多节点的架构方式下,对于P的容错是分布式系统架构下一定要面对的问题,于是只能在C和A之间做取舍,但是有时对于一些对C强一致性要求极高的场景中,如银行转账可以在A和P之间取舍,如果出现网络故障,宁可停止服务。

具体可以根据实际的业务场景选择适合的架构设计。

参考:

分布式CAP定理,为什么不能同时满足三个特性?_cpa原则三个特性-CSDN博客

设计模式是软件开发中常用的解决方案,而设计模式的六大原则则是指导我们创建可维护、可扩展、可重用的高质量软件的基本准则。在本文中,我们将深入探讨这六大原则,并为每个原则提供具体的例子。

1. 单一职责原则(Single Responsibility Principle - SRP)

单一职责原则要求一个类应该只有一个引起变化的原因。这意味着一个类应该只负责一项职责。

例子:

1
2
3
4
5
6
7
8
9
10
11
12
public class FileManager
{
public void SaveFile(string content)
{
// 保存文件的具体实现
}

public void ParseFile(string filePath)
{
// 解析文件的具体实现
}
}

在上述例子中,FileManager类分别负责保存文件和解析文件,遵循了单一职责原则。

2. 开放封闭原则(Open-Closed Principle - OCP)

开放封闭原则要求软件实体(类、模块、函数等)应该对扩展开放,对修改封闭。即通过添加新的代码来扩展现有功能,而不是修改已有代码。

例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public interface IShape
{
void Draw();
}

public class Circle : IShape
{
public void Draw()
{
// 画圆的具体实现
}
}

public class Square : IShape
{
public void Draw()
{
// 画正方形的具体实现
}
}

在上述例子中,通过添加新的实现类(如Triangle),我们可以轻松扩展支持新的形状,而不需要修改IShape接口及其现有实现类。

3. 里氏替换原则(Liskov Substitution Principle - LSP)

里氏替换原则要求子类能够替换其父类而不影响程序的正确性。即如果一个类型是父类型,那么它应该能够被子类型替代。

例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public class Rectangle
{
protected int Width;
protected int Height;

public void SetWidth(int width)
{
Width = width;
}

public void SetHeight(int height)
{
Height = height;
}
}

public class Square : Rectangle
{
public override void SetWidth(int width)
{
Width = width;
Height = width;
}

public override void SetHeight(int height)
{
Width = height;
Height = height;
}
}

在上述例子中,Square类继承自Rectangle类,并重写了SetWidthSetHeight方法,保证了子类能够替换父类而不破坏程序的正确性。

4. 依赖倒置原则(Dependency Inversion Principle - DIP)

依赖倒置原则要求高层模块不应该依赖于低层模块,而是应该依赖于抽象。同时,抽象不应该依赖于细节,细节应该依赖于抽象。

例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public interface IWriter
{
void Write(string message);
}

public class ConsoleWriter : IWriter
{
public void Write(string message)
{
Console.WriteLine("Writing to console: " + message);
}
}

public class MessageProcessor
{
private readonly IWriter _writer;

public MessageProcessor(IWriter writer)
{
_writer = writer;
}

public void ProcessMessage(string message)
{
// 处理消息的逻辑
_writer.Write(message);
}
}

在上述例子中,MessageProcessor高层模块依赖于抽象IWriter接口,而不直接依赖于具体的ConsoleWriter实现,符合依赖倒置原则。

5. 接口隔离原则(Interface Segregation Principle - ISP)

接口隔离原则要求一个类不应该强迫其它类实现它们用不到的方法。接口应该小而专一。

例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
public interface IWorker
{
void Work();
void Eat();
}

public class Programmer : IWorker
{
public void Work()
{
// 程序员的工作
}

public void Eat()
{
// 程序员的吃饭
}
}

public class Janitor : IWorker
{
public void Work()
{
// 看门员的工作
}

public void Eat()
{
// 看门员的吃饭
}
}

在上述例子中,通过接口隔离原则,ProgrammerJanitor只需实现与自己相关的方法,避免了强迫实现不需要的方法。

6. 合成复用原则(Composite Reuse Principle - CRP)

合成复用原则要求尽量使用对象组合,而不是继承。通过组合现有的对象来实现新的功能,而不是通过继承现有的类。

例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class Engine
{
public void Start()
{
// 引擎启动逻辑
}
}

public class Car
{
private readonly Engine _engine;

public Car(Engine engine)
{
_engine = engine;
}

public void Start()
{
_engine.Start();
// 其他汽车启动逻辑
}
}

在上述例子中,Car类通过组合Engine类来实现汽车的启动功能,而不是通过继承Engine类。

通过理解和遵循这六

大原则,开发人员可以更好地设计出灵活、可维护的软件系统。这些原则为面向对象设计提供了指导方针,有助于构建更加健壮和可扩展的应用程序。

状态模式 - 行为型模式的状态切换之旅

在软件设计中,状态模式是一种行为型设计模式,它允许一个对象在其内部状态改变时改变其行为。状态模式的核心思想是将对象的行为与其状态分离,使得在不同的状态下可以选择不同的行为。本文将深入讨论状态模式的概念、实现方式以及在实际应用中的使用场景。

状态模式的概念

状态模式(State Pattern)是一种行为型设计模式,其核心思想是允许一个对象在其内部状态改变时改变其行为。状态模式将对象的状态和行为分离,使得对象在不同的状态下可以选择不同的行为。状态模式主要包括三个角色:上下文(Context)、抽象状态(State)和具体状态(ConcreteState)。

状态模式的 UML 类图

classDiagram
    class Context {
        - state: State
        + Request(): void
        + SetState(state: State): void
    }

    class State {
        + Handle(context: Context): void
    }

    class ConcreteStateA
    class ConcreteStateB

    Context --> State
    State <|.. ConcreteStateA
    State <|.. ConcreteStateB

状态模式的实现方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
using System;

// 抽象状态类
public abstract class State
{
public abstract void Handle(Context context);
}

// 具体状态类 A
public class ConcreteStateA : State
{
public override void Handle(Context context)
{
Console.WriteLine("Handling with ConcreteStateA");
// 在具体状态类中可以改变上下文的状态
context.SetState(new ConcreteStateB());
}
}

// 具体状态类 B
public class ConcreteStateB : State
{
public override void Handle(Context context)
{
Console.WriteLine("Handling with ConcreteStateB");
// 在具体状态类中可以改变上下文的状态
context.SetState(new ConcreteStateA());
}
}

// 上下文类
public class Context
{
private State state;

public Context(State initialState)
{
this.state = initialState;
}

public void Request()
{
// 上下文类将请求委托给当前状态处理
state.Handle(this);
}

public void SetState(State newState)
{
this.state = newState;
}
}

状态模式的应用场景

状态模式适用于以下情况:

  1. 一个对象的行为取决于它的状态,并且它必须在运行时根据状态改变它的行为。
  2. 一个操作中含有大量的条件语句,并且这些条件语句的目的是根据对象的状态选择不同的行为。
  3. 一个对象需要根据内部状态来改变它的状态。

状态模式的优势

  1. 封装性好: 状态模式将一个对象的状态封装到不同的状态类中,使得每个状态类的实现都相对独立,便于维护和扩展。
  2. 可扩展性: 可以轻松地增加新的状态类,扩展系统的功能。
  3. 避免条件语句: 状态模式通过将不同的状态分离,避免了大量的条件语句,使得代码更加清晰。

使用示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Program
{
static void Main()
{
// 创建上下文对象,初始状态为 ConcreteStateA
Context context = new Context(new ConcreteStateA());

// 发起请求,由 ConcreteStateA 处理
context.Request();

// 发起请求,由 ConcreteStateB 处理
context.Request();
}
}

总结

状态模式是一种行为型设计模式,通过将对象的状态和行为分离,使得对象在不同的状态下可以选择不同的行为。状态模式适用于一个对象的行为取决于其内部状态,并且需要在运行时根据状态改变行为的场景。在实际应用中,状态模式常用于处理有限状态机、状态切换等场景。

中介者模式 - 行为型模式的协调调停者

在软件设计中,中介者模式是一种行为型设计模式,它定义了一个中介者对象,该对象封装了一组对象之间的交互方式。中介者模式使得对象之间不直接相互通信,而是通过中介者对象进行协调,降低了对象之间的耦合性。本文将深入讨论中介者模式的概念、实现方式以及在实际应用中的使用场景。

中介者模式的概念

中介者模式(Mediator Pattern)是一种行为型设计模式,其核心思想是定义一个中介者对象,该对象封装了一组对象之间的交互方式。中介者模式使得对象之间不直接相互通信,而是通过中介者对象进行协调。这样的设计降低了对象之间的耦合性,使得系统更加灵活和易于维护。

中介者模式的 UML 类图

classDiagram
    class Mediator {
        + RegisterColleague(colleague: Colleague): void
        + SendMessage(colleague: Colleague, message: string): void
    }

    class Colleague {
        - mediator: Mediator
        + Send(message: string): void
        + Receive(message: string): void
    }

    class ConcreteMediator {
        - colleagues: List
        + RegisterColleague(colleague: Colleague): void
        + SendMessage(colleague: Colleague, message: string): void
    }

    class ConcreteColleagueA
    class ConcreteColleagueB

    Mediator <|.. ConcreteMediator
    Colleague <|.. ConcreteColleagueA
    Colleague <|.. ConcreteColleagueB

中介者模式的实现方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
using System;
using System.Collections.Generic;

// 抽象中介者
public interface Mediator
{
void RegisterColleague(Colleague colleague);
void SendMessage(Colleague colleague, string message);
}

// 抽象同事类
public abstract class Colleague
{
protected Mediator mediator;

public Colleague(Mediator mediator)
{
this.mediator = mediator;
}

public abstract void Send(string message);
public abstract void Receive(string message);
}

// 具体中介者
public class ConcreteMediator : Mediator
{
private List<Colleague> colleagues;

public ConcreteMediator()
{
this.colleagues = new List<Colleague>();
}

public void RegisterColleague(Colleague colleague)
{
colleagues.Add(colleague);
}

public void SendMessage(Colleague colleague, string message)
{
foreach (var c in colleagues)
{
if (c != colleague)
{
c.Receive(message);
}
}
}
}

// 具体同事类A
public class ConcreteColleagueA : Colleague
{
public ConcreteColleagueA(Mediator mediator) : base(mediator) { }

public override void Send(string message)
{
Console.WriteLine("Colleague A sends message: " + message);
mediator.SendMessage(this, message);
}

public override void Receive(string message)
{
Console.WriteLine("Colleague A receives message: " + message);
}
}

// 具体同事类B
public class ConcreteColleagueB : Colleague
{
public ConcreteColleagueB(Mediator mediator) : base(mediator) { }

public override void Send(string message)
{
Console.WriteLine("Colleague B sends message: " + message);
mediator.SendMessage(this, message);
}

public override void Receive(string message)
{
Console.WriteLine("Colleague B receives message: " + message);
}
}

中介者模式的应用场景

中介者模式适用于以下情况:

  1. 一组对象之间存在复杂的交互关系,导致它们之间的通信结构复杂难以理解。
  2. 对象之间的交互行为需要随时变化,或者需要增加新的对象时。
  3. 系统中的对象由于通信关系过于紧密,导致它们之间的耦合性较高。

中介者模式的优势

  1. 降低耦合性: 中介者模式通过将对象之间的通信集中在中介者中,降低了对象之间的耦合性。
  2. 简化对象交互: 中介者模式将对象之间的交互方式封装在中介者中,使得对象之间的通信更加简单清晰。
  3. 易于扩展: 可以通过增加新的同事类和调整中介者的实现,轻松地扩展系统。

使用示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Program
{
static void Main()
{
// 创建具体中介者对象
ConcreteMediator mediator = new ConcreteMediator();

// 创建具体同事类对象,并注册到中介者
ConcreteColleagueA colleagueA = new ConcreteColleagueA(mediator);
ConcreteColleagueB colleagueB = new ConcreteColleagueB(mediator);
mediator.RegisterColleague(colleagueA);
mediator.RegisterColleague(colleagueB);

// 同事类之间通过中介者进行通信
colleagueA.Send("Hello from Colleague A");
colleagueB.Send("Hi from Colleague B");
}
}

总结

中介者模式是一种行为型设计模式,通过定义一个中介者对象,封装了一组对象之间的交互方式,降低了对象之间的耦合性。中介者模式使得对象之间不直接相互通信,而是通过中介者对象进行协调。在实际应用中