一、设计模式概述
Java 中设计模式的整体概述,核心是GoF 经典 23 种设计模式在 Java 中的落地逻辑、分类、核心价值和使用原则,下面从定义与核心价值、经典分类(附 Java 典型应用)、Java 中使用设计模式的特点、使用原则四个核心维度讲清楚,内容贴合 Java 开发实际,新手也能快速理解。
一、Java 设计模式的定义与核心价值
设计模式(Design Patterns)是软件设计中通用、可复用的解决方案,针对 Java 开发中反复出现的代码设计、架构优化、对象交互问题,提供标准化的思路,而非现成的代码。
它的核心价值体现在 Java 开发中:
- 提高代码复用性:避免重复造轮子,比如单例模式解决全局唯一实例的重复实现;
- 增强代码可维护性:符合 Java 的面向对象(OOP)思想,代码结构清晰,易修改、易扩展;
- 统一设计规范:团队开发中达成共识,降低沟通成本;
- 解耦核心逻辑:解决 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 中使用设计模式的核心特点
- 基于 OOP 思想落地:所有设计模式都围绕 Java 的封装、继承、多态、抽象展开,比如多态实现策略模式的动态切换、抽象类 / 接口定义工厂模式的规范;
- 结合 JDK / 框架深度融合:Java 设计模式并非孤立使用,JDK 本身内置了大量设计模式,主流框架(Spring、MyBatis、Tomcat)更是设计模式的集大成者,学习框架的同时也是理解设计模式的过程;
- 支持 “灵活实现”:Java 中设计模式没有固定的代码模板,可根据场景简化,比如单例模式有饿汉式、懒汉式、双重检查锁、枚举式等多种实现,适配不同的线程安全、初始化需求;
- 依赖特性增强:Java 的反射、注解、动态代理(JDK/CGLIB)让设计模式的实现更优雅,比如 Spring 通过反射实现工厂模式创建 Bean,通过动态代理实现 AOP。
四、Java 中使用设计模式的核心原则(六大设计原则)
设计模式的本质是遵循面向对象设计原则,所有模式都是这些原则的具体实现,Java 开发中使用设计模式的前提是遵守这 6 大原则(简称SOLID+ 迪米特法则),避免过度设计:
- 单一职责原则:一个类只负责一个功能模块,比如 Java 的 Service 层只处理业务逻辑,Dao 层只处理数据访问;
- 开闭原则(核心):对扩展开放,对修改关闭,比如用策略模式替换硬编码的 if-else,新增策略只需实现接口,无需修改原有代码;
- 里氏替换原则:子类可以完全替换父类,且不影响程序运行,Java 中继承的核心规范;
- 依赖倒置原则:依赖抽象(接口 / 抽象类),而非具体实现,比如 Service 层依赖 Dao 接口,而非具体的 MySQLDao、OracleDao;
- 接口隔离原则:拆分臃肿的接口,让类只实现自己需要的接口,避免 “接口污染”;
- 迪米特法则(最少知道原则):一个对象只和直接关联的对象通信,降低耦合,比如 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
| class User { private String name; private String email; public void saveToDatabase() { } public void loadFromDatabase() { } public void displayInConsole() { } public void formatForHTML() { } }
class User { private String name; private String email; }
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
| 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() { } }
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() { } }
interface Worker { void work(); default void eat() { } default void sleep() { } }
|
3.依赖倒置原则 (Dependency Inversion Principle, 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 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
| 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; } }
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; } }
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; } throw new IllegalArgumentException("不支持的运算: " + operation); } }
interface Operation { int execute(int a, int b); }
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; } }
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; public String getBookTitle() { return book.getTitle(); } }
class Person { void readBook(Bookshelf shelf) { 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
|
public class Singleton { public static final Singleton INSTANCE = new Singleton();
private Singleton(){
} }
public class Singleton2 { private static final Singleton2 INSTANCE = new Singleton2();
private Singleton2(){
}
public static Singleton2 getInstance(){ return INSTANCE; } }
public class Singleton3 { private static Singleton3 INSTANCE = null;
static{ INSTANCE = new Singleton3(); }
private Singleton3(){
}
public static Singleton3 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
| 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(){ 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 { 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;
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;
public class user { private String name; private int age; private char sex; private String tel;
public user(){}
public static user 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
| interface Shape { void draw(); }
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("画一个三角形 △"); } }
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; } }
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
| interface Vehicle { void drive(); }
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("骑摩托车 🏍️"); } }
interface VehicleFactory { Vehicle createVehicle(); }
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(); } }
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
| interface Chair { void sitOn(); }
interface Sofa { void lieOn(); }
interface Table { void putOn(); }
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("在现代风格的桌子上放置物品"); } }
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("在古典风格的桌子上放置物品"); } }
interface FurnitureFactory { Chair createChair(); Sofa createSofa(); Table createTable(); }
class ModernFurnitureFactory implements FurnitureFactory { public Chair createChair() { return new ModernChair(); } public Sofa createSofa() { return new ModernSofa(); } public Table createTable() { return new ModernTable(); } }
class ClassicalFurnitureFactory implements FurnitureFactory { public Chair createChair() { return new ClassicalChair(); } public Sofa createSofa() { return new ClassicalSofa(); } public Table createTable() { return new ClassicalTable(); } }
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
| class Sheep implements Cloneable { String name; public Sheep(String name) { this.name = name; System.out.println("创建羊: " + name); } @Override public Sheep clone() throws CloneNotSupportedException { return (Sheep) super.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.适配器模式
| 适配器模式 |
转换接口,让不兼容的接口能一起工作 |
“转接头” |
使用场景:
- ✅ 接口不匹配:想用的类接口不符合当前需求
- ✅ 无法修改源码:第三方库/老代码不能改
- ✅ 需要统一接口:多个类似功能但接口不同
- ✅ 系统要支持多种实现:如多种数据库、多种支付
- ✅ 测试需要Mock:隔离外部依赖方便测试
- ✅ 渐进式重构:先适配,再逐步替换
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
| 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; } 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); }
|
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
| interface Text { String getContent(); }
class PlainText implements Text { private String content; public PlainText(String content) { this.content = content; } public String getContent() { return content; } }
abstract class TextDecorator implements Text { protected Text text; public TextDecorator(Text text) { this.text = text; } public String getContent() { return text.getContent(); } }
class BoldDecorator extends TextDecorator { public BoldDecorator(Text text) { super(text); } public String getContent() { return "<b>" + text.getContent() + "</b>"; } }
class ItalicDecorator extends TextDecorator { public ItalicDecorator(Text text) { super(text); } public String getContent() { return "<i>" + text.getContent() + "</i>"; } }
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;
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); } }
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
| abstract class BeverageMaker { public final void makeBeverage() { System.out.println("=== 开始制作饮料 ==="); boilWater(); brew(); pourInCup(); addCondiments(); System.out.println("=== 饮料制作完成 ===\n"); } private void boilWater() { System.out.println("1. 烧开水 (100°C)"); } protected abstract void brew(); private void pourInCup() { System.out.println("3. 倒入杯子"); } protected abstract void addCondiments(); protected boolean customerWantsCondiments() { return true; } }
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"); } }
class CoffeeMaker extends BeverageMaker { protected void brew() { System.out.println("2. 冲泡咖啡粉 (用滤纸过滤)"); } protected void addCondiments() { System.out.println("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"); System.out.println("1. 顾客点了一杯茶:"); BeverageMaker teaMaker = new TeaMaker(); teaMaker.makeBeverage(); System.out.println("2. 顾客点了一杯咖啡:"); BeverageMaker coffeeMaker = new CoffeeMaker(); coffeeMaker.makeBeverage(); 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.*;
interface Cashier { void visit(Apple apple); void visit(Milk milk); void visit(Bread bread); }
interface Product { void accept(Cashier cashier); }
class Apple implements Product { private double weight; public Apple(double weight) { this.weight = weight; } public double getWeight() { return weight; } public void accept(Cashier cashier) { cashier.visit(this); } }
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); } }
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); } }
class PriceCalculator implements Cashier { private double totalPrice = 0; public void visit(Apple apple) { double price = apple.getWeight() * 8; System.out.println("🍎 苹果: " + apple.getWeight() + "kg × 8元 = " + price + "元"); totalPrice += price; } public void visit(Milk milk) { double price = milk.getQuantity() * 5; System.out.println("🥛 牛奶: " + milk.getQuantity() + "盒 × 5元 = " + price + "元"); totalPrice += price; } public void visit(Bread bread) { double price = 10; System.out.println("🍞 " + bread.getType() + "面包: 10元"); totalPrice += price; } public double getTotalPrice() { return totalPrice; } }
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() + "面包: 看是否发霉"); } }
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) { ShoppingCart cart = new ShoppingCart(); cart.addProduct(new Apple(2.5)); cart.addProduct(new Milk(3)); cart.addProduct(new Bread("全麦")); cart.addProduct(new Apple(1.0)); System.out.println("🛒 购物车里有4件商品\n"); PriceCalculator priceCalculator = new PriceCalculator(); cart.process(priceCalculator); System.out.println("💰 总价: " + priceCalculator.getTotalPrice() + "元"); System.out.println("\n---\n"); 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;
interface SortStrategy { void sort(int[] array); }
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; } } } } }
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; } }
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; } } }
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"); System.out.println("1. 冒泡排序:"); context.setStrategy(new BubbleSort()); context.sortArray(Arrays.copyOf(numbers, numbers.length)); System.out.println("2. 快速排序:"); context.setStrategy(new QuickSort()); context.sortArray(Arrays.copyOf(numbers, numbers.length)); System.out.println("3. 选择排序:"); context.setStrategy(new SelectionSort()); context.sortArray(Arrays.copyOf(numbers, numbers.length)); 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(); orderContext.ship(); orderContext.receive(); orderContext.cancel(); } }
|
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()); editor.type("World"); history.push(editor.save()); editor.type("!!!"); editor.print(); editor.restore(history.pop()); editor.print(); editor.restore(history.pop()); editor.print(); } }
|
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) { MathExpression three = new Number(3); MathExpression five = new Number(5); MathExpression add = new Add(three, five); System.out.println("3 + 5 = " + add.interpret()); MathExpression two = new Number(2); MathExpression four = new Number(4); MathExpression add2 = new Add(two, three); MathExpression multiply = new Multiply(add2, four); System.out.println("(2 + 3) × 4 = " + multiply.interpret()); MathExpression ten = new Number(10); MathExpression multiply2 = new Multiply(two, three); MathExpression subtract = new Subtract(ten, multiply2); 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框架
后续再写