跳到主要内容

设计模式总结详解

设计模式是软件开发中的重要概念,提供了解决常见设计问题的标准方案。本文档系统梳理了设计模式的核心概念、分类体系、实际应用和面试重点,帮助你在实际项目中正确应用设计模式。

学习目标

通过本章学习,你将掌握:

  • 设计模式的基本概念和分类体系
  • 23种经典设计模式的原理和应用
  • SOLID设计原则和最佳实践
  • 设计模式在实际项目中的应用场景
  • 面试中常见的设计模式问题

1. 设计模式基本概念

1.1 什么是设计模式?

设计模式是软件开发中常见问题的最佳实践解决方案,它描述了在软件开发过程中不断重复发生的问题,以及该问题的解决方案的核心。

设计模式的定义

设计模式是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。

1.2 设计模式的作用

作用说明示例
代码复用提供可重用的解决方案单例模式确保全局唯一实例
提高可维护性标准化的代码结构工厂模式统一对象创建
增强可扩展性支持功能扩展装饰器模式动态添加功能
降低耦合度减少模块间依赖观察者模式解耦事件处理
提高可读性清晰的代码意图策略模式明确算法选择

1.3 设计模式的核心要素

2. 设计模式分类体系

2.1 按目的分类

设计模式按照其目的可以分为三大类:

创建型模式(Creational Patterns)

结构型模式(Structural Patterns)

行为型模式(Behavioral Patterns)

2.2 按范围分类

类模式 vs 对象模式

分类特点示例
类模式处理类与子类之间的关系,通过继承建立模板方法模式、工厂方法模式
对象模式处理对象间的关系,通过组合建立策略模式、观察者模式、装饰器模式
选择原则
  • 类模式:静态关系,编译时确定
  • 对象模式:动态关系,运行时确定
  • 优先选择对象模式,因为组合比继承更灵活

3. 创建型模式详解

3.1 单例模式(Singleton)

模式定义

确保一个类只有一个实例,并提供一个全局访问点。

实现方式

线程安全的单例模式
java
1public class Singleton {
2 // 私有静态实例,使用volatile保证可见性
3 private static volatile Singleton instance;
4
5 // 私有构造函数,防止外部实例化
6 private Singleton() {
7 // 防止反射攻击
8 if (instance != null) {
9 throw new RuntimeException("单例模式不允许创建多个实例");
10 }
11 }
12
13 // 双重检查锁定(Double-Checked Locking)
14 public static Singleton getInstance() {
15 if (instance == null) {
16 synchronized (Singleton.class) {
17 if (instance == null) {
18 instance = new Singleton();
19 }
20 }
21 }
22 return instance;
23 }
24
25 // 业务方法
26 public void doSomething() {
27 System.out.println("单例模式执行操作");
28 }
29}

枚举实现(推荐)

枚举单例模式
java
1public enum SingletonEnum {
2 INSTANCE;
3
4 public void doSomething() {
5 System.out.println("枚举单例模式执行操作");
6 }
7}

应用场景

  • 配置管理器
  • 数据库连接池
  • 日志记录器
  • 缓存管理器

3.2 工厂方法模式(Factory Method)

模式定义

定义一个创建对象的接口,让子类决定实例化哪一个类。

实现示例

工厂方法模式
java
1// 抽象产品
2public interface Product {
3 void operation();
4}
5
6// 具体产品A
7public class ConcreteProductA implements Product {
8 @Override
9 public void operation() {
10 System.out.println("产品A的操作");
11 }
12}
13
14// 具体产品B
15public class ConcreteProductB implements Product {
16 @Override
17 public void operation() {
18 System.out.println("产品B的操作");
19 }
20}
21
22// 抽象工厂
23public abstract class Creator {
24 // 工厂方法
25 public abstract Product createProduct();
26
27 // 模板方法
28 public void someOperation() {
29 Product product = createProduct();
30 product.operation();
31 }
32}
33
34// 具体工厂A
35public class ConcreteCreatorA extends Creator {
36 @Override
37 public Product createProduct() {
38 return new ConcreteProductA();
39 }
40}
41
42// 具体工厂B
43public class ConcreteCreatorB extends Creator {
44 @Override
45 public Product createProduct() {
46 return new ConcreteProductB();
47 }
48}

应用场景

  • 数据库连接工厂
  • 日志记录器工厂
  • 图形界面组件工厂

3.3 抽象工厂模式(Abstract Factory)

模式定义

提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们的具体类。

实现示例

抽象工厂模式
java
1// 抽象产品A
2public interface AbstractProductA {
3 void operationA();
4}
5
6// 抽象产品B
7public interface AbstractProductB {
8 void operationB();
9}
10
11// 具体产品A1
12public class ConcreteProductA1 implements AbstractProductA {
13 @Override
14 public void operationA() {
15 System.out.println("产品A1的操作");
16 }
17}
18
19// 具体产品B1
20public class ConcreteProductB1 implements AbstractProductB {
21 @Override
22 public void operationB() {
23 System.out.println("产品B1的操作");
24 }
25}
26
27// 抽象工厂
28public interface AbstractFactory {
29 AbstractProductA createProductA();
30 AbstractProductB createProductB();
31}
32
33// 具体工厂1
34public class ConcreteFactory1 implements AbstractFactory {
35 @Override
36 public AbstractProductA createProductA() {
37 return new ConcreteProductA1();
38 }
39
40 @Override
41 public AbstractProductB createProductB() {
42 return new ConcreteProductB1();
43 }
44}

应用场景

  • 跨平台UI组件
  • 数据库访问层
  • 操作系统API

3.4 建造者模式(Builder)

模式定义

将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

实现示例

建造者模式
java
1// 产品类
2public class Computer {
3 private String cpu;
4 private String memory;
5 private String storage;
6 private String graphics;
7
8 // 私有构造函数
9 private Computer() {}
10
11 // Getter方法
12 public String getCpu() { return cpu; }
13 public String getMemory() { return memory; }
14 public String getStorage() { return storage; }
15 public String getGraphics() { return graphics; }
16
17 // 静态内部建造者类
18 public static class Builder {
19 private Computer computer = new Computer();
20
21 public Builder cpu(String cpu) {
22 computer.cpu = cpu;
23 return this;
24 }
25
26 public Builder memory(String memory) {
27 computer.memory = memory;
28 return this;
29 }
30
31 public Builder storage(String storage) {
32 computer.storage = storage;
33 return this;
34 }
35
36 public Builder graphics(String graphics) {
37 computer.graphics = graphics;
38 return this;
39 }
40
41 public Computer build() {
42 // 参数校验
43 if (computer.cpu == null) {
44 throw new IllegalArgumentException("CPU不能为空");
45 }
46 if (computer.memory == null) {
47 throw new IllegalArgumentException("内存不能为空");
48 }
49 return computer;
50 }
51 }
52}

使用示例

建造者模式使用
java
1public class BuilderExample {
2 public static void main(String[] args) {
3 Computer computer = new Computer.Builder()
4 .cpu("Intel i7")
5 .memory("16GB")
6 .storage("512GB SSD")
7 .graphics("RTX 3080")
8 .build();
9
10 System.out.println("CPU: " + computer.getCpu());
11 System.out.println("内存: " + computer.getMemory());
12 }
13}

应用场景

  • 复杂对象构建
  • 参数校验
  • 不可变对象创建

3.5 原型模式(Prototype)

模式定义

用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。

实现示例

原型模式
java
1// 原型接口
2public interface Prototype extends Cloneable {
3 Prototype clone();
4 void display();
5}
6
7// 具体原型
8public class ConcretePrototype implements Prototype {
9 private String name;
10 private List<String> attributes = new ArrayList<>();
11
12 public ConcretePrototype(String name) {
13 this.name = name;
14 this.attributes.add("属性1");
15 this.attributes.add("属性2");
16 }
17
18 @Override
19 public Prototype clone() {
20 try {
21 ConcretePrototype clone = (ConcretePrototype) super.clone();
22 // 深拷贝
23 clone.attributes = new ArrayList<>(this.attributes);
24 return clone;
25 } catch (CloneNotSupportedException e) {
26 throw new RuntimeException(e);
27 }
28 }
29
30 @Override
31 public void display() {
32 System.out.println("原型名称: " + name);
33 System.out.println("属性: " + attributes);
34 }
35
36 public void addAttribute(String attribute) {
37 this.attributes.add(attribute);
38 }
39}

应用场景

  • 对象克隆
  • 配置复制
  • 模板复制
创建型模式选择
  1. 单例模式:需要全局唯一实例时
  2. 工厂方法:需要延迟实例化时
  3. 抽象工厂:需要创建产品族时
  4. 建造者模式:需要构建复杂对象时
  5. 原型模式:需要对象克隆时

4. 结构型模式详解

4.1 适配器模式(Adapter)

模式定义

将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。

类适配器实现

类适配器模式
java
1// 目标接口
2public interface Target {
3 void request();
4}
5
6// 被适配的类
7public class Adaptee {
8 public void specificRequest() {
9 System.out.println("被适配类的特殊请求");
10 }
11}
12
13// 类适配器
14public class ClassAdapter extends Adaptee implements Target {
15 @Override
16 public void request() {
17 // 调用被适配类的方法
18 specificRequest();
19 }
20}

对象适配器实现

对象适配器模式
java
1// 对象适配器
2public class ObjectAdapter implements Target {
3 private Adaptee adaptee;
4
5 public ObjectAdapter(Adaptee adaptee) {
6 this.adaptee = adaptee;
7 }
8
9 @Override
10 public void request() {
11 adaptee.specificRequest();
12 }
13}

应用场景

  • 第三方库集成
  • 接口兼容性
  • 遗留系统改造

4.2 桥接模式(Bridge)

模式定义

将抽象部分与实现部分分离,使它们都可以独立地变化。

实现示例

桥接模式
java
1// 实现者接口
2public interface Implementor {
3 void operationImpl();
4}
5
6// 具体实现者A
7public class ConcreteImplementorA implements Implementor {
8 @Override
9 public void operationImpl() {
10 System.out.println("具体实现者A的操作");
11 }
12}
13
14// 具体实现者B
15public class ConcreteImplementorB implements Implementor {
16 @Override
17 public void operationImpl() {
18 System.out.println("具体实现者B的操作");
19 }
20}
21
22// 抽象类
23public abstract class Abstraction {
24 protected Implementor implementor;
25
26 public Abstraction(Implementor implementor) {
27 this.implementor = implementor;
28 }
29
30 public abstract void operation();
31}
32
33// 精确抽象类
34public class RefinedAbstraction extends Abstraction {
35 public RefinedAbstraction(Implementor implementor) {
36 super(implementor);
37 }
38
39 @Override
40 public void operation() {
41 System.out.println("精确抽象类的操作");
42 implementor.operationImpl();
43 }
44}

应用场景

  • 跨平台开发
  • 数据库驱动
  • 图形渲染引擎

4.3 组合模式(Composite)

模式定义

将对象组合成树形结构以表示"部分-整体"的层次结构,使得用户对单个对象和组合对象的使用具有一致性。

实现示例

组合模式
java
1// 抽象组件
2public abstract class Component {
3 protected String name;
4
5 public Component(String name) {
6 this.name = name;
7 }
8
9 public abstract void add(Component component);
10 public abstract void remove(Component component);
11 public abstract void display(int depth);
12}
13
14// 叶子节点
15public class Leaf extends Component {
16 public Leaf(String name) {
17 super(name);
18 }
19
20 @Override
21 public void add(Component component) {
22 throw new UnsupportedOperationException("叶子节点不能添加子节点");
23 }
24
25 @Override
26 public void remove(Component component) {
27 throw new UnsupportedOperationException("叶子节点不能删除子节点");
28 }
29
30 @Override
31 public void display(int depth) {
32 StringBuilder prefix = new StringBuilder();
33 for (int i = 0; i < depth; i++) {
34 prefix.append(" ");
35 }
36 System.out.println(prefix + "- " + name);
37 }
38}
39
40// 复合节点
41public class Composite extends Component {
42 private List<Component> children = new ArrayList<>();
43
44 public Composite(String name) {
45 super(name);
46 }
47
48 @Override
49 public void add(Component component) {
50 children.add(component);
51 }
52
53 @Override
54 public void remove(Component component) {
55 children.remove(component);
56 }
57
58 @Override
59 public void display(int depth) {
60 StringBuilder prefix = new StringBuilder();
61 for (int i = 0; i < depth; i++) {
62 prefix.append(" ");
63 }
64 System.out.println(prefix + "+ " + name);
65
66 for (Component child : children) {
67 child.display(depth + 1);
68 }
69 }
70}

应用场景

  • 文件系统
  • 组织架构
  • 菜单系统

4.4 装饰器模式(Decorator)

模式定义

动态地给一个对象添加一些额外的职责,就增加功能来说,装饰器模式比生成子类更为灵活。

实现示例

装饰器模式
java
1// 抽象组件
2public interface Component {
3 void operation();
4}
5
6// 具体组件
7public class ConcreteComponent implements Component {
8 @Override
9 public void operation() {
10 System.out.println("具体组件的操作");
11 }
12}
13
14// 抽象装饰器
15public abstract class Decorator implements Component {
16 protected Component component;
17
18 public Decorator(Component component) {
19 this.component = component;
20 }
21
22 @Override
23 public void operation() {
24 component.operation();
25 }
26}
27
28// 具体装饰器A
29public class ConcreteDecoratorA extends Decorator {
30 public ConcreteDecoratorA(Component component) {
31 super(component);
32 }
33
34 @Override
35 public void operation() {
36 super.operation();
37 addedBehavior();
38 }
39
40 private void addedBehavior() {
41 System.out.println("装饰器A添加的行为");
42 }
43}
44
45// 具体装饰器B
46public class ConcreteDecoratorB extends Decorator {
47 public ConcreteDecoratorB(Component component) {
48 super(component);
49 }
50
51 @Override
52 public void operation() {
53 super.operation();
54 addedBehavior();
55 }
56
57 private void addedBehavior() {
58 System.out.println("装饰器B添加的行为");
59 }
60}

使用示例

装饰器模式使用
java
1public class DecoratorExample {
2 public static void main(String[] args) {
3 Component component = new ConcreteComponent();
4 Component decoratedA = new ConcreteDecoratorA(component);
5 Component decoratedB = new ConcreteDecoratorB(decoratedA);
6
7 decoratedB.operation();
8 // 输出:
9 // 具体组件的操作
10 // 装饰器A添加的行为
11 // 装饰器B添加的行为
12 }
13}

应用场景

  • IO流处理
  • 缓存装饰
  • 权限控制

4.5 外观模式(Facade)

模式定义

为子系统中的一组接口提供一个一致的界面,外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。

实现示例

外观模式
java
1// 子系统A
2public class SubsystemA {
3 public void operationA() {
4 System.out.println("子系统A的操作");
5 }
6}
7
8// 子系统B
9public class SubsystemB {
10 public void operationB() {
11 System.out.println("子系统B的操作");
12 }
13}
14
15// 子系统C
16public class SubsystemC {
17 public void operationC() {
18 System.out.println("子系统C的操作");
19 }
20}
21
22// 外观类
23public class Facade {
24 private SubsystemA subsystemA;
25 private SubsystemB subsystemB;
26 private SubsystemC subsystemC;
27
28 public Facade() {
29 this.subsystemA = new SubsystemA();
30 this.subsystemB = new SubsystemB();
31 this.subsystemC = new SubsystemC();
32 }
33
34 public void operation() {
35 System.out.println("外观模式开始操作");
36 subsystemA.operationA();
37 subsystemB.operationB();
38 subsystemC.operationC();
39 System.out.println("外观模式结束操作");
40 }
41}

应用场景

  • 系统集成
  • 复杂API封装
  • 第三方服务调用

4.6 享元模式(Flyweight)

模式定义

运用共享技术有效地支持大量细粒度对象的复用。

实现示例

享元模式
java
1// 抽象享元
2public abstract class Flyweight {
3 public abstract void operation(String extrinsicState);
4}
5
6// 具体享元
7public class ConcreteFlyweight extends Flyweight {
8 private String intrinsicState;
9
10 public ConcreteFlyweight(String intrinsicState) {
11 this.intrinsicState = intrinsicState;
12 }
13
14 @Override
15 public void operation(String extrinsicState) {
16 System.out.println("具体享元: " + intrinsicState + ", 外部状态: " + extrinsicState);
17 }
18}
19
20// 享元工厂
21public class FlyweightFactory {
22 private Map<String, Flyweight> flyweights = new HashMap<>();
23
24 public Flyweight getFlyweight(String key) {
25 Flyweight flyweight = flyweights.get(key);
26 if (flyweight == null) {
27 flyweight = new ConcreteFlyweight(key);
28 flyweights.put(key, flyweight);
29 }
30 return flyweight;
31 }
32
33 public int getFlyweightCount() {
34 return flyweights.size();
35 }
36}

应用场景

  • 字符串池
  • 数据库连接池
  • 图形对象缓存

4.7 代理模式(Proxy)

模式定义

为其他对象提供一种代理以控制对这个对象的访问。

静态代理实现

静态代理模式
java
1// 抽象主题
2public interface Subject {
3 void request();
4}
5
6// 真实主题
7public class RealSubject implements Subject {
8 @Override
9 public void request() {
10 System.out.println("真实主题的请求");
11 }
12}
13
14// 代理类
15public class Proxy implements Subject {
16 private RealSubject realSubject;
17
18 public Proxy() {
19 this.realSubject = new RealSubject();
20 }
21
22 @Override
23 public void request() {
24 preRequest();
25 realSubject.request();
26 postRequest();
27 }
28
29 private void preRequest() {
30 System.out.println("代理前置处理");
31 }
32
33 private void postRequest() {
34 System.out.println("代理后置处理");
35 }
36}

动态代理实现

动态代理模式
java
1public class DynamicProxy implements InvocationHandler {
2 private Object target;
3
4 public DynamicProxy(Object target) {
5 this.target = target;
6 }
7
8 @Override
9 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
10 System.out.println("动态代理前置处理");
11 Object result = method.invoke(target, args);
12 System.out.println("动态代理后置处理");
13 return result;
14 }
15
16 public static Object createProxy(Object target) {
17 return Proxy.newProxyInstance(
18 target.getClass().getClassLoader(),
19 target.getClass().getInterfaces(),
20 new DynamicProxy(target)
21 );
22 }
23}

应用场景

  • 远程代理
  • 虚拟代理
  • 保护代理
  • 缓存代理

5. 行为型模式详解

5.1 责任链模式(Chain of Responsibility)

模式定义

使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。

实现示例

责任链模式
java
1// 抽象处理器
2public abstract class Handler {
3 protected Handler successor;
4
5 public void setSuccessor(Handler successor) {
6 this.successor = successor;
7 }
8
9 public abstract void handleRequest(int request);
10}
11
12// 具体处理器A
13public class ConcreteHandlerA extends Handler {
14 @Override
15 public void handleRequest(int request) {
16 if (request >= 0 && request < 10) {
17 System.out.println("处理器A处理请求: " + request);
18 } else if (successor != null) {
19 successor.handleRequest(request);
20 }
21 }
22}
23
24// 具体处理器B
25public class ConcreteHandlerB extends Handler {
26 @Override
27 public void handleRequest(int request) {
28 if (request >= 10 && request < 20) {
29 System.out.println("处理器B处理请求: " + request);
30 } else if (successor != null) {
31 successor.handleRequest(request);
32 }
33 }
34}
35
36// 具体处理器C
37public class ConcreteHandlerC extends Handler {
38 @Override
39 public void handleRequest(int request) {
40 if (request >= 20 && request < 30) {
41 System.out.println("处理器C处理请求: " + request);
42 } else if (successor != null) {
43 successor.handleRequest(request);
44 } else {
45 System.out.println("没有处理器能处理请求: " + request);
46 }
47 }
48}

应用场景

  • 权限验证链
  • 异常处理链
  • 日志处理链

5.2 命令模式(Command)

模式定义

将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化,对请求排队或记录请求日志,以及支持可撤销的操作。

实现示例

命令模式
java
1// 抽象命令
2public interface Command {
3 void execute();
4 void undo();
5}
6
7// 具体命令
8public class ConcreteCommand implements Command {
9 private Receiver receiver;
10
11 public ConcreteCommand(Receiver receiver) {
12 this.receiver = receiver;
13 }
14
15 @Override
16 public void execute() {
17 receiver.action();
18 }
19
20 @Override
21 public void undo() {
22 receiver.undoAction();
23 }
24}
25
26// 接收者
27public class Receiver {
28 public void action() {
29 System.out.println("接收者执行操作");
30 }
31
32 public void undoAction() {
33 System.out.println("接收者撤销操作");
34 }
35}
36
37// 调用者
38public class Invoker {
39 private List<Command> commands = new ArrayList<>();
40
41 public void addCommand(Command command) {
42 commands.add(command);
43 }
44
45 public void executeCommands() {
46 for (Command command : commands) {
47 command.execute();
48 }
49 }
50
51 public void undoCommands() {
52 for (int i = commands.size() - 1; i >= 0; i--) {
53 commands.get(i).undo();
54 }
55 }
56}

应用场景

  • 菜单系统
  • 宏命令
  • 事务处理

5.3 观察者模式(Observer)

模式定义

定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。

实现示例

观察者模式
java
1// 抽象观察者
2public interface Observer {
3 void update(String message);
4}
5
6// 具体观察者A
7public class ConcreteObserverA implements Observer {
8 @Override
9 public void update(String message) {
10 System.out.println("观察者A收到消息: " + message);
11 }
12}
13
14// 具体观察者B
15public class ConcreteObserverB implements Observer {
16 @Override
17 public void update(String message) {
18 System.out.println("观察者B收到消息: " + message);
19 }
20}
21
22// 抽象主题
23public abstract class Subject {
24 protected List<Observer> observers = new ArrayList<>();
25
26 public void attach(Observer observer) {
27 observers.add(observer);
28 }
29
30 public void detach(Observer observer) {
31 observers.remove(observer);
32 }
33
34 public abstract void notifyObservers();
35}
36
37// 具体主题
38public class ConcreteSubject extends Subject {
39 private String state;
40
41 public void setState(String state) {
42 this.state = state;
43 notifyObservers();
44 }
45
46 @Override
47 public void notifyObservers() {
48 for (Observer observer : observers) {
49 observer.update(state);
50 }
51 }
52}

应用场景

  • 事件处理
  • 消息推送
  • 数据绑定

5.4 策略模式(Strategy)

模式定义

定义一系列的算法,把它们一个个封装起来,并且使它们可以互相替换。

实现示例

策略模式
java
1// 抽象策略
2public interface Strategy {
3 int doOperation(int num1, int num2);
4}
5
6// 具体策略A:加法
7public class OperationAdd implements Strategy {
8 @Override
9 public int doOperation(int num1, int num2) {
10 return num1 + num2;
11 }
12}
13
14// 具体策略B:减法
15public class OperationSubtract implements Strategy {
16 @Override
17 public int doOperation(int num1, int num2) {
18 return num1 - num2;
19 }
20}
21
22// 具体策略C:乘法
23public class OperationMultiply implements Strategy {
24 @Override
25 public int doOperation(int num1, int num2) {
26 return num1 * num2;
27 }
28}
29
30// 上下文
31public class Context {
32 private Strategy strategy;
33
34 public Context(Strategy strategy) {
35 this.strategy = strategy;
36 }
37
38 public void setStrategy(Strategy strategy) {
39 this.strategy = strategy;
40 }
41
42 public int executeStrategy(int num1, int num2) {
43 return strategy.doOperation(num1, num2);
44 }
45}

应用场景

  • 算法选择
  • 支付方式
  • 排序策略

5.5 状态模式(State)

模式定义

允许对象在内部状态发生改变时改变它的行为,对象看起来好像修改了它的类。

实现示例

状态模式
java
1// 抽象状态
2public abstract class State {
3 protected Context context;
4
5 public void setContext(Context context) {
6 this.context = context;
7 }
8
9 public abstract void handle();
10}
11
12// 具体状态A
13public class ConcreteStateA extends State {
14 @Override
15 public void handle() {
16 System.out.println("状态A处理");
17 context.setState(new ConcreteStateB());
18 }
19}
20
21// 具体状态B
22public class ConcreteStateB extends State {
23 @Override
24 public void handle() {
25 System.out.println("状态B处理");
26 context.setState(new ConcreteStateA());
27 }
28}
29
30// 上下文
31public class Context {
32 private State state;
33
34 public Context(State state) {
35 this.state = state;
36 this.state.setContext(this);
37 }
38
39 public void setState(State state) {
40 this.state = state;
41 this.state.setContext(this);
42 }
43
44 public void request() {
45 state.handle();
46 }
47}

应用场景

  • 订单状态管理
  • 游戏状态
  • 工作流状态
行为型模式选择
  1. 责任链模式:需要处理请求链时
  2. 命令模式:需要封装请求时
  3. 观察者模式:需要事件通知时
  4. 策略模式:需要算法选择时
  5. 状态模式:需要状态转换时

6. 设计原则详解

6.1 SOLID原则

单一职责原则(Single Responsibility Principle, SRP)

单一职责原则示例
java
1// 违反SRP的类
2public class UserManager {
3 public void createUser(String username, String password) {
4 // 用户创建逻辑
5 }
6
7 public void sendEmail(String to, String subject, String content) {
8 // 邮件发送逻辑
9 }
10
11 public void saveToDatabase(User user) {
12 // 数据库保存逻辑
13 }
14}
15
16// 符合SRP的类
17public class UserService {
18 public void createUser(String username, String password) {
19 // 用户创建逻辑
20 }
21}
22
23public class EmailService {
24 public void sendEmail(String to, String subject, String content) {
25 // 邮件发送逻辑
26 }
27}
28
29public class UserRepository {
30 public void save(User user) {
31 // 数据库保存逻辑
32 }
33}

开闭原则(Open-Closed Principle, OCP)

开闭原则示例
java
1// 抽象形状
2public abstract class Shape {
3 public abstract double calculateArea();
4}
5
6// 具体形状
7public class Rectangle extends Shape {
8 private double width;
9 private double height;
10
11 public Rectangle(double width, double height) {
12 this.width = width;
13 this.height = height;
14 }
15
16 @Override
17 public double calculateArea() {
18 return width * height;
19 }
20}
21
22public class Circle extends Shape {
23 private double radius;
24
25 public Circle(double radius) {
26 this.radius = radius;
27 }
28
29 @Override
30 public double calculateArea() {
31 return Math.PI * radius * radius;
32 }
33}
34
35// 面积计算器(对扩展开放,对修改关闭)
36public class AreaCalculator {
37 public double calculateTotalArea(List<Shape> shapes) {
38 double totalArea = 0;
39 for (Shape shape : shapes) {
40 totalArea += shape.calculateArea();
41 }
42 return totalArea;
43 }
44}

里氏替换原则(Liskov Substitution Principle, LSP)

里氏替换原则示例
java
1// 基类
2public class Bird {
3 public void fly() {
4 System.out.println("鸟在飞行");
5 }
6}
7
8// 子类应该能够替换父类
9public class Sparrow extends Bird {
10 @Override
11 public void fly() {
12 System.out.println("麻雀在飞行");
13 }
14}
15
16// 违反LSP的子类
17public class Penguin extends Bird {
18 @Override
19 public void fly() {
20 throw new UnsupportedOperationException("企鹅不能飞行");
21 }
22}
23
24// 正确的设计
25public abstract class Bird {
26 public abstract void move();
27}
28
29public class FlyingBird extends Bird {
30 @Override
31 public void move() {
32 fly();
33 }
34
35 protected void fly() {
36 System.out.println("鸟在飞行");
37 }
38}
39
40public class NonFlyingBird extends Bird {
41 @Override
42 public void move() {
43 walk();
44 }
45
46 protected void walk() {
47 System.out.println("鸟在行走");
48 }
49}

接口隔离原则(Interface Segregation Principle, ISP)

接口隔离原则示例
java
1// 违反ISP的胖接口
2public interface Worker {
3 void work();
4 void eat();
5 void sleep();
6}
7
8// 符合ISP的细粒度接口
9public interface Workable {
10 void work();
11}
12
13public interface Eatable {
14 void eat();
15}
16
17public interface Sleepable {
18 void sleep();
19}
20
21// 具体实现
22public class Human implements Workable, Eatable, Sleepable {
23 @Override
24 public void work() {
25 System.out.println("人类工作");
26 }
27
28 @Override
29 public void eat() {
30 System.out.println("人类吃饭");
31 }
32
33 @Override
34 public void sleep() {
35 System.out.println("人类睡觉");
36 }
37}
38
39public class Robot implements Workable {
40 @Override
41 public void work() {
42 System.out.println("机器人工作");
43 }
44}

依赖倒置原则(Dependency Inversion Principle, DIP)

依赖倒置原则示例
java
1// 违反DIP的设计
2public class EmailNotifier {
3 public void sendEmail(String message) {
4 System.out.println("发送邮件: " + message);
5 }
6}
7
8public class OrderService {
9 private EmailNotifier emailNotifier = new EmailNotifier();
10
11 public void placeOrder(String order) {
12 // 处理订单
13 emailNotifier.sendEmail("订单已创建: " + order);
14 }
15}
16
17// 符合DIP的设计
18public interface Notifier {
19 void notify(String message);
20}
21
22public class EmailNotifier implements Notifier {
23 @Override
24 public void notify(String message) {
25 System.out.println("发送邮件: " + message);
26 }
27}
28
29public class SMSNotifier implements Notifier {
30 @Override
31 public void notify(String message) {
32 System.out.println("发送短信: " + message);
33 }
34}
35
36public class OrderService {
37 private Notifier notifier;
38
39 public OrderService(Notifier notifier) {
40 this.notifier = notifier;
41 }
42
43 public void placeOrder(String order) {
44 // 处理订单
45 notifier.notify("订单已创建: " + order);
46 }
47}

6.2 其他重要原则

迪米特法则(Law of Demeter, LoD)

迪米特法则示例
java
1// 违反LoD
2public class Customer {
3 private Wallet wallet;
4
5 public Wallet getWallet() {
6 return wallet;
7 }
8}
9
10public class Wallet {
11 private double money;
12
13 public double getMoney() {
14 return money;
15 }
16}
17
18// 客户端代码违反LoD
19Customer customer = new Customer();
20double money = customer.getWallet().getMoney(); // 违反LoD
21
22// 符合LoD
23public class Customer {
24 private Wallet wallet;
25
26 public double getMoney() {
27 return wallet.getMoney();
28 }
29}
30
31// 客户端代码符合LoD
32Customer customer = new Customer();
33double money = customer.getMoney(); // 符合LoD

组合优于继承

组合优于继承示例
java
1// 使用继承(不推荐)
2public class Bird {
3 public void fly() {
4 System.out.println("飞行");
5 }
6}
7
8public class Duck extends Bird {
9 public void swim() {
10 System.out.println("游泳");
11 }
12}
13
14// 使用组合(推荐)
15public interface Flyable {
16 void fly();
17}
18
19public interface Swimmable {
20 void swim();
21}
22
23public class Duck {
24 private Flyable flyable;
25 private Swimmable swimmable;
26
27 public Duck(Flyable flyable, Swimmable swimmable) {
28 this.flyable = flyable;
29 this.swimmable = swimmable;
30 }
31
32 public void fly() {
33 flyable.fly();
34 }
35
36 public void swim() {
37 swimmable.swim();
38 }
39}

7. 实际应用场景

7.1 框架中的应用

Spring框架中的设计模式

Spring中的设计模式
java
1// 工厂模式 - BeanFactory
2public interface BeanFactory {
3 Object getBean(String name);
4 <T> T getBean(Class<T> requiredType);
5}
6
7// 单例模式 - ApplicationContext
8public class ApplicationContext {
9 private static ApplicationContext instance;
10
11 public static ApplicationContext getInstance() {
12 if (instance == null) {
13 instance = new ApplicationContext();
14 }
15 return instance;
16 }
17}
18
19// 代理模式 - AOP
20@Aspect
21@Component
22public class LoggingAspect {
23 @Around("@annotation(Loggable)")
24 public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
25 System.out.println("方法执行前");
26 Object result = joinPoint.proceed();
27 System.out.println("方法执行后");
28 return result;
29 }
30}
31
32// 观察者模式 - 事件机制
33@Component
34public class OrderEventListener implements ApplicationListener<OrderEvent> {
35 @Override
36 public void onApplicationEvent(OrderEvent event) {
37 System.out.println("处理订单事件: " + event.getOrderId());
38 }
39}

Java集合框架中的设计模式

Java集合中的设计模式
java
1// 迭代器模式
2public class CustomCollection<T> implements Iterable<T> {
3 private List<T> elements = new ArrayList<>();
4
5 public void add(T element) {
6 elements.add(element);
7 }
8
9 @Override
10 public Iterator<T> iterator() {
11 return new CustomIterator();
12 }
13
14 private class CustomIterator implements Iterator<T> {
15 private int index = 0;
16
17 @Override
18 public boolean hasNext() {
19 return index < elements.size();
20 }
21
22 @Override
23 public T next() {
24 if (!hasNext()) {
25 throw new NoSuchElementException();
26 }
27 return elements.get(index++);
28 }
29 }
30}
31
32// 装饰器模式
33public class SynchronizedList<E> implements List<E> {
34 private final List<E> list;
35
36 public SynchronizedList(List<E> list) {
37 this.list = list;
38 }
39
40 @Override
41 public synchronized boolean add(E e) {
42 return list.add(e);
43 }
44
45 @Override
46 public synchronized E get(int index) {
47 return list.get(index);
48 }
49
50 // 其他方法类似...
51}

7.2 业务场景应用

用户权限系统

权限系统中的设计模式
java
1// 责任链模式 - 权限验证链
2public abstract class PermissionHandler {
3 protected PermissionHandler nextHandler;
4
5 public void setNext(PermissionHandler handler) {
6 this.nextHandler = handler;
7 }
8
9 public abstract boolean handle(PermissionRequest request);
10}
11
12public class AuthenticationHandler extends PermissionHandler {
13 @Override
14 public boolean handle(PermissionRequest request) {
15 if (!isAuthenticated(request)) {
16 return false;
17 }
18 return nextHandler != null ? nextHandler.handle(request) : true;
19 }
20}
21
22public class AuthorizationHandler extends PermissionHandler {
23 @Override
24 public boolean handle(PermissionRequest request) {
25 if (!hasPermission(request)) {
26 return false;
27 }
28 return nextHandler != null ? nextHandler.handle(request) : true;
29 }
30}
31
32// 策略模式 - 不同验证策略
33public interface ValidationStrategy {
34 boolean validate(String input);
35}
36
37public class EmailValidationStrategy implements ValidationStrategy {
38 @Override
39 public boolean validate(String input) {
40 return input.matches("^[A-Za-z0-9+_.-]+@(.+)$");
41 }
42}
43
44public class PhoneValidationStrategy implements ValidationStrategy {
45 @Override
46 public boolean validate(String input) {
47 return input.matches("^1[3-9]\\d{9}$");
48 }
49}
50
51// 代理模式 - 权限控制代理
52public class PermissionProxy implements UserService {
53 private UserService userService;
54 private PermissionService permissionService;
55
56 public PermissionProxy(UserService userService, PermissionService permissionService) {
57 this.userService = userService;
58 this.permissionService = permissionService;
59 }
60
61 @Override
62 public void updateUser(User user) {
63 if (permissionService.hasPermission("UPDATE_USER")) {
64 userService.updateUser(user);
65 } else {
66 throw new SecurityException("没有更新用户的权限");
67 }
68 }
69}

订单系统

订单系统中的设计模式
java
1// 状态模式 - 订单状态管理
2public abstract class OrderState {
3 protected Order order;
4
5 public void setOrder(Order order) {
6 this.order = order;
7 }
8
9 public abstract void confirm();
10 public abstract void ship();
11 public abstract void deliver();
12 public abstract void cancel();
13}
14
15public class PendingState extends OrderState {
16 @Override
17 public void confirm() {
18 order.setState(new ConfirmedState());
19 System.out.println("订单已确认");
20 }
21
22 @Override
23 public void ship() {
24 throw new IllegalStateException("待确认订单不能发货");
25 }
26
27 @Override
28 public void deliver() {
29 throw new IllegalStateException("待确认订单不能交付");
30 }
31
32 @Override
33 public void cancel() {
34 order.setState(new CancelledState());
35 System.out.println("订单已取消");
36 }
37}
38
39// 观察者模式 - 订单事件通知
40public class OrderEvent {
41 private String orderId;
42 private String eventType;
43 private Date timestamp;
44
45 // 构造函数、getter、setter
46}
47
48public class OrderService {
49 private List<OrderEventListener> listeners = new ArrayList<>();
50
51 public void addListener(OrderEventListener listener) {
52 listeners.add(listener);
53 }
54
55 public void placeOrder(Order order) {
56 // 处理订单逻辑
57 notifyListeners(new OrderEvent(order.getId(), "ORDER_PLACED"));
58 }
59
60 private void notifyListeners(OrderEvent event) {
61 for (OrderEventListener listener : listeners) {
62 listener.onOrderEvent(event);
63 }
64 }
65}
66
67// 命令模式 - 订单操作
68public interface OrderCommand {
69 void execute();
70 void undo();
71}
72
73public class PlaceOrderCommand implements OrderCommand {
74 private OrderService orderService;
75 private Order order;
76
77 public PlaceOrderCommand(OrderService orderService, Order order) {
78 this.orderService = orderService;
79 this.order = order;
80 }
81
82 @Override
83 public void execute() {
84 orderService.placeOrder(order);
85 }
86
87 @Override
88 public void undo() {
89 orderService.cancelOrder(order.getId());
90 }
91}

8. 性能考虑

8.1 模式选择对性能的影响

创建型模式性能分析

创建型模式性能对比
java
1// 单例模式 - 内存占用最小
2public class Singleton {
3 private static Singleton instance;
4
5 public static Singleton getInstance() {
6 if (instance == null) {
7 instance = new Singleton();
8 }
9 return instance;
10 }
11}
12
13// 工厂模式 - 对象创建开销
14public class Factory {
15 public Product createProduct(String type) {
16 switch (type) {
17 case "A": return new ProductA();
18 case "B": return new ProductB();
19 default: throw new IllegalArgumentException();
20 }
21 }
22}
23
24// 原型模式 - 克隆开销
25public class Prototype implements Cloneable {
26 private List<String> data = new ArrayList<>();
27
28 @Override
29 public Prototype clone() {
30 try {
31 Prototype clone = (Prototype) super.clone();
32 clone.data = new ArrayList<>(this.data); // 深拷贝开销
33 return clone;
34 } catch (CloneNotSupportedException e) {
35 throw new RuntimeException(e);
36 }
37 }
38}

结构型模式性能分析

结构型模式性能对比
java
1// 代理模式 - 方法调用开销
2public class Proxy implements Subject {
3 private RealSubject realSubject;
4
5 @Override
6 public void request() {
7 // 前置处理
8 long start = System.currentTimeMillis();
9
10 realSubject.request();
11
12 // 后置处理
13 long end = System.currentTimeMillis();
14 System.out.println("方法执行时间: " + (end - start) + "ms");
15 }
16}
17
18// 装饰器模式 - 对象包装开销
19public class Decorator implements Component {
20 private Component component;
21
22 @Override
23 public void operation() {
24 // 装饰逻辑
25 component.operation();
26 // 装饰逻辑
27 }
28}
29
30// 享元模式 - 内存优化
31public class FlyweightFactory {
32 private Map<String, Flyweight> flyweights = new HashMap<>();
33
34 public Flyweight getFlyweight(String key) {
35 return flyweights.computeIfAbsent(key, k -> new ConcreteFlyweight(k));
36 }
37}

8.2 优化策略

对象池模式

对象池实现
java
1public class ObjectPool<T> {
2 private final Supplier<T> factory;
3 private final Queue<T> pool;
4 private final int maxSize;
5
6 public ObjectPool(Supplier<T> factory, int maxSize) {
7 this.factory = factory;
8 this.maxSize = maxSize;
9 this.pool = new ConcurrentLinkedQueue<>();
10 }
11
12 public T borrow() {
13 T object = pool.poll();
14 return object != null ? object : factory.get();
15 }
16
17 public void release(T object) {
18 if (pool.size() < maxSize) {
19 pool.offer(object);
20 }
21 }
22}
23
24// 使用示例
25ObjectPool<Connection> connectionPool = new ObjectPool<>(
26 () -> createConnection(),
27 10
28);
29
30Connection conn = connectionPool.borrow();
31try {
32 // 使用连接
33} finally {
34 connectionPool.release(conn);
35}

延迟加载

延迟加载实现
java
1public class LazySingleton {
2 private static volatile LazySingleton instance;
3
4 public static LazySingleton getInstance() {
5 if (instance == null) {
6 synchronized (LazySingleton.class) {
7 if (instance == null) {
8 instance = new LazySingleton();
9 }
10 }
11 }
12 return instance;
13 }
14}
15
16public class LazyInitialization {
17 private volatile ExpensiveObject expensiveObject;
18
19 public ExpensiveObject getExpensiveObject() {
20 if (expensiveObject == null) {
21 synchronized (this) {
22 if (expensiveObject == null) {
23 expensiveObject = new ExpensiveObject();
24 }
25 }
26 }
27 return expensiveObject;
28 }
29}

9. 面试题精选

9.1 基础概念题

Q1: 设计模式的分类和特点是什么?

: 设计模式按目的分为三大类:

创建型模式

  • 解决对象创建问题
  • 包括:单例、工厂方法、抽象工厂、建造者、原型
  • 特点:封装对象创建过程,提高系统灵活性

结构型模式

  • 解决对象组合问题
  • 包括:适配器、桥接、组合、装饰器、外观、享元、代理
  • 特点:关注对象间的组合关系

行为型模式

  • 解决对象交互问题
  • 包括:责任链、命令、解释器、迭代器、中介者、备忘录、观察者、状态、策略、模板方法、访问者
  • 特点:关注对象间的通信机制

Q2: SOLID原则的含义是什么?

: SOLID是面向对象设计的五个基本原则:

  1. S - 单一职责原则:一个类应该只有一个变化的原因
  2. O - 开闭原则:对扩展开放,对修改关闭
  3. L - 里氏替换原则:子类应该能够替换父类
  4. I - 接口隔离原则:客户端不应该依赖它不需要的接口
  5. D - 依赖倒置原则:依赖抽象而不是具体实现

Q3: 设计模式和设计原则的区别是什么?

:

  • 设计原则:是指导设计的基本准则,如SOLID原则
  • 设计模式:是解决特定问题的具体方案,如23种经典模式
  • 关系:设计模式是设计原则的具体应用和体现

9.2 具体模式题

Q4: 单例模式的线程安全实现有哪些?

:

  1. 饿汉式:类加载时就初始化,线程安全
java
1public class Singleton {
2 private static final Singleton instance = new Singleton();
3 private Singleton() {}
4 public static Singleton getInstance() { return instance; }
5}
  1. 双重检查锁定:延迟加载,线程安全
java
1public class Singleton {
2 private static volatile Singleton instance;
3 private Singleton() {}
4 public static Singleton getInstance() {
5 if (instance == null) {
6 synchronized (Singleton.class) {
7 if (instance == null) {
8 instance = new Singleton();
9 }
10 }
11 }
12 return instance;
13 }
14}
  1. 枚举实现:最简单,自动线程安全
java
1public enum Singleton {
2 INSTANCE;
3 public void doSomething() {}
4}

Q5: 工厂模式和抽象工厂的区别是什么?

: 工厂方法模式

  • 定义一个创建对象的接口,让子类决定实例化哪个类
  • 适用于单一产品族
  • 扩展新产品时需要修改工厂类

抽象工厂模式

  • 提供一个创建一系列相关对象的接口
  • 适用于多个产品族
  • 扩展新产品族时需要修改抽象工厂接口

Q6: 装饰器模式和代理模式的区别是什么?

: 装饰器模式

  • 目的:动态添加功能
  • 关系:装饰器与被装饰对象实现相同接口
  • 特点:可以多层装饰,功能叠加

代理模式

  • 目的:控制对象访问
  • 关系:代理与被代理对象实现相同接口
  • 特点:通常只有一层代理,控制访问

9.3 实际应用题

Q7: 如何在项目中应用设计模式?

:

  1. 识别问题:分析代码中的重复问题和不合理设计
  2. 选择模式:根据问题类型选择合适的模式
  3. 重构代码:逐步重构,保持向后兼容
  4. 测试验证:确保重构后功能正确
  5. 文档记录:记录模式应用的原因和效果

Q8: 如何避免过度设计?

:

  1. YAGNI原则:You Aren't Gonna Need It,不要过早优化
  2. 简单优先:优先使用简单直接的解决方案
  3. 实际需求:只在确实需要时才使用设计模式
  4. 团队共识:确保团队理解模式的使用
  5. 持续重构:随着需求变化调整设计

Q9: 如何评估设计模式的效果?

:

  1. 代码质量:可读性、可维护性、可扩展性
  2. 性能影响:内存使用、执行效率
  3. 复杂度:代码复杂度是否合理
  4. 团队接受度:团队成员是否理解和使用
  5. 业务价值:是否解决了实际问题

9.4 性能优化题

Q10: 设计模式对性能的影响有哪些?

: 正面影响

  • 提高代码复用性,减少重复代码
  • 优化对象创建和销毁
  • 改善内存使用模式

负面影响

  • 增加代码复杂度
  • 引入额外的对象和方法调用
  • 可能增加内存占用

优化策略

  • 合理选择模式,避免过度使用
  • 使用对象池减少创建开销
  • 采用延迟加载优化初始化
  • 考虑缓存机制提高性能
设计模式学习要点
  1. 理解原理:深入理解每个模式的核心思想
  2. 实践应用:在实际项目中应用设计模式
  3. 权衡取舍:根据具体场景选择合适的模式
  4. 持续学习:关注新的设计模式和最佳实践
  5. 团队协作:与团队分享和交流设计经验

通过本章的学习,你应该已经掌握了设计模式的核心概念、分类体系、实际应用和最佳实践。设计模式是提高代码质量的重要工具,但需要根据具体场景合理使用,避免过度设计。在实际项目中,要结合业务需求和团队能力,选择合适的设计模式,并持续优化和改进。

forum

评论区 / Comments