抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

设计模式是软件开发中经过验证的最佳实践,面向对象设计原则是编写可维护、可扩展代码的指导方针。本文系统总结Java中常用的设计模式和SOLID等设计原则。

面向对象设计原则

SOLID原则概览

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
┌──────────────────────────────────────────────────────────────────┐
│ SOLID原则 │
├──────────────────────────────────────────────────────────────────┤
│ │
│ S - Single Responsibility Principle 单一职责原则 │
│ 一个类只负责一项职责 │
│ │
│ O - Open/Closed Principle 开闭原则 │
│ 对扩展开放,对修改关闭 │
│ │
│ L - Liskov Substitution Principle 里氏替换原则 │
│ 子类可以替换父类出现的任何地方 │
│ │
│ I - Interface Segregation Principle 接口隔离原则 │
│ 使用多个专门接口,而非单一总接口 │
│ │
│ D - Dependency Inversion Principle 依赖倒置原则 │
│ 依赖抽象而非具体实现 │
│ │
└──────────────────────────────────────────────────────────────────┘

单一职责原则(SRP)

一个类应该只有一个引起它变化的原因。

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
// 违反SRP:User类承担了太多职责
public class User {
private String name;
private String email;

public void saveToDatabase() { /* 数据库操作 */ }
public void sendEmail() { /* 邮件发送 */ }
public String generateReport() { /* 报表生成 */ }
}

// 遵循SRP:职责分离
public class User {
private String name;
private String email;
// 只包含用户属性和基本行为
}

public class UserRepository {
public void save(User user) { /* 数据库操作 */ }
}

public class EmailService {
public void sendEmail(User user, String content) { /* 邮件发送 */ }
}

public class UserReportGenerator {
public String generate(User user) { /* 报表生成 */ }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
┌──────────────────────────────────────────────────────────────────┐
│ 单一职责原则 │
├──────────────────────────────────────────────────────────────────┤
│ │
│ 违反SRP: 遵循SRP: │
│ ┌─────────────────┐ ┌──────────┐ │
│ │ User │ │ User │ │
│ │─────────────────│ └──────────┘ │
│ │ saveToDatabase()│ │ │
│ │ sendEmail() │ ┌─────────────┼─────────────┐ │
│ │ generateReport()│ ▼ ▼ ▼ │
│ └─────────────────┘ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │UserRepo │ │EmailSvc │ │ReportGen │ │
│ 一个类三个变化原因 └──────────┘ └──────────┘ └──────────┘ │
│ 每个类一个变化原因 │
│ │
└──────────────────────────────────────────────────────────────────┘

开闭原则(OCP)

软件实体应该对扩展开放,对修改关闭。

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
// 违反OCP:添加新形状需要修改计算方法
public class AreaCalculator {
public double calculate(Object shape) {
if (shape instanceof Rectangle) {
Rectangle r = (Rectangle) shape;
return r.width * r.height;
} else if (shape instanceof Circle) {
Circle c = (Circle) shape;
return Math.PI * c.radius * c.radius;
}
// 添加新形状需要修改这里
return 0;
}
}

// 遵循OCP:通过抽象扩展
public interface Shape {
double area();
}

public class Rectangle implements Shape {
private double width, height;

@Override
public double area() {
return width * height;
}
}

public class Circle implements Shape {
private double radius;

@Override
public double area() {
return Math.PI * radius * radius;
}
}

// 添加新形状只需新增类,无需修改已有代码
public class Triangle implements Shape {
private double base, height;

@Override
public double area() {
return 0.5 * base * height;
}
}

public class AreaCalculator {
public double calculate(Shape shape) {
return shape.area(); // 对修改关闭
}
}

里氏替换原则(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
// 违反LSP的经典例子:正方形继承矩形
public class Rectangle {
protected int width;
protected int height;

public void setWidth(int width) { this.width = width; }
public void setHeight(int height) { this.height = height; }
public int getArea() { return width * height; }
}

public class Square extends Rectangle {
@Override
public void setWidth(int width) {
this.width = width;
this.height = width; // 正方形宽高相等
}

@Override
public void setHeight(int height) {
this.width = height;
this.height = height;
}
}

// 使用父类的代码
public void resize(Rectangle r) {
r.setWidth(5);
r.setHeight(10);
assert r.getArea() == 50; // 如果传入Square,断言失败!
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
┌──────────────────────────────────────────────────────────────────┐
│ 里氏替换原则 │
├──────────────────────────────────────────────────────────────────┤
│ │
│ 正确做法:使用组合或共同抽象 │
│ │
│ ┌──────────────┐ │
│ │ Shape │ │
│ │──────────────│ │
│ │ + getArea() │ │
│ └──────┬───────┘ │
│ │ │
│ ┌───────────┴───────────┐ │
│ ▼ ▼ │
│ ┌──────────────┐ ┌──────────────┐ │
│ │ Rectangle │ │ Square │ │
│ │──────────────│ │──────────────│ │
│ │ width,height │ │ side │ │
│ └──────────────┘ └──────────────┘ │
│ │
│ LSP核心:子类不应该破坏父类的契约(前置条件、后置条件、不变量) │
│ │
└──────────────────────────────────────────────────────────────────┘

接口隔离原则(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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
// 违反ISP:臃肿的接口
public interface Worker {
void work();
void eat();
void sleep();
}

// 机器人不需要eat和sleep
public class Robot implements Worker {
@Override
public void work() { /* 工作 */ }

@Override
public void eat() { /* 被迫实现空方法 */ }

@Override
public void sleep() { /* 被迫实现空方法 */ }
}

// 遵循ISP:接口拆分
public interface Workable {
void work();
}

public interface Eatable {
void eat();
}

public interface Sleepable {
void sleep();
}

public class Human implements Workable, Eatable, Sleepable {
@Override
public void work() { /* 工作 */ }

@Override
public void eat() { /* 吃饭 */ }

@Override
public void sleep() { /* 睡觉 */ }
}

public class Robot implements Workable {
@Override
public void work() { /* 工作 */ }
// 只实现需要的接口
}

依赖倒置原则(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
29
30
31
32
33
34
35
// 违反DIP:直接依赖具体实现
public class OrderService {
private MySQLDatabase database = new MySQLDatabase(); // 直接依赖
private EmailSender emailSender = new EmailSender();

public void createOrder(Order order) {
database.save(order);
emailSender.send(order.getUserEmail(), "订单创建成功");
}
}

// 遵循DIP:依赖抽象
public interface Database {
void save(Object entity);
}

public interface NotificationService {
void send(String to, String message);
}

public class OrderService {
private final Database database;
private final NotificationService notificationService;

// 通过构造函数注入依赖
public OrderService(Database database, NotificationService notificationService) {
this.database = database;
this.notificationService = notificationService;
}

public void createOrder(Order order) {
database.save(order);
notificationService.send(order.getUserEmail(), "订单创建成功");
}
}
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
┌──────────────────────────────────────────────────────────────────┐
│ 依赖倒置原则 │
├──────────────────────────────────────────────────────────────────┤
│ │
│ 违反DIP: 遵循DIP: │
│ │
│ ┌────────────────┐ ┌────────────────┐ │
│ │ OrderService │ │ OrderService │ │
│ │ (高层) │ │ (高层) │ │
│ └───────┬────────┘ └───────┬────────┘ │
│ │ 依赖 │ 依赖 │
│ ▼ ▼ │
│ ┌────────────────┐ ┌────────────────┐ │
│ │ MySQLDatabase │ │ Database │ ◀─ 抽象 │
│ │ (低层) │ │ (interface) │ │
│ └────────────────┘ └───────┬────────┘ │
│ │ 实现 │
│ 高层直接依赖低层 ▼ │
│ 更换数据库需要修改高层 ┌────────────────┐ │
│ │ MySQLDatabase │ │
│ │ (低层) │ │
│ └────────────────┘ │
│ 更换数据库只需更换实现 │
│ │
└──────────────────────────────────────────────────────────────────┘

其他重要原则

迪米特法则(最少知识原则)

一个对象应该对其他对象有最少的了解。

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
// 违反迪米特法则
public class Customer {
private Wallet wallet;
public Wallet getWallet() { return wallet; }
}

public class Paperboy {
public void collectMoney(Customer customer, double amount) {
// 直接访问customer的wallet,了解太多细节
if (customer.getWallet().getMoney() >= amount) {
customer.getWallet().subtractMoney(amount);
}
}
}

// 遵循迪米特法则
public class Customer {
private Wallet wallet;

// 只暴露必要的方法
public double pay(double amount) {
if (wallet.getMoney() >= amount) {
wallet.subtractMoney(amount);
return amount;
}
return 0;
}
}

public class Paperboy {
public void collectMoney(Customer customer, double amount) {
double paid = customer.pay(amount); // 只与直接对象交互
}
}

合成复用原则

优先使用组合而非继承来达到复用目的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// 使用继承(紧耦合)
public class Car extends Engine {
// Car IS-A Engine? 语义不对
}

// 使用组合(松耦合)
public class Car {
private Engine engine; // Car HAS-A Engine

public Car(Engine engine) {
this.engine = engine;
}

public void start() {
engine.start();
}
}

// 可以灵活更换引擎
Car electricCar = new Car(new ElectricEngine());
Car gasCar = new Car(new GasEngine());
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
┌──────────────────────────────────────────────────────────────────┐
│ 继承 vs 组合 │
├──────────────────────────────────────────────────────────────────┤
│ │
│ 继承: │
│ • IS-A 关系(猫是动物) │
│ • 编译时确定,静态绑定 │
│ • 紧耦合,子类暴露父类细节 │
│ • 破坏封装性 │
│ │
│ 组合: │
│ • HAS-A 关系(汽车有引擎) │
│ • 运行时确定,动态绑定 │
│ • 松耦合,只依赖接口 │
│ • 保持封装性 │
│ │
│ 原则:优先使用组合,只在真正的IS-A关系时使用继承 │
│ │
└──────────────────────────────────────────────────────────────────┘

设计模式概览

设计模式分类

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
┌──────────────────────────────────────────────────────────────────┐
│ 23种设计模式 │
├──────────────────────────────────────────────────────────────────┤
│ │
│ 创建型模式(5种) 关注对象的创建 │
│ ───────────────────────────────────────────── │
│ • 单例模式(Singleton) 确保类只有一个实例 │
│ • 工厂方法(Factory Method) 定义创建对象的接口 │
│ • 抽象工厂(Abstract Factory)创建相关对象族 │
│ • 建造者(Builder) 分步骤构建复杂对象 │
│ • 原型(Prototype) 通过复制创建对象 │
│ │
│ 结构型模式(7种) 关注类和对象的组合 │
│ ───────────────────────────────────────────── │
│ • 适配器(Adapter) 转换接口 │
│ • 桥接(Bridge) 分离抽象和实现 │
│ • 组合(Composite) 树形结构 │
│ • 装饰器(Decorator) 动态添加职责 │
│ • 外观(Facade) 简化子系统接口 │
│ • 享元(Flyweight) 共享细粒度对象 │
│ • 代理(Proxy) 控制对象访问 │
│ │
│ 行为型模式(11种) 关注对象间的通信 │
│ ───────────────────────────────────────────── │
│ • 责任链(Chain of Responsibility) │
│ • 命令(Command) 封装请求 │
│ • 迭代器(Iterator) 遍历集合 │
│ • 中介者(Mediator) 封装对象交互 │
│ • 备忘录(Memento) 保存对象状态 │
│ • 观察者(Observer) 一对多依赖 │
│ • 状态(State) 状态决定行为 │
│ • 策略(Strategy) 封装算法 │
│ • 模板方法(Template Method) 定义算法骨架 │
│ • 访问者(Visitor) 分离数据结构与操作 │
│ • 解释器(Interpreter) 语言解释器 │
│ │
└──────────────────────────────────────────────────────────────────┘

创建型模式

单例模式(Singleton)

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

饿汉式

1
2
3
4
5
6
7
8
9
10
public class Singleton {
// 类加载时就创建实例
private static final Singleton INSTANCE = new Singleton();

private Singleton() {} // 私有构造函数

public static Singleton getInstance() {
return INSTANCE;
}
}

懒汉式(双重检查锁)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class Singleton {
// volatile防止指令重排
private static volatile Singleton instance;

private Singleton() {}

public static Singleton getInstance() {
if (instance == null) { // 第一次检查
synchronized (Singleton.class) {
if (instance == null) { // 第二次检查
instance = new Singleton();
}
}
}
return instance;
}
}

静态内部类(推荐)

1
2
3
4
5
6
7
8
9
10
11
12
public class Singleton {
private Singleton() {}

// 静态内部类,延迟加载,线程安全
private static class Holder {
private static final Singleton INSTANCE = new Singleton();
}

public static Singleton getInstance() {
return Holder.INSTANCE;
}
}

枚举(最佳实践)

1
2
3
4
5
6
7
8
9
10
public enum Singleton {
INSTANCE;

public void doSomething() {
// 业务方法
}
}

// 使用
Singleton.INSTANCE.doSomething();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
┌──────────────────────────────────────────────────────────────────┐
│ 单例模式对比 │
├──────────────────────────────────────────────────────────────────┤
│ │
│ 实现方式 线程安全 延迟加载 防止反射 防止序列化 │
│ ─────────────────────────────────────────────────────────── │
│ 饿汉式 ✓ ✗ ✗ ✗ │
│ 懒汉式(同步方法) ✓ ✓ ✗ ✗ │
│ 双重检查锁 ✓ ✓ ✗ ✗ │
│ 静态内部类 ✓ ✓ ✗ ✗ │
│ 枚举 ✓ ✗ ✓ ✓ │
│ │
│ 推荐:枚举 > 静态内部类 > 双重检查锁 │
│ │
└──────────────────────────────────────────────────────────────────┘

工厂方法模式(Factory Method)

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

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
// 产品接口
public interface Product {
void use();
}

// 具体产品
public class ConcreteProductA implements Product {
@Override
public void use() {
System.out.println("使用产品A");
}
}

public class ConcreteProductB implements Product {
@Override
public void use() {
System.out.println("使用产品B");
}
}

// 工厂接口
public interface Factory {
Product createProduct();
}

// 具体工厂
public class FactoryA implements Factory {
@Override
public Product createProduct() {
return new ConcreteProductA();
}
}

public class FactoryB implements Factory {
@Override
public Product createProduct() {
return new ConcreteProductB();
}
}

// 使用
Factory factory = new FactoryA();
Product product = factory.createProduct();
product.use();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
┌──────────────────────────────────────────────────────────────────┐
│ 工厂方法模式 │
├──────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────┐ ┌──────────────┐ │
│ │ Factory │ │ Product │ │
│ │──────────────│ │──────────────│ │
│ │createProduct()│──────creates──▶│ use() │ │
│ └──────┬───────┘ └──────┬───────┘ │
│ │ │ │
│ ┌───────┴───────┐ ┌───────┴───────┐ │
│ ▼ ▼ ▼ ▼ │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │FactoryA │ │FactoryB │ │ProductA │ │ProductB │ │
│ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │
│ │
│ 优点: │
│ • 符合开闭原则,新增产品只需新增工厂 │
│ • 解耦客户端和具体产品 │
│ │
└──────────────────────────────────────────────────────────────────┘

抽象工厂模式(Abstract Factory)

提供创建一系列相关对象的接口,无需指定具体类。

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
// 抽象产品族
public interface Button {
void render();
}

public interface TextField {
void render();
}

// Windows产品族
public class WindowsButton implements Button {
@Override
public void render() {
System.out.println("Windows风格按钮");
}
}

public class WindowsTextField implements TextField {
@Override
public void render() {
System.out.println("Windows风格文本框");
}
}

// Mac产品族
public class MacButton implements Button {
@Override
public void render() {
System.out.println("Mac风格按钮");
}
}

public class MacTextField implements TextField {
@Override
public void render() {
System.out.println("Mac风格文本框");
}
}

// 抽象工厂
public interface GUIFactory {
Button createButton();
TextField createTextField();
}

// 具体工厂
public class WindowsFactory implements GUIFactory {
@Override
public Button createButton() {
return new WindowsButton();
}

@Override
public TextField createTextField() {
return new WindowsTextField();
}
}

public class MacFactory implements GUIFactory {
@Override
public Button createButton() {
return new MacButton();
}

@Override
public TextField createTextField() {
return new MacTextField();
}
}

// 使用
GUIFactory factory = new WindowsFactory();
Button button = factory.createButton();
TextField textField = factory.createTextField();

建造者模式(Builder)

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

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
public class Computer {
private String cpu;
private String ram;
private String storage;
private String gpu;
private String screen;

private Computer(Builder builder) {
this.cpu = builder.cpu;
this.ram = builder.ram;
this.storage = builder.storage;
this.gpu = builder.gpu;
this.screen = builder.screen;
}

// 静态内部Builder类
public static class Builder {
private String cpu;
private String ram;
private String storage;
private String gpu;
private String screen;

public Builder cpu(String cpu) {
this.cpu = cpu;
return this;
}

public Builder ram(String ram) {
this.ram = ram;
return this;
}

public Builder storage(String storage) {
this.storage = storage;
return this;
}

public Builder gpu(String gpu) {
this.gpu = gpu;
return this;
}

public Builder screen(String screen) {
this.screen = screen;
return this;
}

public Computer build() {
return new Computer(this);
}
}
}

// 使用(链式调用)
Computer computer = new Computer.Builder()
.cpu("Intel i9")
.ram("32GB")
.storage("1TB SSD")
.gpu("RTX 4090")
.screen("4K")
.build();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
┌──────────────────────────────────────────────────────────────────┐
│ 建造者模式 │
├──────────────────────────────────────────────────────────────────┤
│ │
│ 适用场景: │
│ • 构造函数参数过多 │
│ • 需要创建不可变对象 │
│ • 参数之间有依赖关系或需要校验 │
│ │
│ JDK中的应用: │
│ • StringBuilder │
│ • Stream.Builder │
│ • Locale.Builder │
│ │
│ 第三方库: │
│ • Lombok的@Builder注解 │
│ │
└──────────────────────────────────────────────────────────────────┘

原型模式(Prototype)

通过复制现有对象来创建新对象。

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
public class Prototype implements Cloneable {
private String name;
private List<String> items;

public Prototype(String name) {
this.name = name;
this.items = new ArrayList<>();
}

// 浅拷贝
@Override
public Prototype clone() {
try {
return (Prototype) super.clone();
} catch (CloneNotSupportedException e) {
throw new RuntimeException(e);
}
}

// 深拷贝
public Prototype deepClone() {
Prototype clone = new Prototype(this.name);
clone.items = new ArrayList<>(this.items);
return clone;
}
}

结构型模式

适配器模式(Adapter)

将一个类的接口转换成客户期望的另一个接口。

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
// 目标接口
public interface MediaPlayer {
void play(String filename);
}

// 被适配的类
public class VlcPlayer {
public void playVlc(String filename) {
System.out.println("Playing VLC: " + filename);
}
}

public class Mp4Player {
public void playMp4(String filename) {
System.out.println("Playing MP4: " + filename);
}
}

// 适配器(对象适配器)
public class MediaAdapter implements MediaPlayer {
private VlcPlayer vlcPlayer;
private Mp4Player mp4Player;

public MediaAdapter(String audioType) {
if (audioType.equalsIgnoreCase("vlc")) {
vlcPlayer = new VlcPlayer();
} else if (audioType.equalsIgnoreCase("mp4")) {
mp4Player = new Mp4Player();
}
}

@Override
public void play(String filename) {
if (vlcPlayer != null) {
vlcPlayer.playVlc(filename);
} else if (mp4Player != null) {
mp4Player.playMp4(filename);
}
}
}

// 使用
MediaPlayer player = new MediaAdapter("vlc");
player.play("movie.vlc");
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
┌──────────────────────────────────────────────────────────────────┐
│ 适配器模式 │
├──────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ Client │───────▶│ Target │◀───────│ Adapter │ │
│ └──────────┘ │(interface)│ └────┬─────┘ │
│ └──────────┘ │ │
│ │ 持有 │
│ ▼ │
│ ┌──────────┐ │
│ │ Adaptee │ │
│ │(被适配者) │ │
│ └──────────┘ │
│ │
│ JDK中的应用: │
│ • InputStreamReader(InputStream → Reader) │
│ • Arrays.asList()(数组 → List) │
│ • Collections.enumeration() │
│ │
└──────────────────────────────────────────────────────────────────┘

装饰器模式(Decorator)

动态地给对象添加额外的职责。

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
// 组件接口
public interface Coffee {
String getDescription();
double getCost();
}

// 具体组件
public class SimpleCoffee implements Coffee {
@Override
public String getDescription() {
return "普通咖啡";
}

@Override
public double getCost() {
return 10.0;
}
}

// 抽象装饰器
public abstract class CoffeeDecorator implements Coffee {
protected Coffee coffee;

public CoffeeDecorator(Coffee coffee) {
this.coffee = coffee;
}
}

// 具体装饰器
public class MilkDecorator extends CoffeeDecorator {
public MilkDecorator(Coffee coffee) {
super(coffee);
}

@Override
public String getDescription() {
return coffee.getDescription() + " + 牛奶";
}

@Override
public double getCost() {
return coffee.getCost() + 3.0;
}
}

public class SugarDecorator extends CoffeeDecorator {
public SugarDecorator(Coffee coffee) {
super(coffee);
}

@Override
public String getDescription() {
return coffee.getDescription() + " + 糖";
}

@Override
public double getCost() {
return coffee.getCost() + 1.0;
}
}

// 使用(可以多层装饰)
Coffee coffee = new SimpleCoffee();
coffee = new MilkDecorator(coffee);
coffee = new SugarDecorator(coffee);
System.out.println(coffee.getDescription()); // 普通咖啡 + 牛奶 + 糖
System.out.println(coffee.getCost()); // 14.0
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
┌──────────────────────────────────────────────────────────────────┐
│ 装饰器模式 │
├──────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────┐ │
│ │ Component │ │
│ │ (interface) │ │
│ └────────┬────────┘ │
│ │ │
│ ┌────────────┴────────────┐ │
│ ▼ ▼ │
│ ┌─────────────────┐ ┌─────────────────┐ │
│ │ConcreteComponent│ │ Decorator │ │
│ │ (SimpleCoffee) │ │ (abstract) │ │
│ └─────────────────┘ └────────┬────────┘ │
│ │ │
│ ┌──────────┴──────────┐ │
│ ▼ ▼ │
│ ┌─────────────────┐ ┌─────────────────┐ │
│ │ MilkDecorator │ │ SugarDecorator │ │
│ └─────────────────┘ └─────────────────┘ │
│ │
│ JDK中的应用: │
│ • Java I/O流(BufferedInputStream包装InputStream) │
│ • Collections.synchronizedList() │
│ • Collections.unmodifiableList() │
│ │
└──────────────────────────────────────────────────────────────────┘

代理模式(Proxy)

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

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
// 主题接口
public interface Image {
void display();
}

// 真实主题
public class RealImage implements Image {
private String filename;

public RealImage(String filename) {
this.filename = filename;
loadFromDisk(); // 耗时操作
}

private void loadFromDisk() {
System.out.println("Loading image: " + filename);
}

@Override
public void display() {
System.out.println("Displaying: " + filename);
}
}

// 代理
public class ProxyImage implements Image {
private String filename;
private RealImage realImage;

public ProxyImage(String filename) {
this.filename = filename;
}

@Override
public void display() {
// 延迟加载
if (realImage == null) {
realImage = new RealImage(filename);
}
realImage.display();
}
}

// 使用
Image image = new ProxyImage("photo.jpg");
// 此时还没有加载图片
image.display(); // 首次调用才加载
image.display(); // 不再加载

JDK动态代理

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
public interface UserService {
void save(String name);
}

public class UserServiceImpl implements UserService {
@Override
public void save(String name) {
System.out.println("保存用户: " + name);
}
}

// 动态代理
public class LoggingHandler implements InvocationHandler {
private Object target;

public LoggingHandler(Object target) {
this.target = target;
}

@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("方法调用前: " + method.getName());
Object result = method.invoke(target, args);
System.out.println("方法调用后: " + method.getName());
return result;
}
}

// 使用
UserService userService = new UserServiceImpl();
UserService proxy = (UserService) Proxy.newProxyInstance(
userService.getClass().getClassLoader(),
userService.getClass().getInterfaces(),
new LoggingHandler(userService)
);
proxy.save("张三");
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
┌──────────────────────────────────────────────────────────────────┐
│ 代理模式类型 │
├──────────────────────────────────────────────────────────────────┤
│ │
│ 静态代理 │
│ • 编译期确定代理类 │
│ • 每个被代理类需要一个代理类 │
│ │
│ JDK动态代理 │
│ • 运行时生成代理类 │
│ • 被代理类必须实现接口 │
│ • 使用Proxy.newProxyInstance() │
│ │
│ CGLIB代理 │
│ • 运行时生成代理类 │
│ • 通过继承实现,无需接口 │
│ • 不能代理final类和方法 │
│ │
│ 应用场景: │
│ • AOP(面向切面编程) │
│ • 远程代理(RPC) │
│ • 延迟加载 │
│ • 访问控制 │
│ │
└──────────────────────────────────────────────────────────────────┘

外观模式(Facade)

为子系统提供一个统一的高层接口。

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
// 复杂的子系统
public class CPU {
public void start() { System.out.println("CPU启动"); }
public void shutdown() { System.out.println("CPU关闭"); }
}

public class Memory {
public void load() { System.out.println("内存加载"); }
public void clear() { System.out.println("内存清理"); }
}

public class HardDrive {
public void read() { System.out.println("硬盘读取"); }
public void write() { System.out.println("硬盘写入"); }
}

// 外观类
public class ComputerFacade {
private CPU cpu;
private Memory memory;
private HardDrive hardDrive;

public ComputerFacade() {
this.cpu = new CPU();
this.memory = new Memory();
this.hardDrive = new HardDrive();
}

// 简化的接口
public void start() {
cpu.start();
memory.load();
hardDrive.read();
System.out.println("电脑启动完成");
}

public void shutdown() {
hardDrive.write();
memory.clear();
cpu.shutdown();
System.out.println("电脑关机完成");
}
}

// 使用
ComputerFacade computer = new ComputerFacade();
computer.start(); // 一键启动
computer.shutdown(); // 一键关机

组合模式(Composite)

将对象组合成树形结构,使客户端统一处理单个对象和组合对象。

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
// 组件接口
public interface FileSystemComponent {
void display(int indent);
long getSize();
}

// 叶子节点
public class File implements FileSystemComponent {
private String name;
private long size;

public File(String name, long size) {
this.name = name;
this.size = size;
}

@Override
public void display(int indent) {
System.out.println(" ".repeat(indent) + "📄 " + name + " (" + size + "KB)");
}

@Override
public long getSize() {
return size;
}
}

// 组合节点
public class Directory implements FileSystemComponent {
private String name;
private List<FileSystemComponent> children = new ArrayList<>();

public Directory(String name) {
this.name = name;
}

public void add(FileSystemComponent component) {
children.add(component);
}

public void remove(FileSystemComponent component) {
children.remove(component);
}

@Override
public void display(int indent) {
System.out.println(" ".repeat(indent) + "📁 " + name);
for (FileSystemComponent child : children) {
child.display(indent + 2);
}
}

@Override
public long getSize() {
return children.stream()
.mapToLong(FileSystemComponent::getSize)
.sum();
}
}

// 使用
Directory root = new Directory("root");
Directory docs = new Directory("documents");
docs.add(new File("resume.pdf", 100));
docs.add(new File("report.docx", 200));
root.add(docs);
root.add(new File("readme.txt", 10));
root.display(0);

行为型模式

策略模式(Strategy)

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

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
// 策略接口
public interface PaymentStrategy {
void pay(double amount);
}

// 具体策略
public class CreditCardPayment implements PaymentStrategy {
private String cardNumber;

public CreditCardPayment(String cardNumber) {
this.cardNumber = cardNumber;
}

@Override
public void pay(double amount) {
System.out.println("信用卡支付: " + amount + "元,卡号: " + cardNumber);
}
}

public class AlipayPayment implements PaymentStrategy {
private String account;

public AlipayPayment(String account) {
this.account = account;
}

@Override
public void pay(double amount) {
System.out.println("支付宝支付: " + amount + "元,账号: " + account);
}
}

public class WeChatPayment implements PaymentStrategy {
@Override
public void pay(double amount) {
System.out.println("微信支付: " + amount + "元");
}
}

// 上下文
public class ShoppingCart {
private PaymentStrategy paymentStrategy;

public void setPaymentStrategy(PaymentStrategy strategy) {
this.paymentStrategy = strategy;
}

public void checkout(double amount) {
paymentStrategy.pay(amount);
}
}

// 使用
ShoppingCart cart = new ShoppingCart();
cart.setPaymentStrategy(new AlipayPayment("user@example.com"));
cart.checkout(100.0);

cart.setPaymentStrategy(new WeChatPayment());
cart.checkout(200.0);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
┌──────────────────────────────────────────────────────────────────┐
│ 策略模式 │
├──────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────┐ ┌─────────────────┐ │
│ │ Context │────────▶│ Strategy │ │
│ │ │ │ (interface) │ │
│ └──────────┘ └────────┬────────┘ │
│ │ │
│ ┌─────────────────┼─────────────────┐ │
│ ▼ ▼ ▼ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │StrategyA │ │StrategyB │ │StrategyC │ │
│ │(CreditCard) │ │(Alipay) │ │(WeChat) │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │
│ vs if-else: │
│ • 策略模式符合开闭原则 │
│ • 新增策略无需修改现有代码 │
│ • 算法可以独立变化 │
│ │
└──────────────────────────────────────────────────────────────────┘

观察者模式(Observer)

定义对象间的一对多依赖关系,当一个对象状态改变时,所有依赖者都会收到通知。

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
// 观察者接口
public interface Observer {
void update(String message);
}

// 主题接口
public interface Subject {
void registerObserver(Observer observer);
void removeObserver(Observer observer);
void notifyObservers();
}

// 具体主题
public class NewsPublisher implements Subject {
private List<Observer> observers = new ArrayList<>();
private String news;

@Override
public void registerObserver(Observer observer) {
observers.add(observer);
}

@Override
public void removeObserver(Observer observer) {
observers.remove(observer);
}

@Override
public void notifyObservers() {
for (Observer observer : observers) {
observer.update(news);
}
}

public void publishNews(String news) {
this.news = news;
notifyObservers();
}
}

// 具体观察者
public class EmailSubscriber implements Observer {
private String email;

public EmailSubscriber(String email) {
this.email = email;
}

@Override
public void update(String message) {
System.out.println("发送邮件到 " + email + ": " + message);
}
}

public class AppSubscriber implements Observer {
private String userId;

public AppSubscriber(String userId) {
this.userId = userId;
}

@Override
public void update(String message) {
System.out.println("推送通知给用户 " + userId + ": " + message);
}
}

// 使用
NewsPublisher publisher = new NewsPublisher();
publisher.registerObserver(new EmailSubscriber("user@example.com"));
publisher.registerObserver(new AppSubscriber("12345"));
publisher.publishNews("重大新闻发布!");

Java内置观察者(JDK 9后已废弃)

1
2
3
4
5
// JDK 9+ 推荐使用Flow API或第三方库
// Java 9引入的Flow API
public class NewsPublisher implements Flow.Publisher<String> {
// ...
}

模板方法模式(Template Method)

定义算法骨架,将某些步骤延迟到子类。

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
// 抽象类
public abstract class DataProcessor {

// 模板方法(final防止子类覆盖)
public final void process() {
readData();
processData();
writeData();
if (needsNotification()) { // 钩子方法
sendNotification();
}
}

// 抽象方法,子类必须实现
protected abstract void readData();
protected abstract void processData();

// 具体方法,子类可以直接使用
protected void writeData() {
System.out.println("写入数据到默认位置");
}

// 钩子方法,子类可选择覆盖
protected boolean needsNotification() {
return false;
}

protected void sendNotification() {
System.out.println("发送通知");
}
}

// 具体实现
public class CSVDataProcessor extends DataProcessor {
@Override
protected void readData() {
System.out.println("读取CSV文件");
}

@Override
protected void processData() {
System.out.println("处理CSV数据");
}
}

public class DatabaseDataProcessor extends DataProcessor {
@Override
protected void readData() {
System.out.println("从数据库读取");
}

@Override
protected void processData() {
System.out.println("处理数据库数据");
}

@Override
protected boolean needsNotification() {
return true; // 覆盖钩子
}
}

// 使用
DataProcessor processor = new DatabaseDataProcessor();
processor.process();
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
┌──────────────────────────────────────────────────────────────────┐
│ 模板方法模式 │
├──────────────────────────────────────────────────────────────────┤
│ │
│ ┌────────────────────────────────────────────────┐ │
│ │ AbstractClass │ │
│ │────────────────────────────────────────────────│ │
│ │ + templateMethod() { // 模板方法 │ │
│ │ step1(); │ │
│ │ step2(); │ │
│ │ if (hook()) step3(); │ │
│ │ } │ │
│ │ # step1() // 抽象方法 │ │
│ │ # step2() // 抽象方法 │ │
│ │ # step3() // 具体方法 │ │
│ │ # hook(): boolean // 钩子方法 │ │
│ └───────────────────────┬────────────────────────┘ │
│ │ │
│ ┌─────────────┴─────────────┐ │
│ ▼ ▼ │
│ ┌─────────────────┐ ┌─────────────────┐ │
│ │ ConcreteClassA │ │ ConcreteClassB │ │
│ │ step1() {...} │ │ step1() {...} │ │
│ │ step2() {...} │ │ step2() {...} │ │
│ └─────────────────┘ │ hook() {true} │ │
│ └─────────────────┘ │
│ │
│ JDK中的应用: │
│ • InputStream.read() │
│ • AbstractList.get() │
│ • HttpServlet.service() │
│ │
└──────────────────────────────────────────────────────────────────┘

责任链模式(Chain of Responsibility)

使多个对象都有机会处理请求,将这些对象连成一条链。

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
// 抽象处理者
public abstract class Handler {
protected Handler nextHandler;

public void setNext(Handler handler) {
this.nextHandler = handler;
}

public abstract void handle(Request request);
}

// 请求类
public class Request {
private String type;
private double amount;

public Request(String type, double amount) {
this.type = type;
this.amount = amount;
}

// getters
public String getType() { return type; }
public double getAmount() { return amount; }
}

// 具体处理者
public class ManagerHandler extends Handler {
@Override
public void handle(Request request) {
if (request.getAmount() <= 1000) {
System.out.println("经理批准: " + request.getAmount());
} else if (nextHandler != null) {
nextHandler.handle(request);
}
}
}

public class DirectorHandler extends Handler {
@Override
public void handle(Request request) {
if (request.getAmount() <= 5000) {
System.out.println("总监批准: " + request.getAmount());
} else if (nextHandler != null) {
nextHandler.handle(request);
}
}
}

public class CEOHandler extends Handler {
@Override
public void handle(Request request) {
if (request.getAmount() <= 50000) {
System.out.println("CEO批准: " + request.getAmount());
} else {
System.out.println("金额太大,需要董事会审批");
}
}
}

// 使用
Handler manager = new ManagerHandler();
Handler director = new DirectorHandler();
Handler ceo = new CEOHandler();

manager.setNext(director);
director.setNext(ceo);

manager.handle(new Request("报销", 500)); // 经理批准
manager.handle(new Request("采购", 3000)); // 总监批准
manager.handle(new Request("投资", 20000)); // CEO批准

状态模式(State)

允许对象在内部状态改变时改变它的行为。

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
85
86
87
88
89
// 状态接口
public interface State {
void insertCoin(VendingMachine machine);
void pressButton(VendingMachine machine);
void dispense(VendingMachine machine);
}

// 具体状态
public class NoCoinState implements State {
@Override
public void insertCoin(VendingMachine machine) {
System.out.println("投币成功");
machine.setState(new HasCoinState());
}

@Override
public void pressButton(VendingMachine machine) {
System.out.println("请先投币");
}

@Override
public void dispense(VendingMachine machine) {
System.out.println("请先投币");
}
}

public class HasCoinState implements State {
@Override
public void insertCoin(VendingMachine machine) {
System.out.println("已有硬币,无需再投");
}

@Override
public void pressButton(VendingMachine machine) {
System.out.println("正在出货...");
machine.setState(new DispensingState());
}

@Override
public void dispense(VendingMachine machine) {
System.out.println("请按按钮");
}
}

public class DispensingState implements State {
@Override
public void insertCoin(VendingMachine machine) {
System.out.println("正在出货,请稍等");
}

@Override
public void pressButton(VendingMachine machine) {
System.out.println("正在出货,请稍等");
}

@Override
public void dispense(VendingMachine machine) {
System.out.println("商品已送出");
machine.setState(new NoCoinState());
}
}

// 上下文
public class VendingMachine {
private State state;

public VendingMachine() {
this.state = new NoCoinState();
}

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

public void insertCoin() {
state.insertCoin(this);
}

public void pressButton() {
state.pressButton(this);
state.dispense(this);
}
}

// 使用
VendingMachine machine = new VendingMachine();
machine.pressButton(); // 请先投币
machine.insertCoin(); // 投币成功
machine.pressButton(); // 正在出货... 商品已送出

命令模式(Command)

将请求封装成对象,使你可以用不同的请求参数化客户端。

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
// 命令接口
public interface Command {
void execute();
void undo();
}

// 接收者
public class Light {
public void on() {
System.out.println("灯打开");
}

public void off() {
System.out.println("灯关闭");
}
}

// 具体命令
public class LightOnCommand implements Command {
private Light light;

public LightOnCommand(Light light) {
this.light = light;
}

@Override
public void execute() {
light.on();
}

@Override
public void undo() {
light.off();
}
}

public class LightOffCommand implements Command {
private Light light;

public LightOffCommand(Light light) {
this.light = light;
}

@Override
public void execute() {
light.off();
}

@Override
public void undo() {
light.on();
}
}

// 调用者
public class RemoteControl {
private Command command;
private Stack<Command> history = new Stack<>();

public void setCommand(Command command) {
this.command = command;
}

public void pressButton() {
command.execute();
history.push(command);
}

public void pressUndo() {
if (!history.isEmpty()) {
history.pop().undo();
}
}
}

// 使用
Light light = new Light();
RemoteControl remote = new RemoteControl();

remote.setCommand(new LightOnCommand(light));
remote.pressButton(); // 灯打开
remote.pressUndo(); // 灯关闭

迭代器模式(Iterator)

提供一种方法顺序访问集合元素,而不暴露其内部表示。

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
// 迭代器接口
public interface Iterator<T> {
boolean hasNext();
T next();
}

// 集合接口
public interface Container<T> {
Iterator<T> createIterator();
}

// 具体集合
public class BookCollection implements Container<String> {
private String[] books;

public BookCollection(String[] books) {
this.books = books;
}

@Override
public Iterator<String> createIterator() {
return new BookIterator();
}

// 内部迭代器类
private class BookIterator implements Iterator<String> {
private int index = 0;

@Override
public boolean hasNext() {
return index < books.length;
}

@Override
public String next() {
return books[index++];
}
}
}

// 使用
BookCollection collection = new BookCollection(
new String[]{"Java编程", "设计模式", "数据结构"}
);
Iterator<String> iterator = collection.createIterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}

设计模式在Java中的应用

JDK中的设计模式

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
┌──────────────────────────────────────────────────────────────────┐
│ JDK中的设计模式应用 │
├──────────────────────────────────────────────────────────────────┤
│ │
│ 单例模式 │
│ • Runtime.getRuntime() │
│ • Desktop.getDesktop() │
│ │
│ 工厂模式 │
│ • Calendar.getInstance() │
│ • NumberFormat.getInstance() │
│ • Charset.forName() │
│ │
│ 建造者模式 │
│ • StringBuilder │
│ • Stream.Builder │
│ • Locale.Builder │
│ │
│ 适配器模式 │
│ • InputStreamReader / OutputStreamWriter │
│ • Arrays.asList() │
│ │
│ 装饰器模式 │
│ • BufferedInputStream / BufferedOutputStream │
│ • Collections.synchronizedList() │
│ • Collections.unmodifiableList() │
│ │
│ 代理模式 │
│ • java.lang.reflect.Proxy │
│ • RMI │
│ │
│ 观察者模式 │
│ • java.util.Observer(已废弃) │
│ • java.util.concurrent.Flow │
│ • PropertyChangeListener │
│ │
│ 策略模式 │
│ • Comparator │
│ • ThreadPoolExecutor的RejectedExecutionHandler │
│ │
│ 模板方法模式 │
│ • InputStream.read() │
│ • AbstractList │
│ • HttpServlet.service() │
│ │
│ 迭代器模式 │
│ • Iterator接口 │
│ • Enumeration │
│ │
└──────────────────────────────────────────────────────────────────┘

Spring中的设计模式

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
┌──────────────────────────────────────────────────────────────────┐
│ Spring中的设计模式应用 │
├──────────────────────────────────────────────────────────────────┤
│ │
│ 单例模式 │
│ • Bean默认是单例的 │
│ │
│ 工厂模式 │
│ • BeanFactory / ApplicationContext │
│ • FactoryBean │
│ │
│ 代理模式 │
│ • AOP的核心实现 │
│ • JDK动态代理 / CGLIB │
│ │
│ 模板方法模式 │
│ • JdbcTemplate │
│ • RestTemplate │
│ • TransactionTemplate │
│ │
│ 观察者模式 │
│ • ApplicationEvent / ApplicationListener │
│ • @EventListener │
│ │
│ 策略模式 │
│ • Resource接口的多种实现 │
│ • HandlerMapping │
│ │
│ 适配器模式 │
│ • HandlerAdapter │
│ • MessageListenerAdapter │
│ │
│ 装饰器模式 │
│ • BeanWrapper │
│ • HttpServletRequestWrapper │
│ │
│ 责任链模式 │
│ • Filter链 │
│ • Interceptor链 │
│ │
└──────────────────────────────────────────────────────────────────┘

设计模式选择指南

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
┌──────────────────────────────────────────────────────────────────┐
│ 设计模式选择指南 │
├──────────────────────────────────────────────────────────────────┤
│ │
│ 问题场景 推荐模式 │
│ ─────────────────────────────────────────────────────────────── │
│ 需要确保只有一个实例 单例模式 │
│ 创建对象的细节需要隐藏 工厂模式 │
│ 创建相关产品族 抽象工厂 │
│ 分步骤构建复杂对象 建造者模式 │
│ 需要复制现有对象 原型模式 │
│ │
│ 接口不兼容需要转换 适配器模式 │
│ 需要动态添加功能 装饰器模式 │
│ 需要控制对象访问 代理模式 │
│ 简化复杂子系统 外观模式 │
│ 处理树形结构 组合模式 │
│ 分离抽象与实现 桥接模式 │
│ 需要共享大量细粒度对象 享元模式 │
│ │
│ 算法需要灵活切换 策略模式 │
│ 一对多的消息通知 观察者模式 │
│ 定义算法骨架 模板方法 │
│ 对象行为随状态改变 状态模式 │
│ 请求需要多级处理 责任链模式 │
│ 封装请求为对象 命令模式 │
│ 遍历集合元素 迭代器模式 │
│ │
└──────────────────────────────────────────────────────────────────┘

总结

设计原则

原则 核心思想
单一职责(SRP) 一个类只做一件事
开闭原则(OCP) 对扩展开放,对修改关闭
里氏替换(LSP) 子类可以替换父类
接口隔离(ISP) 接口要小而专一
依赖倒置(DIP) 依赖抽象不依赖实现
迪米特法则 最少知识原则
合成复用 组合优于继承

常用设计模式

类型 模式 一句话描述
创建型 单例 确保唯一实例
创建型 工厂方法 延迟到子类创建对象
创建型 建造者 分步构建复杂对象
结构型 适配器 转换不兼容接口
结构型 装饰器 动态添加功能
结构型 代理 控制对象访问
行为型 策略 封装可替换算法
行为型 观察者 一对多消息通知
行为型 模板方法 定义算法骨架
行为型 责任链 多级请求处理

设计模式不是银弹,应该根据具体场景选择合适的模式。过度设计和不使用设计模式一样有害。最重要的是理解每个模式解决的问题,在合适的场景应用合适的模式。