一、设计模式概述

Java 中设计模式的整体概述,核心是GoF 经典 23 种设计模式在 Java 中的落地逻辑、分类、核心价值和使用原则,下面从定义与核心价值经典分类(附 Java 典型应用)Java 中使用设计模式的特点使用原则四个核心维度讲清楚,内容贴合 Java 开发实际,新手也能快速理解。

一、Java 设计模式的定义与核心价值

设计模式(Design Patterns)是软件设计中通用、可复用的解决方案,针对 Java 开发中反复出现的代码设计、架构优化、对象交互问题,提供标准化的思路,而非现成的代码。

它的核心价值体现在 Java 开发中:

  1. 提高代码复用性:避免重复造轮子,比如单例模式解决全局唯一实例的重复实现;
  2. 增强代码可维护性:符合 Java 的面向对象(OOP)思想,代码结构清晰,易修改、易扩展;
  3. 统一设计规范:团队开发中达成共识,降低沟通成本;
  4. 解耦核心逻辑:解决 Java 中对象耦合、依赖过重的问题,比如工厂模式解耦对象创建与使用。

Java 是纯面向对象语言,完美契合设计模式的封装、继承、多态核心思想,因此设计模式在 Java 开发中应用最广泛、最落地。

二、GoF 经典 23 种设计模式(Java 核心分类)

四人组(GoF)定义的 23 种经典设计模式,是 Java 设计模式的核心,按设计目的分为三大类,以下是每类核心思想 + Java 常用模式 + 典型应用场景 / API 示例,这是 Java 开发中最常接触的内容:

1. 创建型设计模式(Creational Patterns)

核心:封装对象的创建过程,将对象创建与业务逻辑解耦,让程序无需关注对象如何创建、初始化,只关注使用。

Java 常用 6 种:单例模式(Singleton)、简单工厂模式(Simple Factory)、工厂方法模式(Factory Method)、抽象工厂模式(Abstract Factory)、建造者模式(Builder)、原型模式(Prototype)。

Java 典型应用

  • JDK 中的java.util.Calendar使用工厂方法模式创建实例;
  • Spring 框架的BeanFactory核心是工厂模式,负责创建 Java Bean;
  • StringBuilder/StringBuffer建造者模式的简化实现,分步构建字符串。

2. 结构型设计模式(Structural Patterns)

核心:关注类 / 对象的组合方式,通过合理的结构组合,实现功能复用、扩展,或解决对象之间的依赖关系,让结构更灵活。

Java 常用 7 种:代理模式(Proxy)、装饰器模式(Decorator)、适配器模式(Adapter)、桥接模式(Bridge)、组合模式(Composite)、享元模式(Flyweight)、外观模式(Facade)。

Java 典型应用

  • JDK 中的java.io.BufferedReader/BufferedWriter装饰器模式,为基础流添加缓冲功能;
  • JDK 中的java.util.Arrays.asList()适配器模式,将数组适配为 List 集合;
  • Spring AOP 的核心是动态代理模式(JDK 动态代理 + CGLIB 代理),实现无侵入的功能增强;
  • JDK 中的String常量池是享元模式,复用字符串对象,减少内存占用。

3. 行为型设计模式(Behavioral Patterns)

核心:关注对象之间的通信与职责分配,定义对象之间的交互规则,让对象协作更高效,同时简化复杂的行为逻辑。

Java 常用 10 种:观察者模式(Observer)、策略模式(Strategy)、模板方法模式(Template Method)、迭代器模式(Iterator)、责任链模式(Chain of Responsibility)、命令模式(Command)、备忘录模式(Memento)、状态模式(State)、访问者模式(Visitor)、中介者模式(Mediator)。

Java 典型应用

  • JDK 中的java.util.Observer/java.util.Observable观察者模式(基础版),Spring 的ApplicationListener也是观察者模式的实现;
  • JDK 中的java.util.Comparator策略模式,自定义排序规则就是替换不同的策略;
  • JDK 中的java.util.Iterator迭代器模式,统一各种集合的遍历方式;
  • Spring MVC 的拦截器链、Tomcat 的过滤器链(Filter)是责任链模式,请求依次经过多个处理器。

三、Java 中使用设计模式的核心特点

  1. 基于 OOP 思想落地:所有设计模式都围绕 Java 的封装、继承、多态、抽象展开,比如多态实现策略模式的动态切换、抽象类 / 接口定义工厂模式的规范;
  2. 结合 JDK / 框架深度融合:Java 设计模式并非孤立使用,JDK 本身内置了大量设计模式,主流框架(Spring、MyBatis、Tomcat)更是设计模式的集大成者,学习框架的同时也是理解设计模式的过程;
  3. 支持 “灵活实现”:Java 中设计模式没有固定的代码模板,可根据场景简化,比如单例模式有饿汉式、懒汉式、双重检查锁、枚举式等多种实现,适配不同的线程安全、初始化需求;
  4. 依赖特性增强:Java 的反射、注解、动态代理(JDK/CGLIB)让设计模式的实现更优雅,比如 Spring 通过反射实现工厂模式创建 Bean,通过动态代理实现 AOP。

四、Java 中使用设计模式的核心原则(六大设计原则)

设计模式的本质是遵循面向对象设计原则,所有模式都是这些原则的具体实现,Java 开发中使用设计模式的前提是遵守这 6 大原则(简称SOLID+ 迪米特法则),避免过度设计:

  1. 单一职责原则:一个类只负责一个功能模块,比如 Java 的 Service 层只处理业务逻辑,Dao 层只处理数据访问;
  2. 开闭原则(核心):对扩展开放,对修改关闭,比如用策略模式替换硬编码的 if-else,新增策略只需实现接口,无需修改原有代码;
  3. 里氏替换原则:子类可以完全替换父类,且不影响程序运行,Java 中继承的核心规范;
  4. 依赖倒置原则:依赖抽象(接口 / 抽象类),而非具体实现,比如 Service 层依赖 Dao 接口,而非具体的 MySQLDao、OracleDao;
  5. 接口隔离原则:拆分臃肿的接口,让类只实现自己需要的接口,避免 “接口污染”;
  6. 迪米特法则(最少知道原则):一个对象只和直接关联的对象通信,降低耦合,比如 Java 中 Service 层不直接操作数据库连接,而是通过 Dao 层间接操作。

二、UML设计

1.概述

UML(统一建模语言,Unified Modeling Language)是设计模式落地的可视化表达工具,也是 Java 开发中梳理类 / 对象关系、设计模式结构的核心手段 —— 设计模式的类结构、对象交互逻辑,都能通过 UML 图清晰呈现,让团队快速理解模式设计思路,避免纯代码的逻辑晦涩。

在 Java 设计模式中,使用频率最高的是 UML 类图(描述静态的类 / 接口关系),其次是UML 时序图(描述动态的对象交互流程),二者能覆盖 90% 以上的设计模式表达需求,以下聚焦这两类核心 UML 图,结合 Java 设计模式的使用场景讲解,同时补充关键语法和模式示例,贴合 Java 开发实际。

2.图类型

UML 图类型 核心作用 设计模式使用场景 Java 设计模式示例
类图 描述系统的静态结构,定义类/接口的属性、方法,以及类之间的关系(继承、实现、关联、聚合、组合、依赖等)。 所有设计模式的基础结构设计,是表达设计模式意图和静态组成的核心图,应优先绘制 单例模式的单一实例类、工厂方法模式的 Creator 与 Product 接口/实现类、装饰器模式中 Component 与 ConcreteDecorator 的嵌套关联关系。
时序图 描述对象之间动态交互的流程,按时间顺序展示方法调用、消息传递的先后顺序,重点关注运行时行为 强调对象间协作和调用流程的设计模式,用于补充类图无法表达的动态逻辑。 观察者模式:被观察者 notify() 调用所有观察者的 update()责任链模式:请求在 Handler 链上的依次传递与处理。 命令模式Invoker 调用 Command.execute()Command 再调用 Receiver 的动作。
状态图 描述一个对象在其生命周期内所经历的各种状态,以及触发状态转换的事件、条件与动作 适用于行为随内部状态改变而改变的设计模式,能清晰展示状态驱动的转换逻辑。 状态模式:展示 Context 如何在不同 State 子类间转换,以及每个状态下的不同行为响应。 策略模式(部分场景):当策略切换可视为状态改变时。
活动图 描述系统或对象完成的一个活动(流程),侧重于操作的顺序和并行流程,类似流程图但支持并发。 适用于描述复杂算法步骤包含并行/分支流程的设计模式的内部工作机制。 模板方法模式:展示算法骨架中抽象步骤与具体步骤的执行顺序和分支。 职责链模式:可展示请求在链中传递时可能遇到的判断与分支路径。
组件图 描述系统物理结构中各组件的组织、依赖关系(如库、文件、模块),体现编译期或部署期的静态依赖 适用于展示设计模式如何应用于大型系统架构中的模块划分与解耦。 抽象工厂模式:展示不同产品族工厂(如 UIFactory)组件与具体产品(如 MacButton, WinButton)组件的依赖关系。 桥接模式:清晰分离“抽象”组件与“实现”组件,展示它们之间的松散耦合。
部署图 描述系统运行时的硬件节点结构,以及软件组件(进程、对象)在这些节点上的物理部署情况。 适用于与性能、伸缩性、分布式架构相关的模式,展示模式的物理部署视图。 单例模式:在集群环境中,讨论单例对象应部署在哪个节点(如转为“每节点单例”)。 代理模式(远程代理):展示客户端对象与远程代理对象在不同节点上的部署,以及网络通信关系。
对象图 描述在系统某一特定时刻,对象实例的快照以及它们之间的链(链接是关联的实例) 用于举例说明设计模式在运行时的某一瞬间,各个参与对象的具体状态和关系。 组合模式:展示一个具体的树形结构对象组合,如一个包含子文件夹和文件的目录实例。 享元模式:展示享元工厂中共享的具体享元对象,以及被多个客户端上下文引用的情况。

(1)类图

一个类图主要由以下三部分组成:

1. 类(Class)
表示一个具有相同属性、操作、关系和语义的对象的集合。在图中被绘制为一个三层矩形。

text

1
2
3
4
5
6
7
-------------------
| <<类名>> |
|-----------------|
| 属性/成员变量 |
|-----------------|
| 操作/方法 |
-------------------
  • 类名层(必须):类的名称,通常首字母大写。
  • 属性层(可选):格式为:[可见性] 属性名: 类型 [= 默认值]
    • 可见性符号
      • +:public(公共)
      • -:private(私有)
      • #:protected(保护)
      • ~:package/default(包内可见)
  • 操作层(可选):格式为:[可见性] 方法名(参数列表): 返回类型

2. 接口(Interface)
定义一组操作的契约,没有具体实现。通常有两种画法:

  • 构造型表示法:在类名上方加 <<interface>>
  • 圆圈表示法:用一个圆圈表示,旁边标注接口名(较少显示方法)。

3. 关系(Relationship)
描述类与类、类与接口之间的联系,是类图的灵魂。

关系类型 UML 图示 说明 代码体现/设计模式示例
继承/泛化 (Inheritance/Generalization) 父类 ←────── 子类 (空心三角箭头,实线 “是一个(is-a)” 关系。子类继承父类的特征,并可扩展。 class Child extends Parent {} 模板方法模式:抽象类定义了算法骨架。
实现 (Realization) <<interface>> 接口 ←────── 实现类 (空心三角箭头,虚线 类实现接口中定义的所有操作契约。 class Class implements Interface {} 策略模式:具体策略类实现策略接口。
关联 (Association) 类A ──────> 类B (普通箭头,实线 “知道(knows-a)” 关系,一个对象持有对另一个对象的长期引用。可以是单向或双向。 class A { private B b; } 观察者模式:被观察者持有观察者列表的引用。
聚合 (Aggregation) 整体 ◇────> 部分 (空心菱形箭头,实线 “拥有(has-a)” 关系,弱的整体-部分关系。部分可以独立于整体存在。 class Team { private List<Member> members; } 成员可以属于多个团队或没有团队。
组合 (Composition) 整体 ◆────> 部分 (实心菱形箭头,实线 “包含(contains-a)” 关系,强的整体-部分关系。部分生命周期依赖于整体。 class Car { private Engine engine; } 引擎随汽车创建而创建,随汽车销毁而销毁。
依赖 (Dependency) 依赖者 ┄┄┄┄> 被依赖者 (普通箭头,虚线 “使用(uses-a)” 关系,一种临时、短暂的关系。通常表现为方法参数、局部变量、静态方法调用等。 class A { public void method(B b) { ... } } 工厂方法模式:创建者依赖于其创建的Product对象。

三、七大原则

1. 单一职责原则 (Single Responsibility 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
29
30
// 违反 SRP 的类 - 承担了用户信息管理和用户展示两种职责
class User {
private String name;
private String email;

// 数据操作职责
public void saveToDatabase() { /*...*/ }
public void loadFromDatabase() { /*...*/ }

// 展示职责
public void displayInConsole() { /*...*/ }
public void formatForHTML() { /*...*/ }
}

// 遵循 SRP 的重构
class User {
private String name;
private String email;
// 只有属性和基本 getter/setter
}

class UserRepository { // 负责数据持久化
public void save(User user) { /*...*/ }
public User findById(String id) { /*...*/ }
}

class UserView { // 负责展示逻辑
public void display(User user) { /*...*/ }
public String formatAsHTML(User user) { /*...*/ }
}

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

定义:客户端不应该依赖它不需要的接口。

通俗理解:接口要小而专,不要大而全。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
// 违反 ISP - 臃肿的接口
interface Worker {
void work();
void eat();
void sleep();
}

class Human implements Worker {
public void work() { /*...*/ }
public void eat() { /*...*/ }
public void sleep() { /*...*/ }
}

class Robot implements Worker {
public void work() { /*...*/ }
public void eat() { /*...*/ } // 机器人不需要吃饭!
public void sleep() { /*...*/ } // 机器人不需要睡觉!
}

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

interface Eatable {
void eat();
}

interface Sleepable {
void sleep();
}

class Human implements Workable, Eatable, Sleepable {
public void work() { /*...*/ }
public void eat() { /*...*/ }
public void sleep() { /*...*/ }
}

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

// 或者使用默认方法(Java 8+)
interface Worker {
void work();
default void eat() { /* 空实现或抛异常 */ }
default void sleep() { /* 空实现或抛异常 */ }
}

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

定义

  1. 高层模块不应该依赖低层模块,两者都应该依赖抽象

  2. 抽象不应该依赖细节,细节应该依赖抽象

通俗理解:要面向接口编程,不要面向实现编程。

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
//不符合原则
class BenC{
public void run(){
System.out.prinln("奔驰车启动中...");
}
}

class Bmw{
public void run(){
System.out.prinln("宝马车启动中...");
}
}

class Driver{
void drive(Benc benc){
System.out.prinln("司机开车");
benc.run();
}

public static void main(String[] args){
Driver d = new Driver();
Bmw b = new Bmw();
d.driver(b); //此时宝马无法写入
}
}


//符合原则
public interface IdCar{ //车辆高层
void run();
}
interface IdDriver{ //司机高层
void driver(Idcar idcar);
}

class BenC implements IdCar{ //底层依赖高层
public void run(){
System.out.prinln("奔驰车启动中...");
}
}

class Bmw implements IdCar{ //底层依赖高层
public void run(){
System.out.prinln("宝马车启动中...");
}
}

class Driver implements IdDriver{
void drive(IdCar idcar){
System.out.prinln("司机开车");
idcar.run();
}

public static void main(String[] args){
Driver d = new Driver();
Bmw b = new Bmw();
BenC benc = new BenC();
d.driver(b); //此时宝马可以写入
d.driver(benc); //此时奔驰可以写入
...
}
}

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

定义:子类必须能够替换其父类,并且不影响程序的正确性。

通俗理解:继承时,子类不应该改变父类的核心行为。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
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
// 违反 LSP - 正方形不是长方形的合适子类
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; }
}

class Square extends Rectangle {
@Override
public void setWidth(int width) {
super.setWidth(width);
super.setHeight(width); // 违反父类预期行为
}

@Override
public void setHeight(int height) {
super.setHeight(height);
super.setWidth(height); // 违反父类预期行为
}
}

// 测试代码
public class Test {
public static void resize(Rectangle rectangle) {
rectangle.setWidth(5);
rectangle.setHeight(4);
assert rectangle.getArea() == 20; // 传入Square时失败!
}
}

// 遵循 LSP 的方案1:使用组合替代继承
interface Shape {
int getArea();
}

class Rectangle implements Shape {
private int width;
private int height;

public Rectangle(int width, int height) {
this.width = width;
this.height = height;
}

@Override
public int getArea() { return width * height; }
}

class Square implements Shape {
private int side;

public Square(int side) {
this.side = side;
}

@Override
public int getArea() { return side * side; }
}

// 遵循 LSP 的方案2:提取更抽象的父类
abstract class Quadrilateral {
public abstract int getArea();
}

5.开闭原则 (Open-Closed Principle, 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
// 一个简单的计算器,如果新增其他操作,则必须修改这个类!!!
class Calculator {
public int calculate(int a, int b, String operation) {
if ("add".equals(operation)) {
return a + b;
} else if ("subtract".equals(operation)) {
return a - b;
}
// 问题:要新增乘法功能,必须修改这个类
// 比如要加:else if ("multiply".equals(operation)) { ... }
throw new IllegalArgumentException("不支持的运算: " + operation);
}
}

//符合原则
// 步骤1:定义抽象(接口)
interface Operation {
int execute(int a, int b);
}

// 步骤2:实现具体运算(已有功能)
class AddOperation implements Operation {
@Override
public int execute(int a, int b) {
return a + b;
}
}

class SubtractOperation implements Operation {
@Override
public int execute(int a, int b) {
return a - b;
}
}

// 步骤3:设计可扩展的计算器
class Calculator {
public int calculate(int a, int b, Operation operation) {
// 核心:这里不关心具体的运算是什么
// 只调用抽象接口的方法
return operation.execute(a, b);
}
}

6. 迪米特法则/最少知识原则 (Law of Demeter, LoD)

定义:一个对象应该对其他对象保持最少的了解。

通俗理解:只与直接的朋友通信,不要和陌生人说话。

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
class Book {
private String title; // 改为私有

public Book(String title) {
this.title = title;
}

// 提供必要的方法
public String getTitle() {
return title;
}
}

class Bookshelf {
private Book book;

// 不直接返回Book对象
public String getBookTitle() { // 关键:只提供需要的信息
return book.getTitle();
}
}

class Person {
void readBook(Bookshelf shelf) {
// 改进:只和直接朋友Bookshelf对话
System.out.println("正在读:" + shelf.getBookTitle());
}
}

7.合成复用原则 (Composite Reuse Principle, CRP)

定义:尽量使用组合/聚合关系,而不是继承关系来达到复用的目的。

通俗理解:优先”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
38
39
// 不好的做法:过度使用继承
class Engine {
void start() { /*...*/ }
}

class Car extends Engine { // 继承实现复用
void drive() {
start(); // 使用父类方法
// 驾驶逻辑
}
}

// 好的做法:使用组合
class Car {
private Engine engine; // 组合关系

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

void drive() {
engine.start(); // 委托给引擎对象
// 驾驶逻辑
}
}

// 更灵活的做法:使用依赖注入
class Car {
private Engine engine;

public Car(Engine engine) { // 注入依赖
this.engine = engine;
}

void drive() {
engine.start();
// 驾驶逻辑
}
}

四、创建型模式

1.单例模式

(1)饿汉式

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
/**
* 饿汉式第一种单例模式
* 1.构造方法私有化
* 2.声明一个本类的成员,静态加初始化
*/
public class Singleton {
public static final Singleton INSTANCE = new Singleton();

private Singleton(){

}
}

//方式2
public class Singleton2 {
private static final Singleton2 INSTANCE = new Singleton2();

private Singleton2(){

}

public static Singleton2 getInstance(){ //提供get方法
return INSTANCE;
}
}

//方式3
public class Singleton3 {
private static Singleton3 INSTANCE = null;

static{ //使用静态代码块初始化对象
INSTANCE = new Singleton3();
}

private Singleton3(){

}

public static Singleton3 getInstance(){ //提供get方法
return INSTANCE;
}
}

(2)懒汉式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
//非多线程版,会有问题!!
public class LazySingleton {
private static LazySingleton lazySingleton;

private LazySingleton(){}

//如果有没有创建就创建,如果有就不创建
public static LazySingleton getInstance(){
if (lazySingleton == null){
lazySingleton = new LazySingleton();
System.out.println("创建成功");
}
return lazySingleton;
}
}

//多线程版,但会影响效率
public class LazySingleton {
private static LazySingleton lazySingleton;

private LazySingleton(){}

//如果有没有创建就创建,如果有就不创建
public static synchronized LazySingleton getInstance(){ //加上synchroized即可
if (lazySingleton == null){
lazySingleton = new LazySingleton();
System.out.println("创建成功");
}
return lazySingleton;
}
}

(3)双重校验锁

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

private DCLSingleton() {
System.out.println("Singleton4 被创建");
}

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

(4)静态内部类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class StaticInnerClassSingleton {
//设置私有构造方法
private StaticInnerClassSingleton(){}

//创建静态内部类
private static class SingletonHolder{
private static final StaticInnerClassSingleton SINGLETON =
new StaticInnerClassSingleton();
}

//提供获取外部类的方法
public static StaticInnerClassSingleton getInstance(){
return SingletonHolder.SINGLETON;
}
}

(5)枚举方式

1
2
3
4
5
6
7
public enum EnumSingleton {
INSTANCE; //相当于 private static final EnumSingleton INSTANCE = new EnumSingleton()

public EnumSingleton getInstance(){
return INSTANCE;
}
}

(6)序列化、反射破解单例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package BuilderPattern.singleton;

public class SafeSingleton {
private static SafeSingleton instance = new SafeSingleton();
private static int count = 0; // 防御标志

private SafeSingleton() {
// 防止反射攻击
if (count > 0) {
throw new RuntimeException("禁止通过反射创建单例!");
}
count++;
System.out.println("SafeSingleton 被创建");
}

public static SafeSingleton getInstance() {
return instance;
}
}

2.建造者模式

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
package BuilderPattern.builder;

/**
* 使用建造者模式 return this;
*/
public class user {
private String name;
private int age;
private char sex;
private String tel;

public user(){}

public static user builder(){ //builder创建对象
return new user();
}

//将属性作为步骤
public user name(String name){
this.name = name;
return this; //返回当前对象,可以链式调用
}

public user age(int age){
this.age = age;
return this;
}

public user sex(char sex){
this.sex = sex;
return this;
}

public user tel(String tel){
this.tel = tel;
return this;
}

//构造
public user build(){
val(this);
return this;
}

public void val(user user){
///操作
}
}

//调用
public static void main(String[] args) {
user u = user.builder()
.name("小陈")
.age(19)
.sex('男')
.build();
System.out.println(u.toString());

}

3.工厂模式

(1)简单工厂模式

简单工厂模式是最简单的工厂模式,也叫静态工厂模式。它的核心思想:

一个工厂类根据传入的参数创建不同的对象. 注: 因为要新增需要修改工厂类代码,违反了开闭原则

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
// 1. 形状接口
interface Shape {
void draw();
}

// 2. 具体形状
class Circle implements Shape {
@Override
public void draw() {
System.out.println("画一个圆形 ○");
}
}

class Square implements Shape {
@Override
public void draw() {
System.out.println("画一个正方形 □");
}
}

class Triangle implements Shape {
@Override
public void draw() {
System.out.println("画一个三角形 △");
}
}

// 3. 形状工厂(最简单的工厂)
class ShapeFactory {
public static Shape createShape(String shapeType) {
if ("circle".equalsIgnoreCase(shapeType)) {
return new Circle();
} else if ("square".equalsIgnoreCase(shapeType)) {
return new Square();
} else if ("triangle".equalsIgnoreCase(shapeType)) {
return new Triangle();
}
return null; // 或者抛异常
}
}

// 4. 使用
public class ShapeDemo {
public static void main(String[] args) {
// 客户端只需要知道工厂,不需要知道具体类
Shape circle = ShapeFactory.createShape("circle");
Shape square = ShapeFactory.createShape("square");
Shape triangle = ShapeFactory.createShape("triangle");

circle.draw(); // 画一个圆形 ○
square.draw(); // 画一个正方形 □
triangle.draw(); // 画一个三角形 △
}
}

(2)工厂方法模式

工厂方法模式解决了简单工厂的扩展问题:

  • 每个产品有自己的工厂
  • 工厂是一个接口,具体工厂实现它
  • 新增产品时只需新增工厂,不用修改已有代码
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
// 1. 产品接口
interface Vehicle {
void drive();
}

// 2. 具体产品
class Car implements Vehicle {
@Override
public void drive() {
System.out.println("驾驶汽车 🚗");
}
}

class Bike implements Vehicle {
@Override
public void drive() {
System.out.println("骑自行车 🚲");
}
}

class Motorcycle implements Vehicle {
@Override
public void drive() {
System.out.println("骑摩托车 🏍️");
}
}

// 3. 工厂接口(核心!)
interface VehicleFactory {
Vehicle createVehicle(); // 工厂方法
}

// 4. 具体工厂 - 每个产品一个工厂
class CarFactory implements VehicleFactory {
@Override
public Vehicle createVehicle() {
return new Car();
}
}

class BikeFactory implements VehicleFactory {
@Override
public Vehicle createVehicle() {
return new Bike();
}
}

class MotorcycleFactory implements VehicleFactory {
@Override
public Vehicle createVehicle() {
return new Motorcycle();
}
}

// 5. 客户端
public class SimpleFactoryMethod {
public static void main(String[] args) {
// 创建汽车工厂
VehicleFactory carFactory = new CarFactory();
Vehicle car = carFactory.createVehicle();
car.drive(); // 驾驶汽车 🚗

// 创建自行车工厂
VehicleFactory bikeFactory = new BikeFactory();
Vehicle bike = bikeFactory.createVehicle();
bike.drive(); // 骑自行车 🚲

// 新增电动车(扩展时不需要修改已有代码)
class ElectricCar implements Vehicle {
public void drive() {
System.out.println("驾驶电动车 🔋");
}
}

class ElectricCarFactory implements VehicleFactory {
public Vehicle createVehicle() {
return new ElectricCar();
}
}

// 使用新工厂
VehicleFactory electricFactory = new ElectricCarFactory();
Vehicle electricCar = electricFactory.createVehicle();
electricCar.drive(); // 驾驶电动车 🔋
}
}

(3)抽象工厂模式

抽象工厂模式是工厂的工厂:

  • 创建产品族(一组相关的产品)
  • 确保同一族的产品能一起工作
  • 抽象工厂创建抽象产品,具体工厂创建具体产品
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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
// 1. 抽象产品:椅子
interface Chair {
void sitOn();
}

// 2. 抽象产品:沙发
interface Sofa {
void lieOn();
}

// 3. 抽象产品:桌子
interface Table {
void putOn();
}

// 4. 具体产品 - 现代风格
class ModernChair implements Chair {
public void sitOn() {
System.out.println("坐在现代风格的椅子上");
}
}

class ModernSofa implements Sofa {
public void lieOn() {
System.out.println("躺在现代风格的沙发上");
}
}

class ModernTable implements Table {
public void putOn() {
System.out.println("在现代风格的桌子上放置物品");
}
}

// 5. 具体产品 - 古典风格
class ClassicalChair implements Chair {
public void sitOn() {
System.out.println("坐在古典风格的椅子上");
}
}

class ClassicalSofa implements Sofa {
public void lieOn() {
System.out.println("躺在古典风格的沙发上");
}
}

class ClassicalTable implements Table {
public void putOn() {
System.out.println("在古典风格的桌子上放置物品");
}
}

// 6. 抽象工厂(核心!)
interface FurnitureFactory {
Chair createChair();
Sofa createSofa();
Table createTable();
}

// 7. 具体工厂 - 现代家具工厂
class ModernFurnitureFactory implements FurnitureFactory {
public Chair createChair() {
return new ModernChair();
}

public Sofa createSofa() {
return new ModernSofa();
}

public Table createTable() {
return new ModernTable();
}
}

// 8. 具体工厂 - 古典家具工厂
class ClassicalFurnitureFactory implements FurnitureFactory {
public Chair createChair() {
return new ClassicalChair();
}

public Sofa createSofa() {
return new ClassicalSofa();
}

public Table createTable() {
return new ClassicalTable();
}
}

// 9. 客户端
public class AbstractFactoryDemo {
public static void main(String[] args) {
System.out.println("=== 现代风格客厅 ===");
FurnitureFactory modernFactory = new ModernFurnitureFactory();

Chair modernChair = modernFactory.createChair();
Sofa modernSofa = modernFactory.createSofa();
Table modernTable = modernFactory.createTable();

modernChair.sitOn(); // 坐在现代风格的椅子上
modernSofa.lieOn(); // 躺在现代风格的沙发上
modernTable.putOn(); // 在现代风格的桌子上放置物品

System.out.println("\n=== 古典风格客厅 ===");
FurnitureFactory classicalFactory = new ClassicalFurnitureFactory();

Chair classicalChair = classicalFactory.createChair();
Sofa classicalSofa = classicalFactory.createSofa();
Table classicalTable = classicalFactory.createTable();

classicalChair.sitOn(); // 坐在古典风格的椅子上
classicalSofa.lieOn(); // 躺在古典风格的沙发上
classicalTable.putOn(); // 在古典风格的桌子上放置物品
}
}

4.原型模式

原型模式是一种创建型设计模式,用于:

  • 通过复制现有对象来创建新对象
  • 避免重复的初始化过程
  • 提高创建复杂对象的性能
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
// 1. 实现 Cloneable 接口
class Sheep implements Cloneable {
String name;

public Sheep(String name) {
this.name = name;
System.out.println("创建羊: " + name);
}

// 2. 重写 clone 方法
@Override
public Sheep clone() throws CloneNotSupportedException {
return (Sheep) super.clone(); // 3. 调用父类的clone
}
}

public class SimplePrototype {
public static void main(String[] args) throws Exception {
// 第一只羊(原型)
Sheep originalSheep = new Sheep("多莉");

// 克隆羊(原型模式的核心)
Sheep clonedSheep = originalSheep.clone();
clonedSheep.name = "克隆多莉";

System.out.println("原羊: " + originalSheep.name);
System.out.println("克隆羊: " + clonedSheep.name);
System.out.println("是同一只羊吗? " + (originalSheep == clonedSheep));
}
}

五、结构型模式

1.适配器模式

适配器模式 转换接口,让不兼容的接口能一起工作 “转接头”

使用场景:

  1. 接口不匹配:想用的类接口不符合当前需求
  2. 无法修改源码:第三方库/老代码不能改
  3. 需要统一接口:多个类似功能但接口不同
  4. 系统要支持多种实现:如多种数据库、多种支付
  5. 测试需要Mock:隔离外部依赖方便测试
  6. 渐进式重构:先适配,再逐步替换
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
// 旧系统:用System.out打印日志(代码很老)
class OldLogger {
void logMessage(String message) {
System.out.println("[OLD LOG] " + message);
}
}

// 新系统:新的日志接口
interface NewLogger {
void info(String message);
void error(String message);
void debug(String message);
}

// 实现新日志系统
class NewLoggerImpl implements NewLogger {
public void info(String message) {
System.out.println("[INFO] " + message);
}

public void error(String message) {
System.out.println("[ERROR] " + message);
}

public void debug(String message) {
System.out.println("[DEBUG] " + message);
}
}

// 适配器:让旧代码能用新系统
class LoggerAdapter implements NewLogger {
private OldLogger oldLogger; // 里面还是老的

public LoggerAdapter(OldLogger oldLogger) {
this.oldLogger = oldLogger;
}

// 把新接口的方法转换成旧方法
public void info(String message) {
oldLogger.logMessage("INFO: " + message);
}

public void error(String message) {
oldLogger.logMessage("ERROR: " + message);
}

public void debug(String message) {
oldLogger.logMessage("DEBUG: " + message);
}
}

// 使用
public class Test {
public static void main(String[] args) {
// 老项目中的代码
OldLogger old = new OldLogger();
old.logMessage("系统启动了");

System.out.println("\n--- 升级日志系统 ---\n");

// 用适配器包装老系统
NewLogger logger = new LoggerAdapter(old);

// 现在可以用新接口了
logger.info("用户登录成功");
logger.error("密码错误");
logger.debug("调试信息");

System.out.println("\n--- 新项目直接用新系统 ---\n");

// 新项目
NewLogger newLogger = new NewLoggerImpl();
newLogger.info("新订单创建");
}
}

2.桥接模式

桥接模式就是把”做什么”和”怎么做”分开,让它们能独立变化。

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
// 实现部分:消息发送方式(怎么发)
interface MessageSender {
void send(String message);
}

class EmailSender implements MessageSender {
public void send(String message) {
System.out.println("📧 邮件发送: " + message);
}
}

class SmsSender implements MessageSender {
public void send(String message) {
System.out.println("📱 短信发送: " + message);
}
}


// 抽象部分:消息类型(发什么)
abstract class Message {
protected MessageSender sender; // 桥接的关键!

public Message(MessageSender sender) {
this.sender = sender;
}

abstract void send(String content);
}

// 具体消息类型
class TextMessage extends Message {
public TextMessage(MessageSender sender) {
super(sender);
}

void send(String content) {
System.out.print("文本消息 → ");
sender.send(content);
}
}


class SystemMessage extends Message {
public SystemMessage(MessageSender sender) {
super(sender);
}

void send(String content) {
System.out.print("【系统】 → ");
sender.send("🔧 " + content);
}
}

// 使用
public class MessageDemo {
public static void main(String[] args) {
// 用邮件发送文本消息
Message msg1 = new TextMessage(new EmailSender());
msg1.send("会议通知");

}
}

3.组合模式

组合模式让单个对象和对象组合(树形结构)有相同的操作接口。

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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
import java.util.ArrayList;
import java.util.List;

// 商品组件接口
interface ProductComponent {
String getName();
double getPrice();
void showDetails(String indent);
}

// 单个商品(叶子节点)
class SingleProduct implements ProductComponent {
private String name;
private double price;

public SingleProduct(String name, double price) {
this.name = name;
this.price = price;
}

public String getName() {
return name;
}

public double getPrice() {
return price;
}

public void showDetails(String indent) {
System.out.println(indent + "🛍️ " + name + " ¥" + price);
}
}

// 商品套餐(组合节点)
class ProductPackage implements ProductComponent {
private String name;
private List<ProductComponent> items = new ArrayList<>();

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

public void add(ProductComponent item) {
items.add(item);
}

public void remove(ProductComponent item) {
items.remove(item);
}

public String getName() {
return name;
}

public double getPrice() {
double total = 0;
for (ProductComponent item : items) {
total += item.getPrice();
}
return total * 0.9; // 套餐打9折
}

public void showDetails(String indent) {
System.out.println(indent + "📦 " + name + " 套餐 (原价总和: ¥" + getOriginalPrice() +
", 套餐价: ¥" + getPrice() + ")");
for (ProductComponent item : items) {
item.showDetails(indent + " ");
}
}

private double getOriginalPrice() {
double total = 0;
for (ProductComponent item : items) {
total += item.getPrice();
}
return total;
}
}

// 使用
public class ShoppingCartDemo {
public static void main(String[] args) {
System.out.println("=== 购物车商品系统 ===\n");

// 创建单个商品
ProductComponent hamburger = new SingleProduct("汉堡", 20);
ProductComponent fries = new SingleProduct("薯条", 10);
ProductComponent cola = new SingleProduct("可乐", 8);
ProductComponent iceCream = new SingleProduct("冰淇淋", 15);

// 创建套餐
ProductPackage combo1 = new ProductPackage("超值套餐");
combo1.add(hamburger);
combo1.add(fries);
combo1.add(cola);

ProductPackage combo2 = new ProductPackage("儿童套餐");
combo2.add(hamburger);
combo2.add(iceCream);

// 创建更大的套餐(套餐里包含套餐)
ProductPackage familyPackage = new ProductPackage("家庭套餐");
familyPackage.add(combo1);
familyPackage.add(combo2);
familyPackage.add(new SingleProduct("鸡翅", 25));
}
}

安全组合方法: 叶子节点和组合节点的方法分开

1
2
3
4
5
6
7
8
9
10
11
12
13
// 只有组合需要的方法在接口中
interface Component {
void operation();
}

// 组合节点有额外方法
interface Composite extends Component {
void add(Component c);
void remove(Component c);
}

// 优点:类型安全
// 缺点:客户端需要区分Leaf和Composite

4.装饰器模式

装饰器模式就像给手机贴膜、加手机壳、挂吊坠,不断添加新功能,但不改变手机本身。

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
90
91
// 1. 组件接口:文本
interface Text {
String getContent();
}

// 2. 具体组件:普通文本
class PlainText implements Text {
private String content;

public PlainText(String content) {
this.content = content;
}

public String getContent() {
return content;
}
}

// 3. 装饰器抽象类
abstract class TextDecorator implements Text {
protected Text text; // 持有被装饰的对象

public TextDecorator(Text text) {
this.text = text;
}

public String getContent() {
return text.getContent(); // 默认不改变
}
}

// 4. 具体装饰器:加粗
class BoldDecorator extends TextDecorator {
public BoldDecorator(Text text) {
super(text);
}

public String getContent() {
return "<b>" + text.getContent() + "</b>";
}
}

// 5. 具体装饰器:斜体
class ItalicDecorator extends TextDecorator {
public ItalicDecorator(Text text) {
super(text);
}

public String getContent() {
return "<i>" + text.getContent() + "</i>";
}
}

// 6. 具体装饰器:下划线
class UnderlineDecorator extends TextDecorator {
public UnderlineDecorator(Text text) {
super(text);
}

public String getContent() {
return "<u>" + text.getContent() + "</u>";
}
}

// 使用
public class TextDecoratorDemo {
public static void main(String[] args) {
// 基础文本
Text text = new PlainText("Hello World");
System.out.println("原文本: " + text.getContent());

// 加粗
Text boldText = new BoldDecorator(text);
System.out.println("加粗: " + boldText.getContent());

// 加粗 + 斜体
Text boldItalicText = new ItalicDecorator(boldText);
System.out.println("加粗斜体: " + boldItalicText.getContent());

// 加粗 + 斜体 + 下划线
Text decoratedText = new UnderlineDecorator(boldItalicText);
System.out.println("全部装饰: " + decoratedText.getContent());

// 也可以直接链式调用
Text fancyText = new UnderlineDecorator(
new ItalicDecorator(
new BoldDecorator(
new PlainText("装饰器模式"))));
System.out.println("链式装饰: " + fancyText.getContent());
}
}

5.门面模式(外观模式)

核心是为复杂子系统提供一个统一的 “门面” 接口,屏蔽内部复杂逻辑,让客户端只需调用这个简单接口就能完成操作,无需关心子系统的内部细节。

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
// 电脑的各个复杂组件
class CPU {
void start() {
System.out.println("🚀 CPU启动");
}
}

class Memory {
void load() {
System.out.println("💾 内存加载");
}
}

class HardDrive {
void read() {
System.out.println("💿 硬盘读取");
}
}

class GraphicsCard {
void init() {
System.out.println("🎮 显卡初始化");
}
}

class SoundCard {
void config() {
System.out.println("🔊 声卡配置");
}
}

// 电脑(门面):隐藏所有复杂性
class Computer {
private CPU cpu = new CPU();
private Memory memory = new Memory();
private HardDrive hardDrive = new HardDrive();
private GraphicsCard graphicsCard = new GraphicsCard();
private SoundCard soundCard = new SoundCard();

// 一键开机
public void powerOn() {
System.out.println("🖥️ 开始启动电脑...");
cpu.start();
memory.load();
hardDrive.read();
graphicsCard.init();
soundCard.config();
System.out.println("✅ 电脑启动完成,欢迎使用!");
}

// 一键关机
public void powerOff() {
System.out.println("🖥️ 关闭电脑...");
System.out.println("✅ 电脑已关闭");
}

// 一键重启
public void restart() {
System.out.println("🔄 重启电脑...");
powerOff();
powerOn();
}
}

// 用户使用
public class ComputerDemo {
public static void main(String[] args) {
Computer computer = new Computer();

// 用户只需要按一下按钮
System.out.println("=== 用户开机 ===");
computer.powerOn();

System.out.println("\n=== 用户重启 ===");
computer.restart();
}
}

6.享元模式

核心是复用内存中已存在的相同对象,减少创建大量相似对象带来的内存消耗,简单说就是 “共享元素”—— 把对象中不变的部分(享元)抽离出来复用,可变的部分(外部状态)由客户端传入,从而大幅减少对象数量。

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
import java.util.HashMap;
import java.util.Map;

// 1. 享元对象:棋子
class ChessPiece {
private String type; // 内部状态:类型(共享的)
private String color; // 内部状态:颜色(共享的)

public ChessPiece(String type, String color) {
this.type = type;
this.color = color;
System.out.println("♟️ 创建棋子: " + color + "色" + type);
}

public void place(int x, int y) { // 外部状态:位置(不共享)
System.out.println("在(" + x + "," + y + ")放置" + color + "色" + type);
}
}

// 2. 享元工厂:管理共享的棋子
class ChessPieceFactory {
private static Map<String, ChessPiece> piecePool = new HashMap<>();

public static ChessPiece getPiece(String type, String color) {
String key = color + "_" + type; // 组合键

ChessPiece piece = piecePool.get(key);

if (piece == null) {
piece = new ChessPiece(type, color); // 第一次创建
piecePool.put(key, piece);
System.out.println("🆕 新增到池中: " + key);
} else {
System.out.println("♻️ 从池中复用: " + key);
}

return piece;
}

public static int getPoolSize() {
return piecePool.size();
}
}

// 使用
public class ChessDemo {
public static void main(String[] args) {
System.out.println("=== 开始下围棋 ===\n");

// 下黑棋
System.out.println("黑方下棋:");
ChessPiece blackPiece1 = ChessPieceFactory.getPiece("棋子", "黑");
blackPiece1.place(1, 1);

ChessPiece blackPiece2 = ChessPieceFactory.getPiece("棋子", "黑"); // 复用!
blackPiece2.place(1, 2);

ChessPiece blackPiece3 = ChessPieceFactory.getPiece("棋子", "黑"); // 再复用!
blackPiece3.place(1, 3);

// 下白棋
System.out.println("\n白方下棋:");
ChessPiece whitePiece1 = ChessPieceFactory.getPiece("棋子", "白");
whitePiece1.place(2, 1);

ChessPiece whitePiece2 = ChessPieceFactory.getPiece("棋子", "白"); // 复用!
whitePiece2.place(2, 2);

System.out.println("\n=== 统计 ===");
System.out.println("棋盘上有 5 个棋子");
System.out.println("但实际只创建了 " + ChessPieceFactory.getPoolSize() + " 个棋子对象");
System.out.println("节省了 " + (5 - ChessPieceFactory.getPoolSize()) + " 个对象");
}
}

7.代理模式

1.静态代理

静态代理就像你雇了一个专门的秘书:每项工作都要单独雇一个秘书,秘书和你签了固定合同。

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
//接口    代理类和被代理类都必须实现该方法!!!!
public interface Travel {
void buyTrainTicket();
}

//被代理类
public class TravelPerson implements Travel{
@Override
public void buyTrainTicket() {
System.out.println("买票 --9:00");
}
}


//代理类
public class TravelAgency implements Travel{
private TravelPerson travelPerson; //被代理类

public TravelAgency(TravelPerson travelPerson){
this.travelPerson = travelPerson;
}


@Override
public void buyTrainTicket() { //进行代理
before();
this.travelPerson.buyTrainTicket();
after();
}

public void before(){
System.out.println("付钱...");
}

public void after(){
System.out.println("购票成功...");
}
}

2.动态代理

动态代理是在程序运行时动态创建代理类和对象的技术,不需要预先编写代理类的源代码。

六、行为型模式

1.模板模式

定义算法骨架,将可变步骤延迟到子类,固定流程、差异化实现

模板模式就像泡茶/冲咖啡:步骤一样(烧水、加料、冲泡),但每个步骤的具体做法不同。

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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
// 1. 抽象模板类:定义制作饮料的步骤
abstract class BeverageMaker {

// 模板方法:定义算法骨架(final防止子类修改流程)
public final void makeBeverage() {
System.out.println("=== 开始制作饮料 ===");

boilWater(); // 1. 烧水
brew(); // 2. 冲泡/酿造(具体实现不同)
pourInCup(); // 3. 倒入杯子
addCondiments(); // 4. 加调料(具体实现不同)

System.out.println("=== 饮料制作完成 ===\n");
}

// 具体步骤1:烧水(所有饮料都需要,所以放在父类)
private void boilWater() {
System.out.println("1. 烧开水 (100°C)");
}

// 具体步骤2:冲泡(抽象方法,子类必须实现)
protected abstract void brew();

// 具体步骤3:倒入杯子(所有饮料都一样)
private void pourInCup() {
System.out.println("3. 倒入杯子");
}

// 具体步骤4:加调料(抽象方法,子类必须实现)
protected abstract void addCondiments();

// 钩子方法:可选步骤(子类可以覆盖,也可以不覆盖)
protected boolean customerWantsCondiments() {
return true; // 默认加调料
}
}


// 2. 具体子类:泡茶
class TeaMaker extends BeverageMaker {
protected void brew() {
System.out.println("2. 冲泡茶叶 (浸泡5分钟)");
}

protected void addCondiments() {
System.out.println("4. 加柠檬和蜂蜜");
}

// 覆盖钩子方法:有些顾客不要调料
protected boolean customerWantsCondiments() {
System.out.print(" 问:要加柠檬和蜂蜜吗?(y/n): ");
// 模拟用户输入
String answer = "y"; // 实际中这里读用户输入
return answer.equalsIgnoreCase("y");
}
}


// 3. 具体子类:冲咖啡
class CoffeeMaker extends BeverageMaker {
protected void brew() {
System.out.println("2. 冲泡咖啡粉 (用滤纸过滤)");
}

protected void addCondiments() {
System.out.println("4. 加糖和牛奶");
}
}


// 4. 具体子类:冲速溶奶茶
class MilkTeaMaker extends BeverageMaker {
protected void brew() {
System.out.println("2. 搅拌速溶奶茶粉");
}

protected void addCondiments() {
System.out.println("4. 加珍珠和冰块");
}

// 覆盖模板方法,改变流程(虽然不推荐,但确实可以)
public void makeBeverage() {
System.out.println("=== 制作奶茶(特殊流程)===");
boilWater();
brew();
pourInCup();
// 奶茶先加冰块再加调料
addIce();
addCondiments();
System.out.println("=== 奶茶制作完成 ===\n");
}

private void addIce() {
System.out.println("4. 先加冰块");
}
}

// 使用
public class TemplatePatternDemo {
public static void main(String[] args) {
System.out.println("🎬 场景:饮品店制作各种饮料\n");

// 1. 泡茶
System.out.println("1. 顾客点了一杯茶:");
BeverageMaker teaMaker = new TeaMaker();
teaMaker.makeBeverage();

// 2. 冲咖啡
System.out.println("2. 顾客点了一杯咖啡:");
BeverageMaker coffeeMaker = new CoffeeMaker();
coffeeMaker.makeBeverage();

// 3. 冲奶茶
System.out.println("3. 顾客点了一杯奶茶:");
BeverageMaker milkTeaMaker = new MilkTeaMaker();
milkTeaMaker.makeBeverage();
}
}

2.访问者模式

为对象结构中的元素定义新操作,不修改元素类即可扩展行为

访问者模式就像医院体检:不同科室的医生(访问者)检查你(被访问元素)的不同部位,你不需要知道医生怎么检查,只需要接受检查。

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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
import java.util.*;

// 1. 访问者接口:收银员
interface Cashier {
void visit(Apple apple); // 处理苹果
void visit(Milk milk); // 处理牛奶
void visit(Bread bread); // 处理面包
}

// 2. 商品接口(要被访问的元素)
interface Product {
void accept(Cashier cashier); // 接受收银员结账
}

// 3. 具体商品:苹果
class Apple implements Product {
private double weight; // 重量(kg)

public Apple(double weight) {
this.weight = weight;
}

public double getWeight() {
return weight;
}

public void accept(Cashier cashier) {
cashier.visit(this); // 请收银员处理苹果
}
}

// 4. 具体商品:牛奶
class Milk implements Product {
private int quantity; // 数量(盒)

public Milk(int quantity) {
this.quantity = quantity;
}

public int getQuantity() {
return quantity;
}

public void accept(Cashier cashier) {
cashier.visit(this); // 请收银员处理牛奶
}
}

// 5. 具体商品:面包
class Bread implements Product {
private String type; // 类型

public Bread(String type) {
this.type = type;
}

public String getType() {
return type;
}

public void accept(Cashier cashier) {
cashier.visit(this); // 请收银员处理面包
}
}

// 6. 具体访问者:计算总价
class PriceCalculator implements Cashier {
private double totalPrice = 0;

public void visit(Apple apple) {
double price = apple.getWeight() * 8; // 苹果8元/kg
System.out.println("🍎 苹果: " + apple.getWeight() + "kg × 8元 = " + price + "元");
totalPrice += price;
}

public void visit(Milk milk) {
double price = milk.getQuantity() * 5; // 牛奶5元/盒
System.out.println("🥛 牛奶: " + milk.getQuantity() + "盒 × 5元 = " + price + "元");
totalPrice += price;
}

public void visit(Bread bread) {
double price = 10; // 面包10元/个
System.out.println("🍞 " + bread.getType() + "面包: 10元");
totalPrice += price;
}

public double getTotalPrice() {
return totalPrice;
}
}

// 7. 具体访问者:检查保质期
class ExpiryChecker implements Cashier {
public void visit(Apple apple) {
System.out.println("🍎 检查苹果: 按一下看是否新鲜");
}

public void visit(Milk milk) {
System.out.println("🥛 检查牛奶: 看生产日期和保质期");
}

public void visit(Bread bread) {
System.out.println("🍞 检查" + bread.getType() + "面包: 看是否发霉");
}
}

// 8. 购物车
class ShoppingCart {
private List<Product> products = new ArrayList<>();

public void addProduct(Product product) {
products.add(product);
}

// 统一处理购物车里的所有商品
public void process(Cashier cashier) {
System.out.println("\n=== 开始处理 ===");
for (Product product : products) {
product.accept(cashier); // 每个商品接受收银员处理
}
}
}

// 使用
public class SimpleVisitorDemo {
public static void main(String[] args) {
// 1. 创建购物车和商品
ShoppingCart cart = new ShoppingCart();
cart.addProduct(new Apple(2.5)); // 2.5kg苹果
cart.addProduct(new Milk(3)); // 3盒牛奶
cart.addProduct(new Bread("全麦")); // 全麦面包
cart.addProduct(new Apple(1.0)); // 1kg苹果

System.out.println("🛒 购物车里有4件商品\n");

// 2. 计算总价
PriceCalculator priceCalculator = new PriceCalculator();
cart.process(priceCalculator);
System.out.println("💰 总价: " + priceCalculator.getTotalPrice() + "元");

System.out.println("\n---\n");

// 3. 检查保质期
ExpiryChecker expiryChecker = new ExpiryChecker();
cart.process(expiryChecker);
}
}

3.策略模式

封装不同算法,客户端可动态切换,解耦算法定义与使用

策略模式就像支付方式:买东西时,你可以选择微信、支付宝、银行卡,但收银员(系统)的处理流程是一样的。

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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
import java.util.Arrays;

// 1. 策略接口:排序算法
interface SortStrategy {
void sort(int[] array);
}

// 2. 具体策略:冒泡排序
class BubbleSort implements SortStrategy {
public void sort(int[] array) {
System.out.println("使用冒泡排序...");
for (int i = 0; i < array.length - 1; i++) {
for (int j = 0; j < array.length - 1 - i; j++) {
if (array[j] > array[j + 1]) {
int temp = array[j];
array[j] = array[j + 1];
array[j + 1] = temp;
}
}
}
}
}

// 3. 具体策略:快速排序
class QuickSort implements SortStrategy {
public void sort(int[] array) {
System.out.println("使用快速排序...");
quickSort(array, 0, array.length - 1);
}

private void quickSort(int[] array, int low, int high) {
if (low < high) {
int pivot = partition(array, low, high);
quickSort(array, low, pivot - 1);
quickSort(array, pivot + 1, high);
}
}

private int partition(int[] array, int low, int high) {
int pivot = array[high];
int i = low - 1;

for (int j = low; j < high; j++) {
if (array[j] <= pivot) {
i++;
int temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}

int temp = array[i + 1];
array[i + 1] = array[high];
array[high] = temp;
return i + 1;
}
}

// 4. 具体策略:选择排序
class SelectionSort implements SortStrategy {
public void sort(int[] array) {
System.out.println("使用选择排序...");
for (int i = 0; i < array.length - 1; i++) {
int minIndex = i;
for (int j = i + 1; j < array.length; j++) {
if (array[j] < array[minIndex]) {
minIndex = j;
}
}
int temp = array[minIndex];
array[minIndex] = array[i];
array[i] = temp;
}
}
}

// 5. 上下文类:使用策略
class SortContext {
private SortStrategy strategy;

// 设置策略
public void setStrategy(SortStrategy strategy) {
this.strategy = strategy;
}

// 执行排序
public void sortArray(int[] array) {
if (strategy == null) {
System.out.println("请先选择排序策略!");
return;
}

System.out.println("排序前: " + Arrays.toString(array));
strategy.sort(array);
System.out.println("排序后: " + Arrays.toString(array));
System.out.println();
}
}

// 使用
public class StrategyPatternDemo {
public static void main(String[] args) {
int[] numbers = {64, 34, 25, 12, 22, 11, 90};

SortContext context = new SortContext();

System.out.println("=== 排序算法策略模式演示 ===\n");

// 1. 使用冒泡排序
System.out.println("1. 冒泡排序:");
context.setStrategy(new BubbleSort());
context.sortArray(Arrays.copyOf(numbers, numbers.length));

// 2. 使用快速排序
System.out.println("2. 快速排序:");
context.setStrategy(new QuickSort());
context.sortArray(Arrays.copyOf(numbers, numbers.length));

// 3. 使用选择排序
System.out.println("3. 选择排序:");
context.setStrategy(new SelectionSort());
context.sortArray(Arrays.copyOf(numbers, numbers.length));

// 4. 运行时切换策略
System.out.println("4. 运行时动态切换策略:");
int[] data1 = {5, 2, 8, 1, 9};
int[] data2 = {10, 3, 7, 4, 6};

context.setStrategy(new BubbleSort());
context.sortArray(data1);

context.setStrategy(new QuickSort());
context.sortArray(data2);
}
}

4.状态模式

封装对象的不同状态,让状态变化时自动切换行为,替代大量 if-else

状态模式就像电梯:有开门、关门、运行、停止等状态,每个状态下按钮的行为不同。

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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
// 订单状态接口
interface OrderState {
void pay(OrderContext order); // 支付
void cancel(OrderContext order); // 取消
void ship(OrderContext order); // 发货
void receive(OrderContext order); // 收货
}

// 订单上下文
class OrderContext {
private OrderState state;
private String orderId;

public OrderContext(String orderId) {
this.orderId = orderId;
// 初始状态为待支付
this.state = new UnpaidState();
System.out.println("🛒 订单 " + orderId + " 创建成功,状态:待支付");
}

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

public void pay() {
System.out.print("💳 订单 " + orderId + " 尝试支付 → ");
state.pay(this);
}

public void cancel() {
System.out.print("🗑️ 订单 " + orderId + " 尝试取消 → ");
state.cancel(this);
}

public void ship() {
System.out.print("🚚 订单 " + orderId + " 尝试发货 → ");
state.ship(this);
}

public void receive() {
System.out.print("📦 订单 " + orderId + " 尝试收货 → ");
state.receive(this);
}

public String getCurrentStatus() {
return state.getClass().getSimpleName();
}
}

// 待支付状态
class UnpaidState implements OrderState {
@Override
public void pay(OrderContext order) {
System.out.println("✅ 支付成功,订单状态:待发货");
order.setState(new PaidState());
}

@Override
public void cancel(OrderContext order) {
System.out.println("❌ 订单已取消");
order.setState(new CancelledState());
}

@Override
public void ship(OrderContext order) {
System.out.println("⛔ 请先支付订单才能发货");
}

@Override
public void receive(OrderContext order) {
System.out.println("⛔ 订单尚未发货,无法收货");
}
}

// 已发货状态
class ShippedState implements OrderState {
@Override
public void pay(OrderContext order) {
System.out.println("⛔ 订单已支付,无需重复支付");
}

@Override
public void cancel(OrderContext order) {
System.out.println("⛔ 商品已发货,无法取消订单");
}

@Override
public void ship(OrderContext order) {
System.out.println("⛔ 商品已在运输中,无需重复发货");
}

@Override
public void receive(OrderContext order) {
System.out.println("✅ 确认收货,订单完成!");
order.setState(new CompletedState());
}
}

// 已支付状态
class PaidState implements OrderState {
@Override
public void pay(OrderContext order) {
System.out.println("⛔ 订单已支付,无需重复支付");
}

@Override
public void cancel(OrderContext order) {
System.out.println("✅ 取消成功,退款处理中...");
order.setState(new CancelledState());
}

@Override
public void ship(OrderContext order) {
System.out.println("✅ 商品已发货,订单状态:待收货");
order.setState(new ShippedState());
}

@Override
public void receive(OrderContext order) {
System.out.println("⛔ 商品尚未发货,无法收货");
}
}

// 已取消状态
class CancelledState implements OrderState {
@Override
public void pay(OrderContext order) {
System.out.println("⛔ 订单已取消,无法支付");
}

@Override
public void cancel(OrderContext order) {
System.out.println("⛔ 订单已取消,无需重复取消");
}

@Override
public void ship(OrderContext order) {
System.out.println("⛔ 订单已取消,无法发货");
}

@Override
public void receive(OrderContext order) {
System.out.println("⛔ 订单已取消,无法收货");
}
}

// 已完成状态
class CompletedState implements OrderState {
@Override
public void pay(OrderContext order) {
System.out.println("⛔ 订单已完成,无需支付");
}

@Override
public void cancel(OrderContext order) {
System.out.println("⛔ 订单已完成,无法取消");
}

@Override
public void ship(OrderContext order) {
System.out.println("⛔ 订单已完成,无需发货");
}

@Override
public void receive(OrderContext order) {
System.out.println("⛔ 订单已完成,无需重复收货");
}
}

//测试
public class Test {
public static void main(String[] args) {
System.out.println("=== 正常流程 ===");
OrderContext orderContext = new OrderContext("ORDER1");
orderContext.pay(); //首次 new UnpaidState 支付成功
orderContext.ship(); // 成功 new PaidState 发货成功
orderContext.receive(); // 成功 new ShippedState 收货成功
orderContext.cancel(); // 成功 new Completed 已完成订单
//一层调用另一层
}
}

5.观察者模式

一对多依赖,一个对象状态变化时通知所有依赖对象(发布 - 订阅)

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
/**
* 消息发布者 --被观察者
*/
public interface Publisher {
void addStudent(Student s);
void notifyObservers(String message);
}

/**
* 具体被观察者
*/
public class PublisherImpl implements Publisher{
//装载观察者
ArrayList<Student> stu = new ArrayList<>();


@Override
public void addStudent(Student s) {
stu.add(s);
}

@Override
public void notifyObservers(String message) {
System.out.println("广播通知:" + message);
for(Student student : stu){
student.receiveNotice(message); //一旦发出消息,接收给观察者
}
}
}

public class Student {
private String name;

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

public void receiveNotice(String notice){ //观察者收到通知,由被观察者调用
System.out.println(name + "收到通知:" + notice);
}
}

6.备忘录模式

保存对象的内部状态,在不破坏封装的前提下恢复状态

“时光机”模式:把对象的状态保存起来,以后可以回到这个状态。

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
// 备忘录:保存编辑器状态
class EditorState {
private final String content;

public EditorState(String content) {
this.content = content;
}

public String getContent() {
return content;
}
}

// 编辑器
class Editor {
private String content = "";

public void type(String text) {
content += text;
}

// 保存当前状态
public EditorState save() {
return new EditorState(content);
}

// 恢复状态
public void restore(EditorState state) {
content = state.getContent();
}

public void print() {
System.out.println("当前内容: " + content);
}
}

// 历史记录管理器
class History {
private final java.util.List<EditorState> states = new java.util.ArrayList<>();

public void push(EditorState state) {
states.add(state);
}

public EditorState pop() {
if (!states.isEmpty()) {
return states.remove(states.size() - 1);
}
return null;
}
}

// 使用
public class SimpleMemento {
public static void main(String[] args) {
Editor editor = new Editor();
History history = new History();

editor.type("Hello ");
history.push(editor.save()); // 保存状态1

editor.type("World");
history.push(editor.save()); // 保存状态2

editor.type("!!!");
editor.print(); // 输出: Hello World!!!

// 撤销一次
editor.restore(history.pop());
editor.print(); // 输出: Hello World

// 再撤销一次
editor.restore(history.pop());
editor.print(); // 输出: Hello
}
}

7.中介者模式

封装多个对象的交互,让对象通过中介者通信,降低对象间耦合

“微信群聊”模式:所有对象通过一个中介者通信,而不是直接相互联系。

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
// 控制塔(中介者)
class ControlTower {
public void requestLanding(String planeName) {
System.out.println("控制塔: " + planeName + " 请求降落");
}

public void approveLanding(String planeName) {
System.out.println("控制塔: " + planeName + " 可以降落");
}

public void notifyAll(String message, String sender) {
System.out.println("控制塔广播 [" + sender + "]: " + message);
}
}

// 飞机
class Airplane {
private String name;
private ControlTower tower;

public Airplane(String name, ControlTower tower) {
this.name = name;
this.tower = tower;
}

public void requestLanding() {
System.out.println(name + ": 请求降落");
tower.requestLanding(name);
}

public void receiveLandingApproval() {
tower.approveLanding(name);
System.out.println(name + ": 收到降落许可");
}

public void sendMessage(String message) {
tower.notifyAll(message, name);
}
}

// 使用
public class AirportDemo {
public static void main(String[] args) {
ControlTower tower = new ControlTower();

Airplane plane1 = new Airplane("航班001", tower);
Airplane plane2 = new Airplane("航班002", tower);
Airplane plane3 = new Airplane("航班003", tower);

System.out.println("=== 机场通信 ===");
plane1.requestLanding();
plane1.receiveLandingApproval();

System.out.println();
plane2.sendMessage("天气状况良好");
plane3.sendMessage("收到,准备降落");
}
}

8.迭代器模式

提供统一方式遍历集合,隐藏集合内部结构

“遥控器”模式:提供一种方法顺序访问一个集合对象的元素,而不需要知道它的内部结构。

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

// 集合接口
interface Container {
Iterator getIterator();
}

// 具体集合
class NameRepository implements Container {
private String[] names = {"张三", "李四", "王五", "赵六"};

@Override
public Iterator getIterator() {
return new NameIterator();
}

// 内部迭代器类
private class NameIterator implements Iterator {
private int index = 0;

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

@Override
public Object next() {
if (hasNext()) {
return names[index++];
}
return null;
}
}
}

// 使用
public class SimpleIterator {
public static void main(String[] args) {
NameRepository repository = new NameRepository();
Iterator iterator = repository.getIterator();

while (iterator.hasNext()) {
System.out.println("姓名: " + iterator.next());
}
}
}

9.解释器模式

定义语言的文法规则,解释执行特定语法的表达式(如正则、SQL 解析)

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
90
91
92
import java.util.*;

// 表达式接口
interface MathExpression {
int interpret();
}

// 数字表达式
class Number implements MathExpression {
private int value;

public Number(int value) {
this.value = value;
}

@Override
public int interpret() {
return value;
}
}

// 加法表达式
class Add implements MathExpression {
private MathExpression left;
private MathExpression right;

public Add(MathExpression left, MathExpression right) {
this.left = left;
this.right = right;
}

@Override
public int interpret() {
return left.interpret() + right.interpret();
}
}

// 减法表达式
class Subtract implements MathExpression {
private MathExpression left;
private MathExpression right;

public Subtract(MathExpression left, MathExpression right) {
this.left = left;
this.right = right;
}

@Override
public int interpret() {
return left.interpret() - right.interpret();
}
}

// 乘法表达式
class Multiply implements MathExpression {
private MathExpression left;
private MathExpression right;

public Multiply(MathExpression left, MathExpression right) {
this.left = left;
this.right = right;
}

@Override
public int interpret() {
return left.interpret() * right.interpret();
}
}

// 使用
public class Calculator {
public static void main(String[] args) {
// 计算:3 + 5
MathExpression three = new Number(3);
MathExpression five = new Number(5);
MathExpression add = new Add(three, five);
System.out.println("3 + 5 = " + add.interpret());

// 计算:(2 + 3) × 4
MathExpression two = new Number(2);
MathExpression four = new Number(4);
MathExpression add2 = new Add(two, three); // 2 + 3
MathExpression multiply = new Multiply(add2, four); // (2+3) × 4
System.out.println("(2 + 3) × 4 = " + multiply.interpret());

// 计算:10 - 2 × 3
MathExpression ten = new Number(10);
MathExpression multiply2 = new Multiply(two, three); // 2 × 3
MathExpression subtract = new Subtract(ten, multiply2); // 10 - (2×3)
System.out.println("10 - 2 × 3 = " + subtract.interpret());
}
}

10.命令模式

将请求封装为对象,可参数化、队列化请求,支持撤销 / 重做

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
import java.util.*;

// 订单项(命令)
class OrderItem implements Command {
private Chef chef;
private String dish;

public OrderItem(Chef chef, String dish) {
this.chef = chef;
this.dish = dish;
}

@Override
public void execute() {
chef.cook(dish);
}
}

// 厨师(接收者)
class Chef {
private String name;

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

public void cook(String dish) {
System.out.println(name + " 正在烹饪: " + dish);
// 模拟烹饪时间
try {
Thread.sleep(500);
System.out.println("✅ " + dish + " 做好了!");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

// 服务员(调用者)
class Waiter {
private Queue<Command> orders = new LinkedList<>();

public void takeOrder(Command order) {
orders.offer(order);
System.out.println("📝 已接单");
}

public void placeOrders() {
System.out.println("\n=== 开始上菜 ===");
while (!orders.isEmpty()) {
Command order = orders.poll();
order.execute();
}
System.out.println("所有菜品已上齐!");
}
}

// 使用
public class Restaurant {
public static void main(String[] args) {
// 创建厨师
Chef chef = new Chef("张师傅");

// 创建订单命令
OrderItem order1 = new OrderItem(chef, "宫保鸡丁");
OrderItem order2 = new OrderItem(chef, "麻婆豆腐");
OrderItem order3 = new OrderItem(chef, "鱼香肉丝");

// 服务员接单
Waiter waiter = new Waiter();
waiter.takeOrder(order1);
waiter.takeOrder(order2);
waiter.takeOrder(order3);

// 开始做菜
waiter.placeOrders();
}
}

11.责任链模式

将请求沿处理链传递,多个对象可处理请求,避免请求发送者与接收者耦合

“击鼓传花”模式:让多个对象都有机会处理请求,形成一条链,请求沿着链传递直到被处理。

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
// 处理者抽象类
abstract class Approver {
protected Approver next; // 下一个处理者

public void setNext(Approver next) {
this.next = next;
}

public abstract void processRequest(LeaveRequest request);
}

// 具体处理者:组长
class TeamLeader extends Approver {
@Override
public void processRequest(LeaveRequest request) {
if (request.getDays() <= 1) {
System.out.println("组长批准 " + request.getName() + " 请假 " + request.getDays() + " 天");
} else if (next != null) {
next.processRequest(request);
}
}
}

// 具体处理者:经理
class Manager extends Approver {
@Override
public void processRequest(LeaveRequest request) {
if (request.getDays() <= 3) {
System.out.println("经理批准 " + request.getName() + " 请假 " + request.getDays() + " 天");
} else if (next != null) {
next.processRequest(request);
}
}
}

// 具体处理者:总监
class Director extends Approver {
@Override
public void processRequest(LeaveRequest request) {
if (request.getDays() <= 7) {
System.out.println("总监批准 " + request.getName() + " 请假 " + request.getDays() + " 天");
} else {
System.out.println("请假 " + request.getDays() + " 天太长,需要董事会批准!");
}
}
}

// 请假请求
class LeaveRequest {
private String name;
private int days;

public LeaveRequest(String name, int days) {
this.name = name;
this.days = days;
}

public String getName() { return name; }
public int getDays() { return days; }
}

// 使用
public class SimpleChain {
public static void main(String[] args) {
// 创建处理链
Approver leader = new TeamLeader();
Approver manager = new Manager();
Approver director = new Director();

// 设置链的顺序:组长 -> 经理 -> 总监
leader.setNext(manager);
manager.setNext(director);

// 提交请假申请
System.out.println("=== 请假申请 ===");
leader.processRequest(new LeaveRequest("张三", 1)); // 组长批
leader.processRequest(new LeaveRequest("李四", 2)); // 经理批
leader.processRequest(new LeaveRequest("王五", 5)); // 总监批
leader.processRequest(new LeaveRequest("赵六", 10)); // 没人能批
}
}

七、自定义Spring框架

后续再写