在软件工程中,设计模式(Design Pattern) 是在特定场景下反复实践、被验证有效的通用设计方案。它不是可直接粘贴的代码片段,而是解决特定问题的设计思想与代码结构模板,是面试、日常开发、系统设计的核心知识点。
GoF(Gamma 等 4 位作者)提出的 23 种经典设计模式,按照解决问题的核心关注点,可清晰分为三大类,核心定位如下:
| 分类 | 核心关注点 | 设计目标 |
|---|---|---|
| 创建型 | 对象如何创建 | 解耦“对象创建”与“对象使用” |
| 行为型 | 对象如何协作、职责如何分配 | 规范交互逻辑,降低协作复杂度 |
| 结构型 | 类/对象如何组合 | 优化结构,降低耦合,提升扩展 |
一、创建型设计模式(5 种)
核心目标:解耦“对象的创建”和“对象的使用” 避免直接
new对象导致的耦合过高、创建逻辑混乱问题,让对象创建更灵活、可扩展。
1️⃣ 单例模式(Singleton)
设计意图:确保一个类在整个系统中仅有唯一实例,并提供全局统一的访问入口。 典型场景:
- 全局配置管理器(如 AppSettings 单例)
- 日志组件(避免多实例写日志冲突)
- 缓存对象(保证缓存数据一致性)
// 饿汉式(线程安全,推荐简单场景使用)
public sealed class Singleton
{
// 静态初始化,CLR 保证线程安全
private static readonly Singleton _instance = new Singleton();
// 私有构造函数,禁止外部实例化
private Singleton() { }
// 全局访问点
public static Singleton Instance => _instance;
// 示例方法:验证单例唯一性
public void DoSomething() => Console.WriteLine("单例对象执行操作");
}
// 调用示例
// var singleton1 = Singleton.Instance;
// var singleton2 = Singleton.Instance;
// Console.WriteLine(singleton1 == singleton2); // 输出:True
2️⃣ 简单工厂模式(Simple Factory)
设计意图:由一个工厂类封装所有对象的创建逻辑,调用方只需传入参数,无需关心对象的具体创建过程。 典型场景:
- 业务层创建不同类型的业务对象(如不同支付方式:微信/支付宝)
- 基础组件创建不同格式的解析器(JSON/XML)
// 抽象产品接口
public interface ICar
{
void Drive(); // 产品核心行为
}
// 具体产品:宝马
public class Bmw : ICar
{
public void Drive() => Console.WriteLine("驾驶宝马汽车");
}
// 具体产品:奔驰
public class Benz : ICar
{
public void Drive() => Console.WriteLine("驾驶奔驰汽车");
}
// 工厂类:封装创建逻辑
public class CarFactory
{
// 根据参数创建不同产品
public static ICar CreateCar(string carType)
{
return carType.ToUpper() switch
{
"BMW" => new Bmw(),
"BENZ" => new Benz(),
_ => throw new NotSupportedException($"不支持创建{carType}类型的汽车")
};
}
}
// 调用示例
// ICar car = CarFactory.CreateCar("BMW");
// car.Drive(); // 输出:驾驶宝马汽车
3️⃣ 工厂方法模式(Factory Method)
设计意图:将对象创建延迟到子类实现,每个子类对应一种产品创建,符合开闭原则(新增产品无需修改原有代码)。 典型场景:
- 电商系统:不同商家对应不同的订单工厂(京东订单/淘宝订单)
- 框架扩展:自定义插件的创建(如 EF Core 不同数据库的上下文工厂)
// 抽象产品
public interface ICar
{
void Drive();
}
// 具体产品:宝马
public class Bmw : ICar
{
public void Drive() => Console.WriteLine("驾驶宝马汽车");
}
// 抽象工厂:定义创建产品的接口
public interface ICarFactory
{
ICar CreateCar(); // 工厂方法
}
// 具体工厂:宝马工厂(负责创建宝马)
public class BmwFactory : ICarFactory
{
public ICar CreateCar() => new Bmw();
}
// 调用示例
// ICarFactory factory = new BmwFactory();
// ICar car = factory.CreateCar();
// car.Drive(); // 输出:驾驶宝马汽车
4️⃣ 建造者模式(Builder)
设计意图:将复杂对象的构建过程拆分为多个步骤,分步构建,避免“构造函数参数爆炸”问题,同时支持不同组合的对象创建。 典型场景:
- 创建复杂实体(如订单对象:包含商品、收货地址、支付信息等)
- 生成结构化文档(如 PDF:分步设置标题、正文、页码)
// 复杂产品:汽车(包含多个组件)
public class Car
{
public string Engine { get; set; } // 发动机
public string Wheel { get; set; } // 轮胎
public string Seat { get; set; } // 座椅
}
// 建造者:封装构建步骤
public class CarBuilder
{
private readonly Car _car = new Car(); // 待构建的产品
// 分步构建:设置发动机
public CarBuilder BuildEngine(string engineType)
{
_car.Engine = engineType;
return this; // 链式调用
}
// 分步构建:设置轮胎
public CarBuilder BuildWheel(string wheelBrand)
{
_car.Wheel = wheelBrand;
return this;
}
// 最终构建:返回成品
public Car Build() => _car;
}
// 调用示例
// Car car = new CarBuilder()
// .BuildEngine("V8 发动机")
// .BuildWheel("米其林轮胎")
// .Build();
// Console.WriteLine($"发动机:{car.Engine},轮胎:{car.Wheel}");
5️⃣ 原型模式(Prototype)
设计意图:通过复制(克隆)已有对象(原型)创建新对象,避免重复执行复杂的初始化逻辑,提升创建效率。 典型场景:
- 游戏开发:复制游戏角色(基础属性相同,仅修改少量参数)
- 大数据场景:复制基础查询条件对象(仅修改分页参数)
// 原型接口:实现 ICloneable
public class UserPrototype : ICloneable
{
public string Name { get; set; }
public int Age { get; set; }
public List<string> Roles { get; set; } = new List<string>();
// 浅克隆(值类型复制,引用类型复制引用)
public object Clone()
{
// MemberwiseClone:CLR 内置浅克隆方法
return this.MemberwiseClone();
}
// 深克隆(引用类型也复制新实例)
public UserPrototype DeepClone()
{
var clone = (UserPrototype)this.MemberwiseClone();
clone.Roles = new List<string>(this.Roles); // 重新创建集合
return clone;
}
}
// 调用示例
// UserPrototype prototype = new UserPrototype { Name = "张三", Age = 25 };
// prototype.Roles.Add("管理员");
// UserPrototype clone = (UserPrototype)prototype.Clone();
// Console.WriteLine(clone.Name); // 输出:张三
二、行为型设计模式(11 种)
核心目标:规范对象协作方式,明确职责边界 解决多个对象交互时的逻辑混乱、职责耦合问题,让协作更清晰、可扩展。
6️⃣ 策略模式(Strategy)
设计意图:将不同算法封装为独立的策略类,算法可自由替换,且算法变化不影响调用方。 典型场景:
- 电商折扣:普通用户/会员/VIP 不同折扣策略
- 支付方式:微信支付/支付宝/银行卡不同支付逻辑
// 策略接口:定义算法规范
public interface IDiscountStrategy
{
decimal Calculate(decimal originalPrice); // 计算折扣后价格
}
// 具体策略:VIP 8 折
public class VipDiscount : IDiscountStrategy
{
public decimal Calculate(decimal originalPrice) => originalPrice * 0.8m;
}
// 具体策略:普通用户无折扣
public class NormalDiscount : IDiscountStrategy
{
public decimal Calculate(decimal originalPrice) => originalPrice;
}
// 上下文:调用策略(屏蔽策略细节)
public class PriceContext
{
private readonly IDiscountStrategy _strategy;
// 注入策略
public PriceContext(IDiscountStrategy strategy)
{
_strategy = strategy;
}
// 对外提供统一计算方法
public decimal GetFinalPrice(decimal originalPrice)
{
return _strategy.Calculate(originalPrice);
}
}
// 调用示例
// PriceContext context = new PriceContext(new VipDiscount());
// Console.WriteLine(context.GetFinalPrice(100)); // 输出:80
7️⃣ 模板方法模式(Template Method)
设计意图:在父类中定义算法的固定骨架,将可变的具体步骤延迟到子类实现,复用通用逻辑,扩展可变逻辑。 典型场景:
- 流程化操作:登录流程(通用步骤:验证→处理→返回;可变步骤:验证方式)
- 框架开发:控制器基类(通用:请求接收→响应封装;可变:业务处理)
// 抽象父类:定义算法骨架
public abstract class AbstractOrderProcessor
{
// 模板方法:固定算法流程(禁止子类重写)
public void ProcessOrder()
{
ValidateOrder(); // 通用步骤1:验证订单
CalculateAmount(); // 可变步骤:计算金额
SaveOrder(); // 通用步骤2:保存订单
NotifyUser(); // 可变步骤:通知用户
}
// 通用步骤:父类实现
private void ValidateOrder() => Console.WriteLine("验证订单参数合法性");
private void SaveOrder() => Console.WriteLine("保存订单到数据库");
// 可变步骤:子类实现
protected abstract void CalculateAmount();
protected abstract void NotifyUser();
}
// 具体子类:实物订单处理器
public class PhysicalOrderProcessor : AbstractOrderProcessor
{
protected override void CalculateAmount()
{
Console.WriteLine("计算实物订单金额(含运费)");
}
protected override void NotifyUser()
{
Console.WriteLine("发送物流短信通知");
}
}
// 调用示例
// AbstractOrderProcessor processor = new PhysicalOrderProcessor();
// processor.ProcessOrder(); // 按固定流程执行
8️⃣ 观察者模式(Observer)
设计意图:定义“一对多”的依赖关系,当一个对象(主题)状态变化时,所有依赖它的对象(观察者)自动收到通知并更新。 典型场景:
- 事件通知:按钮点击后,多个组件响应(弹窗+日志+统计)
- 消息订阅:订单支付成功后,库存服务、积分服务、通知服务同步更新
// 观察者接口:定义更新方法
public interface IObserver
{
void Update(string message); // 接收主题通知
}
// 具体观察者:日志观察者
public class LogObserver : IObserver
{
public void Update(string message) => Console.WriteLine($"日志记录:{message}");
}
// 具体观察者:通知观察者
public class NotifyObserver : IObserver
{
public void Update(string message) => Console.WriteLine($"发送通知:{message}");
}
// 主题(被观察者):定义管理观察者和通知的接口
public class Subject
{
private readonly List<IObserver> _observers = new List<IObserver>();
// 注册观察者
public void Attach(IObserver observer) => _observers.Add(observer);
// 移除观察者
public void Detach(IObserver observer) => _observers.Remove(observer);
// 通知所有观察者
public void Notify(string message)
{
foreach (var observer in _observers)
{
observer.Update(message);
}
}
}
// 调用示例
// Subject subject = new Subject();
// subject.Attach(new LogObserver());
// subject.Attach(new NotifyObserver());
// subject.Notify("订单支付成功"); // 所有观察者收到通知
9️⃣ 责任链模式(Chain of Responsibility)
设计意图:将请求的处理者连成一条链,请求沿链传递,直到被某个处理者处理,避免请求发送者与接收者直接耦合。 典型场景:
- 权限校验:普通用户→VIP→管理员(不同级别处理不同权限请求)
- 异常处理:基础异常→业务异常→系统异常(逐级处理)
// 抽象处理者:定义处理接口和下一个处理者
public abstract class Handler
{
protected Handler _nextHandler; // 下一个处理者
// 设置下一个处理者(链式组装)
public Handler SetNext(Handler nextHandler)
{
_nextHandler = nextHandler;
return nextHandler;
}
// 抽象处理方法
public abstract void HandleRequest(int level);
}
// 具体处理者:初级处理者(处理级别1)
public class PrimaryHandler : Handler
{
public override void HandleRequest(int level)
{
if (level == 1)
{
Console.WriteLine("初级处理者处理请求");
}
else if (_nextHandler != null)
{
_nextHandler.HandleRequest(level); // 传递给下一个
}
}
}
// 具体处理者:高级处理者(处理级别2)
public class AdvancedHandler : Handler
{
public override void HandleRequest(int level)
{
if (level == 2)
{
Console.WriteLine("高级处理者处理请求");
}
else if (_nextHandler != null)
{
_nextHandler.HandleRequest(level);
}
}
}
// 调用示例
// Handler primary = new PrimaryHandler();
// Handler advanced = new AdvancedHandler();
// primary.SetNext(advanced); // 组装责任链
// primary.HandleRequest(2); // 高级处理者处理
🔟 命令模式(Command)
设计意图:将请求封装为独立的命令对象,使请求发送者与接收者解耦,支持请求的撤销、重试、队列化。 典型场景:
- 操作回滚:订单提交/撤销、支付/退款(命令可记录并反向执行)
- 界面操作:按钮点击(点击事件封装为命令,可复用)
// 命令接口:定义执行/撤销操作
public interface ICommand
{
void Execute(); // 执行命令
void Undo(); // 撤销命令
}
// 接收者:实际执行操作的对象(如电灯)
public class Light
{
public void TurnOn() => Console.WriteLine("电灯打开");
public void TurnOff() => Console.WriteLine("电灯关闭");
}
// 具体命令:开灯命令
public class LightOnCommand : ICommand
{
private readonly Light _light; // 关联接收者
public LightOnCommand(Light light) => _light = light;
public void Execute() => _light.TurnOn();
public void Undo() => _light.TurnOff();
}
// 调用者:触发命令(如遥控器)
public class RemoteControl
{
private ICommand _command;
// 设置要执行的命令
public void SetCommand(ICommand command) => _command = command;
// 执行命令
public void PressButton() => _command.Execute();
// 撤销命令
public void PressUndo() => _command.Undo();
}
// 调用示例
// Light light = new Light();
// ICommand onCommand = new LightOnCommand(light);
// RemoteControl remote = new RemoteControl();
// remote.SetCommand(onCommand);
// remote.PressButton(); // 开灯
// remote.PressUndo(); // 关灯
11️⃣ 状态模式(State)
设计意图:将对象的不同状态封装为独立的状态类,对象状态变化时自动切换行为,替代大量 if-else 判断。
典型场景:
- 订单状态:待支付→已支付→已发货→已完成(不同状态对应不同行为)
- 电梯状态:空闲→运行→停止→故障(不同状态响应不同操作)
// 状态接口:定义状态对应的行为
public interface IOrderState
{
void Handle(OrderContext context); // 处理当前状态的逻辑
}
// 具体状态:待支付
public class PendingPayState : IOrderState
{
public void Handle(OrderContext context)
{
Console.WriteLine("订单待支付:可执行支付/取消操作");
// 状态切换:支付后变为已支付
context.State = new PaidState();
}
}
// 具体状态:已支付
public class PaidState : IOrderState
{
public void Handle(OrderContext context)
{
Console.WriteLine("订单已支付:可执行发货操作");
}
}
// 上下文:维护当前状态,提供状态切换入口
public class OrderContext
{
// 当前状态
public IOrderState State { get; set; }
public OrderContext(IOrderState initialState)
{
State = initialState;
}
// 执行当前状态的行为
public void Process() => State.Handle(this);
}
// 调用示例
// OrderContext order = new OrderContext(new PendingPayState());
// order.Process(); // 执行待支付逻辑,切换为已支付状态
// order.Process(); // 执行已支付逻辑
12️⃣ 备忘录模式(Memento)
设计意图:保存对象的内部状态,在需要时恢复到指定状态,且不暴露对象的内部结构。 典型场景:
- 编辑器撤销:保存文档历史版本,支持撤销操作
- 游戏存档:保存游戏角色状态,可回滚到之前的存档
// 备忘录:存储对象状态(不可修改)
public class Memento
{
// 要保存的状态(如文档内容)
public string Content { get; }
public Memento(string content) => Content = content;
}
// 原发器:创建/恢复备忘录
public class Editor
{
public string Content { get; set; } // 当前状态
// 创建备忘录(保存当前状态)
public Memento Save() => new Memento(Content);
// 恢复备忘录(回滚状态)
public void Restore(Memento memento) => Content = memento.Content;
}
// 管理者:管理备忘录(不修改,仅存储)
public class Caretaker
{
private readonly List<Memento> _history = new List<Memento>();
// 保存备忘录
public void Add(Memento memento) => _history.Add(memento);
// 获取指定版本的备忘录
public Memento Get(int index) => _history[index];
}
// 调用示例
// Editor editor = new Editor { Content = "初始内容" };
// Caretaker caretaker = new Caretaker();
// caretaker.Add(editor.Save()); // 保存初始状态
// editor.Content = "修改后的内容";
// editor.Restore(caretaker.Get(0)); // 恢复到初始状态
// Console.WriteLine(editor.Content); // 输出:初始内容
13️⃣ 访问者模式(Visitor)
设计意图:将对象的操作与对象结构分离,新增操作时无需修改对象结构,仅新增访问者类。 典型场景:
- 数据导出:对不同类型的报表(订单/用户/商品)统一导出为Excel/PDF
- 节点遍历:对树形结构的不同节点(文件夹/文件)执行不同操作(删除/复制)
// 元素接口:接受访问者
public interface IElement
{
void Accept(IVisitor visitor);
}
// 具体元素:订单元素
public class OrderElement : IElement
{
public decimal Amount { get; set; } = 1000;
public void Accept(IVisitor visitor)
{
visitor.Visit(this); // 接受访问者访问
}
}
// 具体元素:用户元素
public class UserElement : IElement
{
public string Name { get; set; } = "张三";
public void Accept(IVisitor visitor)
{
visitor.Visit(this);
}
}
// 访问者接口:定义对不同元素的操作
public interface IVisitor
{
void Visit(OrderElement order);
void Visit(UserElement user);
}
// 具体访问者:导出Excel访问者
public class ExcelExportVisitor : IVisitor
{
public void Visit(OrderElement order)
{
Console.WriteLine($"导出订单到Excel:金额{order.Amount}");
}
public void Visit(UserElement user)
{
Console.WriteLine($"导出用户到Excel:姓名{user.Name}");
}
}
// 调用示例
// List<IElement> elements = new List<IElement>
// {
// new OrderElement(),
// new UserElement()
// };
// IVisitor visitor = new ExcelExportVisitor();
// foreach (var element in elements)
// {
// element.Accept(visitor); // 统一执行导出操作
// }
14️⃣ 中介者模式(Mediator)
设计意图:引入中介者对象封装多个对象之间的交互,减少对象间的直接耦合,所有交互通过中介者完成。 典型场景:
- 聊天室:用户发送消息无需直接联系对方,通过聊天室(中介者)转发
- 表单组件:输入框、按钮、提示框的交互由表单中介者统一管理
// 中介者接口:定义对象交互的方法
public interface IChatMediator
{
void SendMessage(string message, User user); // 转发消息
void AddUser(User user); // 添加用户
}
// 具体中介者:聊天室
public class ChatRoom : IChatMediator
{
private readonly List<User> _users = new List<User>();
public void AddUser(User user) => _users.Add(user);
public void SendMessage(string message, User sender)
{
// 转发消息给所有非发送者
foreach (var user in _users)
{
if (user != sender)
{
user.Receive(message);
}
}
}
}
// 同事类:用户(所有交互通过中介者)
public class User
{
private readonly IChatMediator _mediator;
public string Name { get; }
public User(IChatMediator mediator, string name)
{
_mediator = mediator;
Name = name;
}
// 发送消息(通过中介者)
public void Send(string message)
{
Console.WriteLine($"{Name} 发送消息:{message}");
_mediator.SendMessage(message, this);
}
// 接收消息
public void Receive(string message)
{
Console.WriteLine($"{Name} 接收消息:{message}");
}
}
// 调用示例
// IChatMediator room = new ChatRoom();
// User user1 = new User(room, "张三");
// User user2 = new User(room, "李四");
// room.AddUser(user1);
// room.AddUser(user2);
// user1.Send("你好!"); // 李四接收消息
15️⃣ 解释器模式(Interpreter)
设计意图:定义语言的语法规则,并构建解释器来解释该语言的表达式,处理简单的语法解析。 典型场景:
- 简单公式计算:解析“1+2*3”等表达式
- 规则引擎:解析自定义的业务规则(如“年龄>18 且 金额>1000”)
// 抽象表达式
public abstract class Expression
{
public abstract int Interpret(); // 解释表达式
}
// 终结符表达式:数字
public class NumberExpression : Expression
{
private readonly int _number;
public NumberExpression(int number) => _number = number;
public override int Interpret() => _number;
}
// 非终结符表达式:加法
public class AddExpression : Expression
{
private readonly Expression _left;
private readonly Expression _right;
public AddExpression(Expression left, Expression right)
{
_left = left;
_right = right;
}
public override int Interpret()
{
return _left.Interpret() + _right.Interpret();
}
}
// 调用示例
// // 解析 1 + 2
// Expression expression = new AddExpression(new NumberExpression(1), new NumberExpression(2));
// Console.WriteLine(expression.Interpret()); // 输出:3
16️⃣ 迭代器模式(Iterator)
设计意图:提供统一的方式遍历集合对象,屏蔽不同集合(数组/列表/哈希表)的底层遍历实现。 典型场景:
- 自定义集合:为自定义容器(如树形集合)提供遍历接口
- 统一遍历:对不同类型的集合执行相同的遍历逻辑
// 迭代器接口:定义遍历方法
public interface IIterator<T>
{
bool HasNext(); // 是否有下一个元素
T Next(); // 获取下一个元素
}
// 具体迭代器:列表迭代器
public class ListIterator<T> : IIterator<T>
{
private readonly List<T> _list;
private int _index = 0;
public ListIterator(List<T> list) => _list = list;
public bool HasNext() => _index < _list.Count;
public T Next() => _list[_index++];
}
// 聚合接口:定义创建迭代器的方法
public interface IAggregate<T>
{
IIterator<T> CreateIterator(); // 创建迭代器
}
// 具体聚合:自定义列表
public class CustomList<T> : IAggregate<T>
{
private readonly List<T> _list = new List<T>();
public void Add(T item) => _list.Add(item);
public IIterator<T> CreateIterator()
{
return new ListIterator<T>(_list);
}
}
// 调用示例
// CustomList<string> list = new CustomList<string>();
// list.Add("A");
// list.Add("B");
// IIterator<string> iterator = list.CreateIterator();
// while (iterator.HasNext())
// {
// Console.WriteLine(iterator.Next()); // 输出:A、B
// }
三、结构型设计模式(7 种)
核心目标:优化类/对象的组合关系 通过灵活的结构设计,解决类/对象耦合过高、扩展困难、结构复杂的问题。
17️⃣ 适配器模式(Adapter)
设计意图:将一个类的接口转换为客户端期望的另一个接口,使原本接口不兼容的类可以协同工作。 典型场景:
- 第三方组件集成:老系统接口适配新框架接口
- 数据格式转换:JSON 数据适配 XML 解析接口
// 目标接口:客户端期望的接口
public interface INewPaymentService
{
void Pay(decimal amount); // 新支付接口
}
// 适配者:已有但接口不兼容的类
public class OldWeChatPay
{
// 老接口(参数/方法名与新接口不一致)
public void DoWeChatPay(double money)
{
Console.WriteLine($"微信支付:{money} 元");
}
}
// 适配器:将老接口适配为新接口
public class WeChatPayAdapter : INewPaymentService
{
private readonly OldWeChatPay _oldPay = new OldWeChatPay();
// 适配老接口
public void Pay(decimal amount)
{
// 类型转换 + 调用老方法
_oldPay.DoWeChatPay(Convert.ToDouble(amount));
}
}
// 调用示例
// INewPaymentService payService = new WeChatPayAdapter();
// payService.Pay(100); // 输出:微信支付:100 元
18️⃣ 装饰器模式(Decorator)
设计意图:动态地给对象添加额外功能,且不修改原对象的结构,功能可叠加。 典型场景:
- 功能增强:日志装饰器(给接口添加日志)、缓存装饰器(给查询添加缓存)
- IO 流包装:Java IO 的 BufferedInputStream(装饰基础流)
// 组件接口:定义核心功能
public interface IDataService
{
void GetData(); // 核心功能:获取数据
}
// 具体组件:基础实现
public class BasicDataService : IDataService
{
public void GetData() => Console.WriteLine("获取基础数据");
}
// 装饰器抽象类:实现组件接口,关联被装饰对象
public abstract class DataServiceDecorator : IDataService
{
protected readonly IDataService _service;
public DataServiceDecorator(IDataService service) => _service = service;
// 默认调用被装饰对象的方法
public virtual void GetData() => _service.GetData();
}
// 具体装饰器:日志装饰(添加日志功能)
public class LogDecorator : DataServiceDecorator
{
public LogDecorator(IDataService service) : base(service) { }
public override void GetData()
{
Console.WriteLine("日志:开始获取数据"); // 新增功能
base.GetData(); // 调用原功能
Console.WriteLine("日志:获取数据完成"); // 新增功能
}
}
// 调用示例
// IDataService service = new LogDecorator(new BasicDataService());
// service.GetData(); // 输出日志 + 基础数据获取
19️⃣ 代理模式(Proxy)
设计意图:为目标对象提供一个代理对象,控制对目标对象的访问(如权限校验、缓存、远程访问)。 典型场景:
- 权限控制:代理接口访问,校验用户权限
- 远程代理:RPC 框架中,本地代理调用远程服务
- 缓存代理:缓存查询结果,避免重复查询
// 主题接口:定义目标对象和代理的共同接口
public interface IProductService
{
void GetProductInfo(int id); // 获取产品信息
}
// 真实主题:目标对象(实际执行业务)
public class ProductService : IProductService
{
public void GetProductInfo(int id)
{
Console.WriteLine($"查询产品{id}的详细信息(数据库查询)");
}
}
// 代理:控制对目标对象的访问(添加缓存逻辑)
public class ProductServiceProxy : IProductService
{
private readonly IProductService _realService = new ProductService();
private readonly Dictionary<int, string> _cache = new Dictionary<int, string>();
public void GetProductInfo(int id)
{
// 缓存校验:有缓存则直接返回,无则调用真实对象
if (_cache.ContainsKey(id))
{
Console.WriteLine($"缓存:{_cache[id]}");
}
else
{
_realService.GetProductInfo(id); // 调用真实对象
_cache[id] = $"产品{id}缓存数据"; // 存入缓存
}
}
}
// 调用示例
// IProductService proxy = new ProductServiceProxy();
// proxy.GetProductInfo(1); // 数据库查询
// proxy.GetProductInfo(1); // 缓存返回
20️⃣ 外观模式(Facade)
设计意图:为复杂的子系统提供一个统一的简化接口,屏蔽子系统的复杂逻辑,降低客户端使用成本。 典型场景:
- 支付流程:整合“校验→扣款→通知→日志”等子系统,提供统一的 Pay 接口
- 框架封装:ORM 框架封装数据库连接、SQL 执行、事务等逻辑
// 子系统1:库存服务
public class InventoryService
{
public void ReduceStock(int productId)
{
Console.WriteLine($"扣减产品{productId}库存");
}
}
// 子系统2:支付服务
public class PaymentService
{
public void DeductMoney(decimal amount)
{
Console.WriteLine($"扣除金额{amount}元");
}
}
// 子系统3:通知服务
public class NotifyService
{
public void SendMessage()
{
Console.WriteLine("发送支付成功通知");
}
}
// 外观类:封装子系统,提供统一接口
public class OrderFacade
{
private readonly InventoryService _inventory = new InventoryService();
private readonly PaymentService _payment = new PaymentService();
private readonly NotifyService _notify = new NotifyService();
// 统一的下单接口
public void CreateOrder(int productId, decimal amount)
{
_inventory.ReduceStock(productId); // 调用子系统1
_payment.DeductMoney(amount); // 调用子系统2
_notify.SendMessage(); // 调用子系统3
}
}
// 调用示例
// OrderFacade facade = new OrderFacade();
// facade.CreateOrder(1, 100); // 一键下单,无需关心子系统细节
21️⃣ 桥接模式(Bridge)
设计意图:将“抽象部分”与“实现部分”分离,使两者可以独立变化,解决多维度变化导致的类爆炸问题。 典型场景:
- 图形绘制:形状(圆形/方形)与颜色(红色/蓝色)两个维度独立扩展
- 支付系统:支付方式(微信/支付宝)与支付场景(APP/网页)独立扩展
// 实现部分接口:颜色(独立变化维度)
public interface IColor
{
string GetColor(); // 获取颜色
}
// 具体实现:红色
public class RedColor : IColor
{
public string GetColor() => "红色";
}
// 具体实现:蓝色
public class BlueColor : IColor
{
public string GetColor() => "蓝色";
}
// 抽象部分:形状(独立变化维度)
public abstract class Shape
{
protected IColor _color; // 桥接实现部分
public Shape(IColor color) => _color = color;
// 抽象方法:绘制
public abstract void Draw();
}
// 具体抽象:圆形
public class Circle : Shape
{
public Circle(IColor color) : base(color) { }
public override void Draw()
{
Console.WriteLine($"绘制{_color.GetColor()}的圆形");
}
}
// 调用示例
// Shape redCircle = new Circle(new RedColor());
// redCircle.Draw(); // 输出:绘制红色的圆形
// Shape blueCircle = new Circle(new BlueColor());
// blueCircle.Draw(); // 输出:绘制蓝色的圆形
22️⃣ 组合模式(Composite)
设计意图:将对象组合成树形结构,统一处理单个对象和组合对象(叶子节点/容器节点),无需区分处理。 典型场景:
- 文件系统:文件夹(容器)包含文件(叶子)和子文件夹,统一遍历/删除
- 组织架构:公司→部门→员工,统一统计人数/计算薪资
// 组件接口:定义叶子和容器的共同方法
public interface IOrganization
{
void Display(int depth); // 显示层级结构
int GetCount(); // 统计数量
}
// 叶子节点:员工
public class Employee : IOrganization
{
private readonly string _name;
public Employee(string name) => _name = name;
public void Display(int depth)
{
Console.WriteLine(new string('-', depth) + _name);
}
public int GetCount() => 1; // 单个员工,数量为1
}
// 容器节点:部门(包含员工/子部门)
public class Department : IOrganization
{
private readonly string _name;
private readonly List<IOrganization> _children = new List<IOrganization>();
public Department(string name) => _name = name;
// 添加子节点
public void Add(IOrganization org) => _children.Add(org);
public void Display(int depth)
{
Console.WriteLine(new string('-', depth) + _name);
// 递归显示子节点
foreach (var child in _children)
{
child.Display(depth + 2);
}
}
public int GetCount()
{
// 统计所有子节点数量
return _children.Sum(c => c.GetCount());
}
}
// 调用示例
// // 构建组织架构:研发部→前端组→员工
// Department rdDept = new Department("研发部");
// Department feGroup = new Department("前端组");
// feGroup.Add(new Employee("张三"));
// feGroup.Add(new Employee("李四"));
// rdDept.Add(feGroup);
// rdDept.Display(1); // 显示层级结构
// Console.WriteLine($"总人数:{rdDept.GetCount()}"); // 输出:2
23️⃣ 享元模式(Flyweight)
设计意图:复用系统中频繁创建的相似对象,减少对象实例数量,降低内存消耗。 典型场景:
- 缓存池:线程池、数据库连接池(复用连接/线程)
- 大量细粒度对象:游戏中的粒子、界面中的按钮样式
// 享元对象:包含共享状态(不可变)和非共享状态(可变)
public class Flyweight
{
// 共享状态(如字体样式)
public string Font { get; }
public Flyweight(string font) => Font = font;
// 执行操作(非共享状态作为参数传入)
public void Display(string text)
{
Console.WriteLine($"字体:{Font},内容:{text}");
}
}
// 享元工厂:管理享元对象,复用已有实例
public class FlyweightFactory
{
// 缓存池:存储已创建的享元对象
private readonly Dictionary<string, Flyweight> _pool = new Dictionary<string, Flyweight>();
// 获取享元对象(有则复用,无则创建)
public Flyweight GetFlyweight(string font)
{
if (!_pool.ContainsKey(font))
{
_pool[font] = new Flyweight(font);
Console.WriteLine($"创建新享元:{font}");
}
return _pool[font];
}
// 获取缓存池大小
public int GetPoolSize() => _pool.Count;
}
// 调用示例
// FlyweightFactory factory = new FlyweightFactory();
// Flyweight f1 = factory.GetFlyweight("宋体"); // 创建新享元
// f1.Display("Hello");
// Flyweight f2 = factory.GetFlyweight("宋体"); // 复用享元
// f2.Display("World");
// Console.WriteLine(factory.GetPoolSize()); // 输出:1
四、总结
核心要点回顾
- 三大分类核心定位:创建型解耦“对象创建”,行为型规范“对象协作”,结构型优化“对象组合”;
- 设计模式的本质:不是“炫技”,而是用成熟的结构解决特定问题,遵循 SOLID 原则,提升代码可维护性和扩展性;
- 使用原则:按需选择,不生搬硬套(如简单场景用简单工厂,无需强行用工厂方法)。