学习创建结构行为设计模式
📚 目录
前置知识:设计原则
在深入学习设计模式之前,必须掌握三个核心设计原则,它们是所有设计模式的基石:
1. 面向接口编程,而非面向实现
这是编写可扩展、优雅代码的基础。通过接口定义契约,而不是依赖具体实现类。
好处:
- 降低耦合度
- 提高代码灵活性
- 便于单元测试
2. 职责单一原则 (SRP)
每个类只负责一个单一功能,且该功能由该类完全封装。
好处:
- 代码更清晰易懂
- 修改影响范围小
- 便于复用和测试
3. 开闭原则 (OCP)
对修改关闭,对扩展开放。
核心思想:
- 已完成的功能和修复的bug不应该被随意修改
- 代码应该易于扩展新功能
- 通过抽象和多态实现扩展

一、创建型模式
核心作用: 提供友好的对象创建方式,封装对象创建逻辑,降低客户端使用复杂度。
1. 简单工厂模式 (Simple Factory)
核心思想
通过一个工厂类的静态方法,根据入参返回不同父类/接口的实例对象,将对象创建逻辑集中在工厂中。
代码示例
java
public class FoodFactory {
public static Food makeFood(String name) {
if (name.equals("noodle")) {
Food noodle = new LanZhouNoodle();
noodle.addSpicy("more");
return noodle;
} else if (name.equals("chicken")) {
Food chicken = new HuangMenChicken();
chicken.addCondiment("potato");
return chicken;
} else {
return null;
}
}
}
适用场景
- 创建逻辑简单
- 不需要多维度扩展
- 对象数量较少
优点
✅ 符合职责单一原则
✅ 工厂类只负责生产各类Food
✅ 客户端无需关心创建细节
缺点
❌ 不符合开闭原则,新增产品需要修改工厂类
2. 工厂模式 (Factory Method)
核心思想
解决简单工厂模式不易扩展的问题,通过抽象工厂接口,让不同工厂实现类负责创建不同类型的对象。
实现步骤
- 定义工厂接口
java
public interface FoodFactory {
Food makeFood(String name);
}
- 不同工厂实现
java
// 中餐工厂
public class ChineseFoodFactory implements FoodFactory {
@Override
public Food makeFood(String name) {
if (name.equals("A")) return new ChineseFoodA();
else if (name.equals("B")) return new ChineseFoodB();
else return null;
}
}
// 西餐工厂
public class AmericanFoodFactory implements FoodFactory {
@Override
public Food makeFood(String name) {
if (name.equals("A")) return new AmericanFoodA();
else if (name.equals("B")) return new AmericanFoodB();
else return null;
}
}
- 客户端调用
java
public class APP {
public static void main(String[] args) {
// 第一步:选择具体工厂
FoodFactory factory = new ChineseFoodFactory();
// 第二步:通过工厂创建对象
Food food = factory.makeFood("A");
}
}
适用场景
- 需要支持多种类型的对象创建
- 易于扩展新类型
- 客户端不需要知道具体产品类的创建细节
优点
✅ 符合开闭原则,扩展时只需新增工厂实现类
✅ 符合职责单一原则
✅ 客户端只需关心工厂接口
3. 抽象工厂模式 (Abstract Factory)
核心思想
解决「产品族兼容」问题。当多个产品需要配套使用时(比如Intel的CPU和AMD的主板不兼容),不再单独为每个产品定义工厂,而是定义「大厂工厂」,每个工厂负责生产整个产品族的所有产品,保证产品的兼容性。
代码示例
java
// 1. 定义抽象电脑工厂
public interface ComputerFactory {
CPU makeCPU();
MainBoard makeMainBoard();
HardDisk makeHardDisk();
}
// 2. 不同品牌工厂实现
public class AmdFactory implements ComputerFactory {
@Override
public CPU makeCPU() { return new AmdCPU(); }
@Override
public MainBoard makeMainBoard() { return new AmdMainBoard(); }
@Override
public HardDisk makeHardDisk() { return new AmdHardDisk(); }
}
// 3. 客户端调用
public static void main(String[] args) {
// 第一步:选择大厂
ComputerFactory cf = new AmdFactory();
// 第二步:从同一个工厂生产所有部件
CPU cpu = cf.makeCPU();
MainBoard board = cf.makeMainBoard();
HardDisk hardDisk = cf.makeHardDisk();
// 组装,保证兼容
Computer result = new Computer(cpu, board, hardDisk);
}
适用场景
- 产品需要配套使用
- 保证产品兼容性
- 强调产品族概念
优点
✅ 彻底解决产品族兼容问题
✅ 保证客户端始终只使用同一个产品族的产品
缺点
❌ 新增产品类型(比如加显示器)时,需要修改所有工厂,违反开闭原则
4. 单例模式 (Singleton)
核心思想
保证全局只有一个实例,常用于需要全局共享资源、控制资源访问的场景。
典型应用场景
- 日志对象
- 线程池
- 配置类
- 数据库连接池
- 缓存对象
三种常用实现方式
方式一:饿汉模式
java
public class Singleton {
private Singleton() {};
private static Singleton instance = new Singleton();
public static Singleton getInstance() {
return instance;
}
}
特点: 类加载时就实例化,实现简单,但可能会提前创建不需要的实例。
方式二:双重检查锁(推荐)
java
public class Singleton {
private Singleton() {}
private static volatile Singleton instance = null;
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
特点: 懒加载,只有在第一次调用时才创建实例,需要加volatile关键字防止指令重排。
方式三:静态内部类(最推荐)
java
public class Singleton3 {
private Singleton3() {}
private static class Holder {
private static Singleton3 instance = new Singleton3();
}
public static Singleton3 getInstance() {
return Holder.instance;
}
}
特点: 利用类加载机制保证线程安全,同时实现懒加载,静态内部类在外部类加载时不会加载,只有在调用getInstance()时才会加载并创建实例。
补充知识
- 枚举类型天生就是单例,JVM保证不会被多次实例化
- RxJava源码中大量使用枚举实现单例
5. 建造者模式 (Builder)
核心思想
解决「属性很多,且有必填/选填区分」的类的创建问题,通过链式调用设置属性,最后通过build()方法校验属性并创建对象。
代码示例
java
class User {
private String name;
private String password;
private String nickName;
private int age;
// 构造方法私有化
private User(String name, String password, String nickName, int age) {
this.name = name;
this.password = password;
this.nickName = nickName;
this.age = age;
}
// 静态方法返回Builder
public static UserBuilder builder() {
return new UserBuilder();
}
// 内部Builder类
public static class UserBuilder {
private String name;
private String password;
private String nickName;
private int age;
// 链式设置属性
public UserBuilder name(String name) {
this.name = name;
return this;
}
public UserBuilder password(String password) {
this.password = password;
return this;
}
public UserBuilder nickName(String nickName) {
this.nickName = nickName;
return this;
}
public UserBuilder age(int age) {
this.age = age;
return this;
}
// 构建方法,做参数校验
public User build() {
if (name == null || password == null) {
throw new RuntimeException("用户名和密码必填");
}
if (age <= 0 || age >= 150) {
throw new RuntimeException("年龄不合法");
}
if (nickName == null) {
nickName = name; // 设置默认值
}
return new User(name, password, nickName, age);
}
}
}
// 客户端调用
User user = User.builder()
.name("foo")
.password("pAss12345")
.age(25)
.build();
优化方案
使用Lombok的@Builder注解,自动生成Builder相关代码,大幅减少模板代码。
适用场景
- 属性多,有必填/选填区分
- 需要参数校验
- 需要设置默认值
6. 原型模式 (Prototype)
核心思想
通过复制(克隆)已有原型实例来创建新对象,而不是通过new创建。
实现方式
Java中需要实现Cloneable接口,重写Object的clone()方法。
java
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
重要注意事项
浅克隆 vs 深克隆:
- 浅克隆: Java默认实现,如果对象有引用类型的属性,克隆后的对象和原对象的引用属性会指向同一个对象
- 深克隆: 需要通过序列化、反序列化的方式实现,确保所有引用对象都被复制
适用场景
- 创建对象成本较高
- 需要复制对象的场景
- 对象初始化需要加载大量资源
创建型模式对比总结
| 模式 | 核心特点 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|---|
| 简单工厂 | 一个静态工厂方法根据入参返回不同实例 | 创建逻辑简单,不需要扩展 | 简单易懂 | 不符合开闭原则 |
| 工厂模式 | 先选工厂,再通过工厂创建对象 | 需要支持多种类型的对象创建 | 符合开闭原则 | 类数量增多 |
| 抽象工厂 | 一个工厂生产整个产品族的所有产品 | 产品需要配套使用 | 保证兼容性 | 不易扩展新产品类型 |
| 单例模式 | 全局唯一实例 | 共享资源、控制资源访问 | 节省资源 | 不易测试 |
| 建造者模式 | 链式设置属性,统一构建 | 属性多,有必填/选填区分 | 代码清晰,易校验 | 需要写Builder类 |
| 原型模式 | 克隆已有对象 | 创建对象成本高 | 性能好 | 深克隆实现复杂 |
二、结构型模式
核心作用: 通过改变代码结构实现解耦,让代码更易维护和扩展。
1. 代理模式 (Proxy)
核心思想
用一个代理类隐藏真实实现类的细节,在真实方法的前后添加增强逻辑。
典型应用场景
- 日志记录
- 权限校验
- 缓存处理
- 事务管理
- 性能监控
代码示例
java
// 1. 定义业务接口
public interface FoodService {
Food makeChicken();
Food makeNoodle();
}
// 2. 真实实现类
public class FoodServiceImpl implements FoodService {
public Food makeChicken() {
Food f = new Chicken();
f.setChicken("1kg");
f.setSpicy("1g");
f.setSalt("3g");
return f;
}
}
// 3. 代理类
public class FoodServiceProxy implements FoodService {
private FoodService foodService = new FoodServiceImpl();
public Food makeChicken() {
System.out.println("我们马上要开始制作鸡肉了");
Food food = foodService.makeChicken();
System.out.println("鸡肉制作完成啦,加点胡椒粉");
food.addCondiment("pepper");
return food;
}
}
// 4. 客户端调用
FoodService foodService = new FoodServiceProxy();
foodService.makeChicken();
扩展知识
Spring AOP 就是基于动态代理实现的:
- 如果类实现了接口 → 使用 JDK 动态代理
- 如果没有实现接口 → 使用 CGLIB 动态代理
2. 适配器模式 (Adapter)
核心思想
将一个类的接口转换成客户端期望的另一个接口,解决接口不兼容的问题。
三种实现方式
方式一:默认适配器模式
当接口方法太多,不需要实现所有方法时,提供一个默认实现类(所有方法为空实现),客户端只需要继承这个默认类,重写需要的方法即可。
示例: FileAlterationListenerAdaptor 实现了 FileAlterationListener 的所有方法,子类只需要重写文件创建、删除等关心的方法。
方式二:对象适配器模式(推荐)
持有被适配对象的实例,实现目标接口,将目标接口的方法调用委托给被适配对象。
java
// 目标接口:鸭
public interface Duck {
public void quack();
public void fly();
}
// 被适配类:鸡
public interface Cock {
public void gobble();
public void fly();
}
// 适配器
public class CockAdapter implements Duck {
private Cock cock;
public CockAdapter(Cock cock) {
this.cock = cock;
}
// 鸡不会呱呱叫,用咕咕叫适配
@Override
public void quack() {
cock.gobble();
}
@Override
public void fly() {
cock.fly();
}
}
方式三:类适配器模式
通过继承被适配类 + 实现目标接口的方式实现。
java
public class CockAdapter extends WildCock implements Duck {
// 自动获得被适配类的方法
}
和代理模式的区别
- 代理模式: 是增强原方法
- 适配器模式: 是做接口转换
- 两者目的不同
3. 桥梁模式 (Bridge)
核心思想
将抽象和实现解耦,让两者可以独立扩展。
代码示例(画图场景)
java
// 1. 定义桥梁接口(画图API)
public interface DrawAPI {
public void draw(int radius, int x, int y);
}
// 2. 桥梁接口的不同实现
public class RedPen implements DrawAPI {
@Override
public void draw(int radius, int x, int y) {
System.out.println("用红色笔画圆");
}
}
public class GreenPen implements DrawAPI {
@Override
public void draw(int radius, int x, int y) {
System.out.println("用绿色笔画圆");
}
}
// 3. 定义抽象形状类
public abstract class Shape {
protected DrawAPI drawAPI;
protected Shape(DrawAPI drawAPI) {
this.drawAPI = drawAPI;
}
public abstract void draw();
}
// 4. 具体形状实现
public class Circle extends Shape {
private int radius;
public Circle(int radius, DrawAPI drawAPI) {
super(drawAPI);
this.radius = radius;
}
public void draw() {
drawAPI.draw(radius, 0, 0);
}
}
// 5. 客户端调用
Shape greenCircle = new Circle(10, new GreenPen());
greenCircle.draw();
优点
✅ 非常容易扩展
✅ 需要新增形状只要加 Shape 的子类
✅ 需要新增画笔只要加 DrawAPI 的实现类
✅ 两者互不影响
适用场景
- 一个类有多个维度的变化
- 需要独立扩展的场景
4. 装饰模式 (Decorator)
核心思想
动态给对象添加额外的功能,比继承更灵活,可以实现多层装饰。
经典应用
Java IO 流:
FileInputStream- 基础输入流BufferedInputStream- 装饰器,给输入流添加缓冲功能DataInputStream- 给输入流添加读取基本类型的功能
代码示例(奶茶加料)
java
// 1. 定义饮料抽象基类
public abstract class Beverage {
public abstract String getDescription();
public abstract double cost();
}
// 2. 基础饮料实现
public class BlackTea extends Beverage {
@Override
public String getDescription() { return "红茶"; }
@Override
public double cost() { return 10; }
}
// 3. 装饰器抽象类
public abstract class Condiment extends Beverage {}
// 4. 具体装饰器
public class Lemon extends Condiment {
private Beverage beverage;
public Lemon(Beverage beverage) {
this.beverage = beverage;
}
@Override
public String getDescription() {
return beverage.getDescription() + ", 加柠檬";
}
@Override
public double cost() {
return beverage.cost() + 2;
}
}
// 5. 客户端调用,多层装饰
Beverage beverage = new GreenTea();
beverage = new Lemon(beverage); // 加柠檬
beverage = new Mango(beverage); // 加芒果
System.out.println(beverage.getDescription() + " 价格:¥" + beverage.cost());
适用场景
- 需要动态给对象添加功能
- 功能可以动态撤销
- IO流处理
- 缓存包装
5. 门面模式 (Facade)
核心思想
提供一个统一的门面接口,隐藏系统的复杂实现,客户端只需要和门面交互。
代码示例
java
// 1. 定义各个子系统的接口和实现
interface Shape { void draw(); }
class Circle implements Shape {
@Override
public void draw() { System.out.println("画圆"); }
}
class Rectangle implements Shape {
@Override
public void draw() { System.out.println("画矩形"); }
}
// 2. 定义门面类
public class ShapeMaker {
private Shape circle;
private Shape rectangle;
public ShapeMaker() {
circle = new Circle();
rectangle = new Rectangle();
}
public void drawCircle(){
circle.draw();
}
public void drawRectangle(){
rectangle.draw();
}
}
// 3. 客户端调用
ShapeMaker shapeMaker = new ShapeMaker();
shapeMaker.drawCircle();
经典应用
Slf4j 日志框架: 就是门面模式的应用,底层可以对接 Log4j、Logback 等不同日志实现。
优点
✅ 降低客户端和子系统的耦合
✅ 客户端不需要关心需要实例化哪个子类
✅ 调用更友好
6. 组合模式 (Composite)
核心思想
将对象组合成树形结构,表示「部分-整体」的层次结构,让客户端对单个对象和组合对象的访问具有一致性。
代码示例(员工组织架构)
java
public class Employee {
private String name;
private String dept;
private int salary;
private List<Employee> subordinates; // 下属
public void add(Employee e) {
subordinates.add(e);
}
public void remove(Employee e) {
subordinates.remove(e);
}
public List<Employee> getSubordinates(){
return subordinates;
}
}
适用场景
- 菜单系统
- 组织架构
- 文件系统
- XML/JSON 解析
7. 享元模式 (Flyweight)
核心思想
复用已经创建的对象,减少对象创建的数量,降低内存占用,提升性能。
实现方式
通常用 HashMap 存放已经创建的对象,比如:
- String 常量池
- Integer 的缓存机制 (-128 到 127)
适用场景
- 需要创建大量相似对象
- 文字处理中的字符对象
- 游戏中的子弹对象
结构型模式对比总结
| 模式 | 核心作用 | 适用场景 | 典型应用 |
|---|---|---|---|
| 代理模式 | 方法增强,隐藏真实实现 | 日志、权限、缓存 | Spring AOP |
| 适配器模式 | 接口转换,解决不兼容 | 现有类接口不匹配 | 旧系统改造 |
| 桥梁模式 | 抽象和实现解耦 | 多维度变化 | 跨平台开发 |
| 装饰模式 | 动态添加功能 | IO流处理、缓存 | Java IO |
| 门面模式 | 统一入口,隐藏复杂度 | 复杂系统调用 | Slf4j |
| 组合模式 | 表示树形结构 | 菜单、组织架构 | 文件系统 |
| 享元模式 | 对象复用 | 大量相似对象 | 字符串常量池 |
三、行为型模式
核心作用: 关注类和对象之间的交互,划分职责,让代码逻辑更清晰。
1. 策略模式 (Strategy)
核心思想
定义一系列算法,将每个算法封装成独立的策略类,让它们可以相互替换。
代码示例
java
// 1. 定义策略接口
public interface Strategy {
public void draw(int radius, int x, int y);
}
// 2. 不同策略实现
public class RedPen implements Strategy {
@Override
public void draw(int radius, int x, int y) {
System.out.println("用红色笔画圆");
}
}
// 3. 定义使用策略的上下文类
public class Context {
private Strategy strategy;
public Context(Strategy strategy){
this.strategy = strategy;
}
public int executeDraw(int radius, int x, int y){
return strategy.draw(radius, x, y);
}
}
// 4. 客户端调用
Context context = new Context(new BluePen());
context.executeDraw(10, 0, 0);
和桥梁模式的区别
- 桥梁模式: 在抽象层有更明确的抽象定义,耦合更低,结构更复杂
- 策略模式: 更关注算法的封装和替换
2. 观察者模式 (Observer)
核心思想
定义对象间的一对多依赖关系,当一个对象(主题)状态发生变化时,所有依赖它的对象(观察者)都会收到通知并自动更新。
代码示例
java
// 1. 定义主题类
public class Subject {
private List<Observer> observers = new ArrayList<Observer>();
private int state;
public void setState(int state) {
this.state = state;
notifyAllObservers(); // 状态变化,通知所有观察者
}
public void attach(Observer observer) {
observers.add(observer);
}
public void notifyAllObservers() {
for (Observer observer : observers) {
observer.update();
}
}
}
// 2. 定义观察者抽象类
public abstract class Observer {
protected Subject subject;
public abstract void update();
}
// 3. 具体观察者实现
public class BinaryObserver extends Observer {
public BinaryObserver(Subject subject) {
this.subject = subject;
this.subject.attach(this);
}
@Override
public void update() {
System.out.println("Binary: " + Integer.toBinaryString(subject.getState()));
}
}
// 4. 客户端调用
Subject subject = new Subject();
new BinaryObserver(subject);
new HexaObserver(subject);
subject.setState(11); // 状态变化,观察者收到通知
扩展知识
- JDK 提供了
Observable和Observer类支持观察者模式 - 实际开发中常用 Guava 的 EventBus 或者消息中间件实现观察者模式
3. 责任链模式 (Chain of Responsibility)
核心思想
将多个处理对象组成一条链,请求沿着链传递,直到有一个对象处理它为止。
代码示例(活动规则校验)
java
// 1. 定义处理节点的抽象类
public abstract class RuleHandler {
protected RuleHandler successor;
public abstract void apply(Context context);
public void setSuccessor(RuleHandler successor) {
this.successor = successor;
}
}
// 2. 具体处理节点实现
public class NewUserRuleHandler extends RuleHandler {
@Override
public void apply(Context context) {
if (context.isNewUser()) {
// 处理新用户逻辑
System.out.println("新用户规则校验通过");
}
// 传递给后继节点
if (successor != null) {
successor.apply(context);
}
}
}
// 3. 客户端组装责任链
RuleHandler locationHandler = new LocationRuleHandler();
RuleHandler limitHandler = new LimitRuleHandler();
locationHandler.setSuccessor(limitHandler); // 组装链
locationHandler.apply(context); // 从头部开始传递请求
典型应用
- Servlet 的 Filter
- Spring 的 Interceptor
- 流程审批
- 规则校验
4. 模板方法模式 (Template Method)
核心思想
定义一个算法的骨架,将算法中的一些步骤延迟到子类中实现。
代码示例
java
// 1. 定义抽象模板类
public abstract class AbstractTemplate {
// 模板方法,定义算法步骤
public void templateMethod() {
init(); // 可选步骤,抽象类可以实现默认逻辑
apply(); // 必选步骤,抽象方法,子类必须实现
end(); // 钩子方法,子类可以选择性覆写
}
protected void init() {
System.out.println("init 抽象层已经实现,子类也可以选择覆写");
}
protected abstract void apply();
protected void end() {} // 钩子方法
}
// 2. 子类实现
public class ConcreteTemplate extends AbstractTemplate {
public void apply() {
System.out.println("子类实现抽象方法 apply");
}
public void end() {
System.out.println("覆写钩子方法");
}
}
典型应用
- JdbcTemplate
- RedisTemplate
5. 状态模式 (State)
核心思想
对象的行为依赖于它的状态,当状态改变时,对象的行为也随之改变。
代码示例(库存操作)
java
// 1. 定义状态接口
public interface State {
public void doAction(Context context);
}
// 2. 具体状态实现
public class DeductState implements State {
@Override
public void doAction(Context context) {
System.out.println("执行减库存逻辑");
// 状态转换
context.setState(new RevertState());
}
}
// 3. 定义上下文类
public class Context {
private State state;
private String name;
public void setState(State state) {
this.state = state;
}
public void doAction() {
state.doAction(this);
}
}
适用场景
- 订单状态流转
- 游戏角色状态变化
- 工作流引擎
行为型模式对比总结
| 模式 | 核心作用 | 适用场景 | 典型应用 |
|---|---|---|---|
| 策略模式 | 封装算法,动态切换 | 多个相似算法 | 支付方式选择 |
| 观察者模式 | 一对多通知 | 事件监听、消息通知 | EventBus |
| 责任链模式 | 请求传递 | 流程审批、规则校验 | Servlet Filter |
| 模板方法模式 | 定义算法骨架 | 固定步骤算法 | JdbcTemplate |
| 状态模式 | 状态和行为绑定 | 状态机 | 订单状态流转 |
四、设计模式对比与选择
创建型模式选择指南
如果需要创建单一对象 → 单例模式
如果需要创建复杂对象 → 建造者模式
如果需要克隆对象 → 原型模式
如果需要创建系列产品 → 抽象工厂模式
如果需要扩展创建逻辑 → 工厂模式
如果创建逻辑简单 → 简单工厂模式
结构型模式选择指南
如果需要增强功能 → 代理模式 / 装饰模式
如果需要接口转换 → 适配器模式
如果需要统一入口 → 门面模式
如果需要表示整体-部分 → 组合模式
如果需要复用对象 → 享元模式
如果有多维度变化 → 桥梁模式
行为型模式选择指南
如果需要封装算法 → 策略模式
如果需要一对多通知 → 观察者模式
如果需要链式处理 → 责任链模式
如果有固定算法步骤 → 模板方法模式
如果行为依赖状态 → 状态模式
五、实际应用建议
1. 不要生搬硬套
❌ 错误做法:
java
// 为了用设计模式而用设计模式
// 简单的问题复杂化
✅ 正确做法:
- 根据业务场景选择合适的模式
- 优先考虑简单直接的实现
- 当代码出现重复、难以扩展时再考虑重构
2. 遵循设计原则
始终牢记三个核心设计原则:
- 面向接口编程
- 职责单一原则
- 开闭原则
3. 常见反模式
❌ 避免过度设计:
- 不要为了未来可能的需求提前设计
- YAGNI 原则 (You Aren't Gonna Need It)
❌ 避免模式滥用:
- 一个类中混用多种模式
- 模式嵌套过深
✅ 推荐做法:
- 从简单开始
- 逐步重构
- 保持代码可读性和可维护性
4. 学习路径建议
初级阶段:
- 掌握三大工厂模式
- 理解单例模式
- 学习代理模式和装饰模式
中级阶段:
- 掌握观察者模式
- 理解策略模式
- 学习模板方法模式
高级阶段:
- 深入理解桥梁模式
- 掌握状态模式
- 灵活运用多种模式组合
📚 参考资料
- 原文链接:https://cloud.tencent.com/developer/article/2028802
- GoF 《设计模式:可复用面向对象软件的基础》
- Head First 设计模式
🎯 总结
设计模式的核心目的是让代码更优雅、易维护、易扩展。但实际使用中不需要生搬硬套模式,而是:
- ✅ 根据业务场景选择合适的模式
- ✅ 遵循前置的三个设计原则
- ✅ 保持代码简洁易懂
- ✅ 持续重构和优化
记住: 好的代码不是用了多少设计模式,而是是否容易理解、维护和扩展。