MultiThread/README/设计模式-v2.md

2521 lines
64 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 设计模式
设计模式是对许多业务和算法的抽象,因此学习起来具有一定的难度。短时间内掌握是不可能的,需要通过不断的实践和理解来积累经验。对于已经在职场上工作,但后期才开始学习设计模式的人来说,可能会面临更多的挑战。
在学习设计模式时很多概念趋于理论化且种类繁多设计模式总共有23种如果没有进行系统的梳理可能很难直接应用到实际场景中。
设计模式中的抽象类通常是接口或抽象类,这些类的实现会根据具体的业务需求进行调整,因而不一定是唯一的实现方式。
在我学习过程中,我试图将所学的内容总结下来,但由于篇幅有限,无法一一列举所有场景,只能举出一些常见的例子。
---
## 工厂模式---创建型
### 工厂模式Factory Pattern介绍
工厂模式属于创建型设计模式,主要用于通过定义一个接口来创建对象,但让子类决定实例化哪一个类。通过这种方式,工厂模式将对象的创建与使用分离,从而解耦了客户端与具体类的依赖关系。
工厂模式的核心思想是:**让子类决定具体要创建哪一个产品,而不是直接在客户端代码中硬编码要使用哪个类**。
### 工厂模式的主要角色
1. **产品接口Product**:通常是一个接口或者抽象类,定义了具体产品的公共方法。
2. **具体产品Concrete Product**:实现了产品接口的具体类,代表不同的产品。
3. **工厂接口Creator**:通常是一个抽象类或接口,定义了一个工厂方法用于创建产品。
4. **具体工厂Concrete Creator**:实现了工厂接口的具体类,负责创建具体的产品对象。
### 工厂模式的类型
1. **简单工厂模式Simple Factory**:通过工厂类中的一个方法,根据传入的参数决定返回哪种具体的产品对象。
2. **工厂方法模式Factory Method**:通过一个工厂接口或者抽象类来定义创建产品的工厂方法,让子类决定创建哪个具体产品。
3. **抽象工厂模式Abstract Factory**:提供一个创建一系列相关或相互依赖对象的接口,而无需指定具体类。
### 简单工厂模式示例Java
```java
// 产品接口
public interface Product {
void create();
}
// 具体产品A
public class ProductA implements Product {
@Override
public void create() {
System.out.println("Product A created.");
}
}
// 具体产品B
public class ProductB implements Product {
@Override
public void create() {
System.out.println("Product B created.");
}
}
// 工厂类
public class ProductFactory {
// 简单工厂方法,根据输入参数创建不同的产品
public static Product createProduct(String productType) {
if ("A".equals(productType)) {
return new ProductA();
} else if ("B".equals(productType)) {
return new ProductB();
}
throw new IllegalArgumentException("Unknown product type");
}
}
// 客户端代码
public class Client {
public static void main(String[] args) {
Product productA = ProductFactory.createProduct("A");
productA.create();
Product productB = ProductFactory.createProduct("B");
productB.create();
}
}
```
### 优点
1. **降低耦合度**:工厂模式将对象的创建过程与使用过程分开,客户端不需要了解具体的创建过程,从而降低了耦合度。
2. **易于扩展**可以通过新增具体产品类和工厂方法来扩展系统不需要修改现有代码符合开闭原则OCP
3. **提高代码的可维护性**:当需要修改创建产品的逻辑时,只需修改工厂类,不影响客户端代码。
### 缺点
1. **增加类的数量**:引入了工厂类、产品接口和多个具体产品类,可能导致类的数量增加,系统变得复杂。
2. **难以理解和维护**:对于一些简单的应用程序,使用工厂模式可能会使得设计过于复杂,反而增加了理解和维护的难度。
---
## 单例模式---创建型
### 懒汉模式
#### 双重检查锁定DCL
```java
public class Singleton {
private static volatile Singleton instance;
private Singleton() {
// 构造函数私有化
}
public static Singleton getInstance() {
if (instance == null) { // 第一次检查
synchronized (Singleton.class) {
if (instance == null) { // 第二次检查
instance = new Singleton();
}
}
}
return instance;
}
}
```
#### 静态内部类方式
利用 **静态内部类**(饿汉式)的特性来实现懒汉模式,并且可以保证线程安全。这种方式只有在调用 `getInstance()` 时才会加载内部类,从而实现懒加载。
```java
public class Singleton {
private Singleton() {
// 构造函数私有化
}
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
```
#### 适用场景
- 如果单例对象比较重,且只在程序中某些特定情况下才使用,懒汉模式可以带来性能优势。
- 在低并发环境或单线程环境下,懒汉模式使用较为简单,不会有多线程安全问题。
- 对于高并发且需要频繁访问单例的场景,推荐使用**静态内部类**或**饿汉模式**来避免懒汉模式可能带来的性能问题。
- **优点**
1. 延迟加载,节省资源。
2. 内存优化,只有在需要时才实例化。
3. 减少不必要的初始化开销。
- **缺点**
1. 传统懒汉模式线程不安全(多个线程可能会创建多个实例)。
2. 使用同步机制会有性能开销,特别是在多线程环境下。
3. 代码复杂性较高,容易引入错误。
4. 不适合高并发场景,特别是频繁访问时会影响性能。
### 饿汉模式
**饿汉模式**Eager Initialization是单例模式的一种实现方式在该方式中单例实例在类加载时就已经创建完成而不是在首次使用时才创建。换句话说**饿汉模式**
的单例实例在类被加载时就会立即初始化,确保了单例模式的唯一性。
```java
public class Singleton {
// 在类加载时就初始化单例对象
private static final Singleton INSTANCE = new Singleton();
// 私有构造函数,防止外部通过 new 创建实例
private Singleton() {
}
// 提供全局访问点
public static Singleton getInstance() {
return INSTANCE;
}
}
```
#### 适用场景
- **简单应用**:适合没有延迟初始化需求的小型应用,或者单例对象的创建非常轻量,不会影响系统性能的场景。
- **实例化不耗费太多资源**:如果单例对象的初始化过程非常轻量级且无须延迟初始化,可以使用饿汉模式。
- **类加载顺序固定**:如果不在乎单例对象在启动时是否初始化,且单例对象的初始化过程没有严重性能损失,可以选择饿汉模式。
- **优点**:简单、线程安全、性能高(没有锁机制)、实现方便。
- **缺点**:不支持延迟加载、可能会浪费资源(如果单例对象不常用时)。
饿汉模式是单例模式中最简单的实现方式,适用于大多数情况下单例对象的创建开销较小,且不需要延迟初始化的场景。如果单例对象的创建非常轻量且不依赖于后期加载时的资源,饿汉模式是一个不错的选择。
### 枚举类型实现
**枚举类型实现单例模式**Enum Singleton是实现单例模式的另一种方式优点是更加简洁、可靠并且避免了许多常见的单例实现方式如懒汉模式和饿汉模式可能出现的问题。使用枚举类型的单例实现方式自
**Java 5** 引入以来,已经成为了最推荐的单例模式实现方式之一。
**当你不需要懒加载或延迟初始化时,使用枚举实现单例模式是最理想的选择。**
```java
public enum Singleton {
// 唯一实例
INSTANCE;
// 可以添加其他的方法
public void someMethod() {
System.out.println("This is a singleton instance method.");
}
}
```
#### 使用示例
```java
public class Main {
public static void main(String[] args) {
// 获取单例对象
Singleton singleton = Singleton.INSTANCE;
// 调用单例方法
singleton.someMethod();
}
}
```
## 原型模式---创建型
![image-20250202214232289](./images/设计模式-v2/image-20250202214232289.png)
需要三个角色抽象原型类Abstract Prototype、具体原型类Concrete Prototype、访问类Client
### 简单示例
提示:需要做深克隆,当类中还存在另一个类时
#### 错误示例代码
当我们对school对象进行设置时对`resume1`进行设置结果`resume`也发生了改变。需要修改`Resume`类中的`clone`方法
```java
public class Prototype {
public static void main(String[] args) {
Resume resume = new Resume();
resume.name = "Bunny";
resume.position = "架构师";
resume.salary = 15000;
School school = new School();
school.schoolName = "江南大学";
school.time = "2025年2月2日21:38:07";
resume.school = school;
System.out.println(resume);
Resume resume1 = resume.clone();
resume1.salary = 19000;
resume1.school.schoolName = "清华大学";
System.out.println(resume1);
Resume resume2 = resume.clone();
resume2.salary = 20000;
System.out.println(resume2);
System.out.println(resume1 == resume2);// false
System.out.println(resume1.school == resume2.school);// true
}
@Data
static class Resume implements Cloneable {
private String name;
private String position;
private Integer salary;
private School school;
@Override
public Resume clone() {
try {
return (Resume) super.clone();
} catch (CloneNotSupportedException e) {
throw new AssertionError();
}
}
}
@Data
static class School implements Cloneable {
private String schoolName;
private String time;
@Override
public School clone() {
try {
return (School) super.clone();
} catch (CloneNotSupportedException e) {
throw new AssertionError();
}
}
}
}
```
#### 运行结果:
```java
Prototype.Resume(name=Bunny, position=架构师, salary=15000, school=Prototype.School(schoolName=江南大学, time=2025年2月2日21:38:07))
Prototype.Resume(name=Bunny, position=架构师, salary=19000, school=Prototype.School(schoolName=清华大学, time=2025年2月2日21:38:07))
Prototype.Resume(name=Bunny, position=架构师, salary=20000, school=Prototype.School(schoolName=清华大学, time=2025年2月2日21:38:07))
false
true
```
#### 正确示例代码
##### 修改`conle`
```java
@Data
static class Resume implements Cloneable {
private String name;
private String position;
private Integer salary;
private School school;
@Override
public Resume clone() {
Resume resume = null;
try {
resume = (Resume) super.clone();
if (school != null) {
resume.school = school.clone();
}
} catch (CloneNotSupportedException e) {
throw new AssertionError();
}
return resume;
}
}
```
##### 示例
```java
public class Prototype {
public static void main(String[] args) {
Resume resume = new Resume();
resume.name = "Bunny";
resume.position = "架构师";
resume.salary = 15000;
School school = new School();
school.schoolName = "江南大学";
school.time = "2025年2月2日21:38:07";
resume.school = school;
System.out.println(resume);
Resume resume1 = resume.clone();
resume1.salary = 19000;
resume1.school.schoolName = "清华大学";
System.out.println(resume1);
Resume resume2 = resume.clone();
resume2.salary = 20000;
System.out.println(resume2);
System.out.println(resume1 == resume2);// false
System.out.println(resume1.school == resume2.school);// false
}
@Data
static class Resume implements Cloneable {
private String name;
private String position;
private Integer salary;
private School school;
@Override
public Resume clone() {
Resume resume = null;
try {
resume = (Resume) super.clone();
if (school != null) {
resume.school = school.clone();
}
} catch (CloneNotSupportedException e) {
throw new AssertionError();
}
return resume;
}
}
@Data
static class School implements Cloneable {
private String schoolName;
private String time;
@Override
public School clone() {
try {
return (School) super.clone();
} catch (CloneNotSupportedException e) {
throw new AssertionError();
}
}
}
}
```
#### 运行结果:
```java
Prototype.Resume(name=Bunny, position=架构师, salary=15000, school=Prototype.School(schoolName=江南大学, time=2025年2月2日21:38:07))
Prototype.Resume(name=Bunny, position=架构师, salary=19000, school=Prototype.School(schoolName=清华大学, time=2025年2月2日21:38:07))
Prototype.Resume(name=Bunny, position=架构师, salary=20000, school=Prototype.School(schoolName=江南大学, time=2025年2月2日21:38:07))
false
false
```
---
## 建造者模式
![image-20250201203116885](./images/设计模式-v2/image-20250201203116885.png)
### 简单示例
比如我们要构建一个复杂的 `Computer`(计算机)对象。我们可以定义一个 `ComputerBuilder`,它将按顺序设置计算机的 CPU、内存、硬盘等组件最后得到一个完整的 `Computer` 对象。
#### 代码示例
```java
public class CommandDemo {
public static void main(String[] args) {
ConcreteLowComputerBuilder concreteLowComputerBuilder = new ConcreteLowComputerBuilder();
Director director = new Director(concreteLowComputerBuilder);
director.constructComputer();
System.out.println(concreteLowComputerBuilder.getComputer());
System.out.println("\n-----------------分割线-----------------\n");
ConcreteHighComputerBuilder concreteHighComputerBuilder = new ConcreteHighComputerBuilder();
director = new Director(concreteHighComputerBuilder);
director.constructComputer();
System.out.println(concreteHighComputerBuilder.getComputer());
}
// 构建产品接口
interface ComputerBuilder {
/**
* 构建 CPU 方法
*/
void buildCPU();
/**
* 构建 RAM 方法
*/
void buildRAM();
/**
* 构建 磁盘 方法
*/
void buildHardDrive();
/**
* 返回产品
*
* @return Computer
*/
Computer getComputer();
}
// 产品类
@Data
static class Computer {
private String CPU;
private String RAM;
private String hardDrive;
}
// 构建低端产品
static class ConcreteLowComputerBuilder implements ComputerBuilder {
private final Computer computer = new Computer();
/**
* 构建 CPU 方法
*/
@Override
public void buildCPU() {
computer.setCPU("Low CPU");
}
/**
* 构建 RAM 方法
*/
@Override
public void buildRAM() {
computer.setRAM("Low RAM");
}
/**
* 构建 磁盘 方法
*/
@Override
public void buildHardDrive() {
computer.setHardDrive("Low Driver");
}
/**
* 返回产品
*
* @return Computer
*/
@Override
public Computer getComputer() {
return computer;
}
}
// 构建高端产品
static class ConcreteHighComputerBuilder implements ComputerBuilder {
private final Computer computer = new Computer();
/**
* 构建 CPU 方法
*/
@Override
public void buildCPU() {
computer.setCPU("High CPU");
}
/**
* 构建 RAM 方法
*/
@Override
public void buildRAM() {
computer.setRAM("High RAM");
}
/**
* 构建 磁盘 方法
*/
@Override
public void buildHardDrive() {
computer.setHardDrive("High Driver");
}
/**
* 返回产品
*
* @return Computer
*/
@Override
public Computer getComputer() {
return computer;
}
}
// 构建者
public static class Director {
private final ComputerBuilder builder;
public Director(ComputerBuilder builder) {
this.builder = builder;
}
public void constructComputer() {
builder.buildCPU();
builder.buildRAM();
builder.buildHardDrive();
}
}
}
```
#### 运行结果:
```java
CommandDemo.Computer(CPU=Low CPU, RAM=Low RAM, hardDrive=Low Driver)
-----------------分割线-----------------
CommandDemo.Computer(CPU=High CPU, RAM=High RAM, hardDrive=High Driver)
```
---
## 装饰者模式---结构型
一共有四个角色。
- 抽象组件:一般是最原始、最基础的对象。
- 具体组件:一般是最原始最基础的实现对象,可以有多个(只是数量不多),可以大致看下`InputStream`UML结构图。
- 装饰角色:继承或者实现**抽象组件**这是最关键的地方。
- 具体装饰角色:可以有多个实现或者继承**装饰角色**。
### 简单示例
需要做一个抽象的相机功能,相机包含拍照功能(这是肯定的),之后随着业务需求要求相机有美颜功能,在这之后还要有滤镜功能,客户还需要延迟摄影功能。
![image-20250201185356903](./images/设计模式-v2/image-20250201185356903.png)
#### 代码实现
1. 需要定义根组件Component
2. 制作最原始的拍照功能,实现根组件
3. 制作延迟摄影,实现根组件
4. 作为相机之外的功能(美颜),需要定义装饰角色方便为以后的组件进行扩展
5. 继承或者实现(装饰者角色),完成美颜
6. 继承或者实现(装饰者角色),完成滤镜
```java
public class CameraDemo {
public static void main(String[] args) {
TakePhotoCamera takePhotoCamera = new TakePhotoCamera();
takePhotoCamera.operation();
System.out.println("\n-----------------分割线-----------------\n");
BeautyCamera beautyCamera = new BeautyCamera(takePhotoCamera);
beautyCamera.operation();
System.out.println("\n-----------------分割线-----------------\n");
FilterCamera filterCamera = new FilterCamera(beautyCamera);
filterCamera.operation();
System.out.println("\n-----------------分割线-----------------\n");
TimerCamera timerCamera = new TimerCamera();
timerCamera.setTime(2);
timerCamera.operation();
filterCamera = new FilterCamera(beautyCamera);
filterCamera.operation();
}
// 相机功能
interface Camera {
/**
* 相机操作
*/
void operation();
}
// 相机装饰者角色
static abstract class CameraDecorator implements Camera {
Camera camera;
public CameraDecorator(Camera camera) {
this.camera = camera;
}
}
// 相机拍照
static class TakePhotoCamera implements Camera {
/**
* 相机操作
*/
@Override
public void operation() {
System.out.println("相机拍照。。。");
}
}
// 相机功能
static class BeautyCamera extends CameraDecorator {
public BeautyCamera(Camera camera) {
super(camera);
}
/**
* 相机操作
*/
@Override
public void operation() {
camera.operation();
System.out.println("美颜功能。。。");
}
}
// 滤镜效果
static class FilterCamera extends CameraDecorator {
public FilterCamera(Camera camera) {
super(camera);
}
/**
* 相机操作
*/
@Override
public void operation() {
camera.operation();
System.out.println("滤镜效果。。。");
}
}
// 实现相机延迟功能
@Setter
static class TimerCamera implements Camera {
// 延迟时间
private Integer time = 0;
/**
* 相机操作
*/
@Override
public void operation() {
System.out.println("开始拍照,延迟时间:" + time + "s");
try {
Thread.sleep(time * 1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
```
#### 运行结果:
```java
相机拍照。。。
-----------------分割线-----------------
相机拍照。。。
美颜功能。。。
-----------------分割线-----------------
相机拍照。。。
美颜功能。。。
滤镜效果。。。
-----------------分割线-----------------
开始拍照延迟时间2s
相机拍照。。。
美颜功能。。。
滤镜效果。。。
```
---
## 外观模式---结构型
有点类似网址导航的思想,比如有很多零散的东西(网址)但是每次我们想用的时候需要寻找这些网址,如果有个网址大全讲这些网址封装我们寻找会方便很多。
再或者,我们每天看天气,需要打开手机点开天气应用、熄屏;如果我们将这些东西封装成单独的指令会简化我们平时的行为,比如写个脚本执行上面的事情。
主要角色门面角色Facade、子系统角色Sub System、客户角色Client
![image-20250203154216552](./images/设计模式-v2/image-20250203154216552.png)
### 简单实现
#### 示例代码
```java
public class Facade {
public static void main(String[] args) {
DeviceFacade deviceFacade = new DeviceFacade();
// 查看
deviceFacade.on();
// 看完关闭
deviceFacade.off();
}
// 子系统-手机
static class SubSystemIPhone {
public void on() {
System.out.println("打开手机。。。");
}
public void off() {
System.out.println("关闭手机。。。");
}
}
// 子系统-天气
static class SubSystemWeather {
public void on() {
System.out.println("打开天气。。。");
}
public void off() {
System.out.println("关闭天气。。。");
}
}
// 门面
static class DeviceFacade {
// 也可以作为参数传递,如果没有别的实现类,直接在内部初始化会使使用者更简单
SubSystemIPhone subSystemIPhone = new SubSystemIPhone();
SubSystemWeather subSystemWeather = new SubSystemWeather();
public void on() {
subSystemIPhone.on();
subSystemWeather.on();
}
public void off() {
subSystemWeather.off();
subSystemIPhone.off();
}
}
}
```
#### 运行结果:
```java
打开手机。。。
打开天气。。。
关闭天气。。。
关闭手机。。。
```
---
## 适配器模式---结构型
需要角色抽象适配者角色Abstract Adapter、适配者角色Adapter、目标角色Target
在生活中有时需要将380V三相电转成220V这时候需要变压器当然也有三相电转两相电接法我们可以使用代码模拟这个操作 。
![](./images/设计模式-v2/v2-8efc399313ae3746932c63069aa103b0_1440w-1738507407103-4.avif)
### 类适配器
![image-20250202222740030](./images/设计模式-v2/image-20250202222740030.png)
#### 示例代码
```java
public class Adapter1 {
public static void main(String[] args) {
PowerAdapter powerAdapter = new PowerAdapter();
Integer integer = powerAdapter.output220V();
System.out.println("----------------");
PowerAdapter powerAdapter1 = new PowerAdapter();
powerAdapter1.output220V();
Integer i = powerAdapter1.output380V();
}
// 电压输出
interface PowerTarget {
/**
* 输出电压220V
*
* @return 输出电压
*/
Integer output220V();
}
static class PowerAdapter extends Power implements PowerTarget {
/**
* 输出电压220V
*
* @return 输出电压
*/
@Override
public Integer output220V() {
Integer output = super.getOutput();
System.out.println("变压器交流" + output + "v转220v三相电变两项电。。。");
double adapter = new Random().nextDouble(1.64, 1.72);
Integer newOutput = (int) (output / adapter);
System.out.println("变压器转换完成:电压输出为:" + newOutput);
return newOutput;
}
}
@Data
static class Power {
private Integer output = 380;
public Integer output380V() {
System.out.println("输出电压:" + output);
return output;
}
}
}
```
#### 运行结果:
```java
变压器交流380v转220v三相电变两项电。。。
变压器转换完成电压输出为224
----------------
变压器交流380v转220v三相电变两项电。。。
变压器转换完成电压输出为224
输出电压380
```
### 对象适配器
![image-20250202223220831](./images/设计模式-v2/image-20250202223220831.png)
#### 示例代码
```java
public class Adapter2 {
public static void main(String[] args) {
Power power = new Power();
PowerAdapter powerAdapter = new PowerAdapter(power);
Integer integer = powerAdapter.output220V();
}
// 电压输出
interface PowerTarget {
/**
* 输出电压220V
*
* @return 输出电压
*/
Integer output220V();
}
@Setter
@Getter
static class PowerAdapter implements PowerTarget {
private final Power power;
public PowerAdapter(Power power) {
this.power = power;
}
/**
* 输出电压220V
*
* @return 输出电压
*/
@Override
public Integer output220V() {
Integer output = power.getOutput();
System.out.println("变压器交流" + output + "v转220v三相电变两项电。。。");
double adapter = new Random().nextDouble(1.64, 1.72);
Integer newOutput = (int) (output / adapter);
System.out.println("变压器转换完成:电压输出为:" + newOutput);
return newOutput;
}
}
@Data
static class Power {
private Integer output = 380;
public Integer output380V() {
System.out.println("输出电压:" + output);
return output;
}
}
}
```
#### 运行结果
```java
变压器交流380v转220v三相电变两项电。。。
变压器转换完成电压输出为224
```
### 缺省适配器
![image-20250202224211540](./images/设计模式-v2/image-20250202224211540.png)
#### 示例代码
```java
public class Adapter3 {
public static void main(String[] args) {
Power power = new Power();
PowerAdapter powerAdapter = new Power220VAdapter(power);
Integer integer = powerAdapter.output220V();
}
// 电压输出
interface PowerTarget {
/**
* 输出电压24V
*
* @return 输出电压
*/
Integer output24V();
/**
* 输出电压110V
*
* @return 输出电压
*/
Integer output110V();
/**
* 输出电压220V
*
* @return 输出电压
*/
Integer output220V();
}
@Data
static abstract class PowerAdapter implements PowerTarget {
protected Power power;
public PowerAdapter(Power power) {
this.power = power;
}
/**
* 输出电压24V
*
* @return 输出电压
*/
@Override
public Integer output24V() {
return 0;
}
/**
* 输出电压110V
*
* @return 输出电压
*/
@Override
public Integer output110V() {
return 0;
}
/**
* 输出电压220V
*
* @return 输出电压
*/
@Override
public Integer output220V() {
return 0;
}
}
// 缺省适配器转换器
static class Power220VAdapter extends PowerAdapter {
public Power220VAdapter(Power power) {
super(power);
}
/**
* 输出电压220V
*
* @return 输出电压
*/
@Override
public Integer output220V() {
Integer output = power.getOutput();
System.out.println("变压器开始转换:" + output + "v转220v三相电变两项电。。。");
double adapter = new Random().nextDouble(1.64, 1.72);
Integer newOutput = (int) (output / adapter);
System.out.println("变压器转换完成:电压输出为:" + newOutput);
return newOutput;
}
}
@Data
static class Power {
private Integer output = 380;
public Integer output380V() {
System.out.println("输出电压:" + output);
return output;
}
}
}
```
#### 运行结果:
```java
变压器开始转换380v转220v三相电变两项电。。。
变压器转换完成电压输出为224
```
---
## 组合模式---结构型
组合模式Composite Pattern是一种结构型设计模式用于将对象组合成树形结构以表示“部分-整体”层次结构。组合模式让客户端以统一的方式对待单个对象和对象组合。
![image-20250203210907388](./images/设计模式-v2/image-20250203210907388.png)
1. **Component抽象组件**
- 定义了组合对象和叶子对象的共同接口。
- 在组合模式中,所有的“叶子”和“容器”类都实现此接口,因此客户端可以一致地对待这些对象。
- 例如,可以定义一个 `Operation` 方法,使得所有的组件(无论是叶子对象还是组合对象)都能执行该操作。
2. **Leaf叶子节点**
- 叶子对象表示树的最末端元素,不再有子对象。
- 叶子对象继承自 `Component` 类,具体实现功能。
- 叶子对象不再包含子节点。
3. **Composite组合节点**
- 组合对象也实现了 `Component` 接口,且包含多个子组件(即可以包含其他 `Leaf``Composite` 对象)。
- 组合节点负责将所有的叶子节点和子组合节点组织起来,实现“部分-整体”的结构。
### 简单示例
#### 示例代码
```java
public class Composite {
public static void main(String[] args) {
ConcreteCompany company = new ConcreteCompany("总公司");
// 总公司的分公司
ConcreteCompany subCompany1 = new ConcreteCompany("上海分公司");
subCompany1.add(new HRDepartment("上海华东分公司"));
subCompany1.add(new FinanceDepartment("上海华东分公司"));
company.add(subCompany1);
// 总公司的分公司
ConcreteCompany subCompany2 = new ConcreteCompany("北京分公司");
subCompany2.add(new HRDepartment("北京华东分公司"));
subCompany2.add(new FinanceDepartment("北京华东分公司"));
company.add(subCompany2);
// 上海的南京分公司
ConcreteCompany subCompany3 = new ConcreteCompany("南京分公司");
subCompany3.add(new HRDepartment("南京华东分公司"));
subCompany3.add(new FinanceDepartment("南京华东分公司"));
subCompany1.add(subCompany3);
System.out.println("---------------------显示组织图---------------------");
company.display(1);
System.out.println("---------------------显示职责---------------------");
company.duty();
}
// Component 抽象子组件
abstract static class Company {
protected String name;
public Company(String name) {
this.name = name;
}
/**
* 添加节点
*
* @param company 子组件
*/
public abstract void add(Company company);
/**
* 删除节点
*
* @param company 子组件
*/
public abstract void remove(Company company);
/**
* 显示
*
* @param depth 深度
*/
public abstract void display(int depth);
/**
* 职责
*/
public abstract void duty();
}
// 容器对象
static class ConcreteCompany extends Company {
private final List<Company> companyList = new ArrayList<>();
public ConcreteCompany(String name) {
super(name);
}
/**
* 添加节点
*
* @param company 子组件
*/
@Override
public void add(Company company) {
companyList.add(company);
}
/**
* 删除节点
*
* @param company 子组件
*/
@Override
public void remove(Company company) {
companyList.remove(company);
}
/**
* 显示
*
* @param depth 深度
*/
@Override
public void display(int depth) {
for (int i = 0; i < depth; i++) System.out.print("-");
System.out.println(name);
for (Company company : companyList) {
company.display(depth + 1);
}
}
/**
* 职责
*/
@Override
public void duty() {
for (Company company : companyList) {
company.duty();
}
}
}
// 人事部门
static class HRDepartment extends Company {
public HRDepartment(String name) {
super(name);
}
/**
* 添加节点
*
* @param company 子组件
*/
@Override
public void add(Company company) {
}
/**
* 删除节点
*
* @param company 子组件
*/
@Override
public void remove(Company company) {
}
/**
* 显示
*
* @param depth 深度
*/
@Override
public void display(int depth) {
for (int i = 0; i < depth; i++) System.out.print("-");
System.out.println(name);
}
/**
* 职责
*/
@Override
public void duty() {
System.out.println(name + ":员工招聘培训管理");
}
}
// 财务部
static class FinanceDepartment extends Company {
public FinanceDepartment(String name) {
super(name);
}
/**
* 添加节点
*
* @param company 子组件
*/
@Override
public void add(Company company) {
}
/**
* 删除节点
*
* @param company 子组件
*/
@Override
public void remove(Company company) {
}
/**
* 显示
*
* @param depth 深度
*/
@Override
public void display(int depth) {
for (int i = 0; i < depth; i++) System.out.print("-");
System.out.println(name);
}
/**
* 职责
*/
@Override
public void duty() {
System.out.println(name + ":公司财务收支管理");
}
}
}
```
#### 运行结果:
```java
---------------------显示组织图---------------------
-总公司
--上海分公司
---上海华东分公司
---上海华东分公司
---南京分公司
----南京华东分公司
----南京华东分公司
--北京分公司
---北京华东分公司
---北京华东分公司
---------------------显示职责---------------------
上海华东分公司员工招聘培训管理
上海华东分公司公司财务收支管理
南京华东分公司员工招聘培训管理
南京华东分公司公司财务收支管理
北京华东分公司员工招聘培训管理
北京华东分公司公司财务收支管理
```
---
## 享元模式---结构型
---
## 代理模式---结构型3
---
## 桥接模式---结构型
---
## 策略模式---行为型
### 常见应用场景
策略模式广泛应用于支付、计算、文件压缩、登录等场景尤其是在游戏中如王者荣耀和PUBG的角色处理。值得注意的是在实际开发中一种业务场景可能会同时使用多种设计模式因此下面的介绍仅为简化并专注于策略模式的核心概念。
### 策略模式基础介绍
策略模式涉及三个主要角色:
1. **抽象策略Strategy**
2. **具体策略Concrete Strategy**
3. **上下文Context**
其中,`Context` 的概念较为抽象,通常用来持有策略并在运行时动态地切换策略。
![策略模式结构图](./images/设计模式-v2/image-20250201164040235.png)
#### 代码实现
策略模式的实现并不复杂,主要是定义三个角色:抽象策略、具体策略和上下文。为了更清晰地展示,我定义了两个具体策略,每个策略执行不同的操作。然后将策略放入上下文中,最终通过上下文来执行具体策略的方法。
```java
public class BaseStrategy {
public static void main(String[] args) {
// 创建具体策略
ConcreteStrategy1 concreteStrategy1 = new ConcreteStrategy1();
ConcreteStrategy2 concreteStrategy2 = new ConcreteStrategy2();
// 通过上下文执行策略
new Context(concreteStrategy1).doIt();
new Context(concreteStrategy2).doIt();
}
// 抽象策略接口
public interface Strategy {
/**
* 执行策略方法
*/
void method();
}
// 具体策略实现1
public static class ConcreteStrategy1 implements Strategy {
@Override
public void method() {
System.out.println("执行具体策略1...");
}
}
// 具体策略实现2
public static class ConcreteStrategy2 implements Strategy {
@Override
public void method() {
System.out.println("执行具体策略2...");
}
}
// 上下文类,持有策略并执行
public static class Context {
private final Strategy strategy;
public Context(Strategy strategy) {
this.strategy = strategy;
}
/**
* 执行策略的方法
*/
public void doIt() {
strategy.method();
}
}
}
```
#### 执行结果:
```java
执行具体策略1...
执行具体策略2...
```
### 示例-游戏角色
需要制作的游戏角色业务需求,基础角色是其他角色的抽象,包括国王、王后、骑士、士兵等,武器是一个接口所有武器都实现这个接口,切换武器(武器有主武器和副武器)可以调用`setPrimaryWeapon`和`setSubWeapon`。
![image-20250201173433406](./images/设计模式-v2/image-20250201173433406.png)
#### 代码实现
```java
public class GameCharacter {
public static void main(String[] args) {
Character soldier = new Soldier();
soldier.fight();
Character king = new King();
king.setPrimaryWeapon(new AxeWeapon());
king.fight();
}
// 武器接口
interface Weapon {
String function();
}
// 各种武器实现
public static class SwordWeapon implements Weapon {
@Override
public String function() {
return "⚔️ ⚔️ ⚔️";
}
}
public static class AxeWeapon implements Weapon {
@Override
public String function() {
return "🪓 🪓 🪓";
}
}
public static class KnifeWeapon implements Weapon {
@Override
public String function() {
return "🔪 🔪 🔪";
}
}
// 抽象角色类
public abstract static class Character {
String name;
@Setter
private Weapon primaryWeapon;
@Setter
private Weapon subWeapon;
public Character(String name) {
this.name = name;
// 默认武器配置
this.primaryWeapon = new SwordWeapon();
this.subWeapon = new KnifeWeapon();
}
void fight() {
if (primaryWeapon != null && subWeapon != null) {
String primary = primaryWeapon.function();
String sub = subWeapon.function();
System.out.println(name + "" + primary + "和" + sub);
} else {
System.out.println(name + "没有武器!");
}
}
}
// 国王角色
public static class King extends Character {
public King() {
super("King");
setPrimaryWeapon(new SwordWeapon());
setSubWeapon(new KnifeWeapon());
}
}
// 士兵角色
public static class Soldier extends Character {
public Soldier() {
super("Soldier");
setPrimaryWeapon(new AxeWeapon());
setSubWeapon(new SwordWeapon());
}
}
}
```
#### 运行结果:
```java
Soldier:🪓 🪓 🪓
King:🪓 🪓 🪓🔪 🔪 🔪
```
---
## 观察者模式---行为型
观察者有四个角色观察者Observe和具体观察者Concrete Observe、主题Subject和具体主题Concrete Subject具体观察者和具体主题可以多个。
![image-20250201175728138](./images/设计模式-v2/image-20250201175728138.png)
### 简单示例
其中主题中有3个方法添加或者理解成注册都可以、移出、通知差不多都是这三个方法其中添加可以理解成注册加入总之是往数组中添加观察者。
#### 代码实现
```java
public class ObserverDemo {
public static void main(String[] args) {
// 定义的主题
News news = new News();
// 观察者
SisterObserver sisterObserver = new SisterObserver();
GirlfriendObserver girlfriendObserver = new GirlfriendObserver();
// 添加观察者
news.addObserver(sisterObserver);
news.notifyObservers("添加了妹妹");
System.out.println("\n-----------------分割线-----------------\n");
// 添加女朋友
news.addObserver(girlfriendObserver);
news.notifyObservers("添加了女朋友");
System.out.println("\n-----------------分割线-----------------\n");
news.removeObserver(girlfriendObserver);
news.notifyObservers("需要和妹妹说点悄悄话,将女朋友移除了,这时女朋友听不见我们说话。。。");
}
// 观察者接口
@FunctionalInterface
interface Observer {
void update(String message);
}
// 主题接口
interface Subject {
void addObserver(Observer observer);
void removeObserver(Observer observer);
void notifyObservers(String message);
}
// 妹妹观察者
static class SisterObserver implements Observer {
@Override
public void update(String message) {
System.out.println("SisterObserver 接受到消息:" + message);
}
}
// 女朋友观察者
static class GirlfriendObserver implements Observer {
@Override
public void update(String message) {
System.out.println("GirlfriendObserver 接受到消息:" + message);
}
}
// 主题类
static class News implements Subject {
private final List<Observer> observerList = new ArrayList<>();
@Override
public void addObserver(Observer observer) {
observerList.add(observer);
}
@Override
public void removeObserver(Observer observer) {
observerList.remove(observer);
}
@Override
public void notifyObservers(String message) {
for (Observer observer : observerList) {
observer.update(message);
}
}
}
}
```
#### 运行结果:
```java
SisterObserver 接受到消息添加了妹妹
-----------------分割线-----------------
SisterObserver 接受到消息添加了女朋友
GirlfriendObserver 接受到消息添加了女朋友
-----------------分割线-----------------
SisterObserver 接受到消息需要和妹妹说点悄悄话将女朋友移除了这时女朋友听不见我们说话。。。
```
---
## 命令模式---行为型
**Command**:定义执行请求的接口(或抽象类)。
**ConcreteCommand**:实现命令接口并具体化执行请求的过程,通常还会持有接收者对象。
**Receiver**:具体的对象,完成实际的操作任务。
**Invoker**:调用命令的对象,触发命令的执行。
**Client**:客户端,负责创建并配置命令对象,将命令与接收者绑定,并传递给调用者执行。
### 简单示例
![image-20250201205350467](./images/设计模式-v2/image-20250201205350467.png)
#### 示例代码
```java
public class CommandDemo {
public static void main(String[] args) {
Receiver receiver = new Receiver();
ConcreteCommand concreteCommand = new ConcreteCommand(receiver);
Invoker invoker = new Invoker();
invoker.setCommand(concreteCommand);
invoker.invoke();
}
// 命令接口
interface Command {
/**
* 执行方法
*/
void execute();
}
// 接受者
static class Receiver {
public void action() {
System.out.println("接受者 执行。。。");
}
}
// 具体的执行命令
static class ConcreteCommand implements Command {
private final Receiver receiver;
public ConcreteCommand(Receiver receiver) {
this.receiver = receiver;
}
/**
* 执行方法
*/
@Override
public void execute() {
receiver.action();
}
}
@Setter
static class Invoker {
private Command command;
public void invoke() {
command.execute();
}
}
}
```
#### 执行结果:
```java
接受者 执行。。。
```
### 示例-烧烤店
![image-20250201205232542](./images/设计模式-v2/image-20250201205232542.png)
#### 示例代码
```java
public class BakeDemo {
// 充当客户端
public static void main(String[] args) {
Waiter waiter = new Waiter();
Barbecue barbecue = new Barbecue();
waiter.addCommand(new BakeChickenWing(barbecue));
waiter.addCommand(new BakeMutton(barbecue));
waiter.notifyCommand();
}
// 接受者-厨师
static class Barbecue {
/**
* 烤串
*/
public void bakeMutton() {
System.out.println("开始烤串。。。");
}
/**
* 烤鸡翅
*/
public void bakeChickenWing() {
System.out.println("开始烤鸡翅。。。");
}
}
// 请求者-invoker-服务员
public static class Waiter {
private final List<Command> commandList = new ArrayList<>();
public void addCommand(Command command) {
commandList.add(command);
}
/**
* 通知厨师开始制作
*/
public void notifyCommand() {
for (Command command : commandList) {
command.execute();
}
}
}
public static abstract class Command {
protected Barbecue barbecue;
public Command(Barbecue barbecue) {
this.barbecue = barbecue;
}
/**
* 执行方法
*/
public abstract void execute();
}
// 命令-烤鸡翅
public static class BakeChickenWing extends Command {
public BakeChickenWing(Barbecue barbecue) {
super(barbecue);
}
/**
* 执行方法
*/
@Override
public void execute() {
barbecue.bakeChickenWing();
}
}
// 命令-烤串
public static class BakeMutton extends Command {
public BakeMutton(Barbecue barbecue) {
super(barbecue);
}
/**
* 执行方法
*/
@Override
public void execute() {
barbecue.bakeMutton();
}
}
}
```
#### 执行结果:
```java
开始烤鸡翅。。。
开始烤串。。。
```
---
## 状态模式---行为型
![image-20250204181749629](./images/设计模式-v2/image-20250204181749629.png)
需要角色状态对象Context、状态接口State、具体状态实现Concrete State
### 简单示例
#### 示例代码
**上下文对象**
```java
@Getter
public class Lift {
// 开门状态
public static LiftState OPEN_STATE = new OpeningLiftState();
// 关门状态
public static LiftState CLOSE_STATE = new ClosingLiftState();
// 运行状态
public static LiftState RUNNING_STATE = new RunningLiftState();
// 停止状态
public static LiftState STOPPING_STATE = new StoppingLiftState();
// 当前电梯状态
private LiftState currentLiftState;
public void setCurrentLiftState(LiftState currentState) {
this.currentLiftState = currentState;
// 执行开门动作
this.currentLiftState.lift = this;
}
public void open() {
currentLiftState.open();
}
public void close() {
currentLiftState.close();
}
public void run() {
currentLiftState.run();
}
public void stop() {
currentLiftState.stop();
}
}
```
**抽象状态接口**
```java
@Setter
abstract class LiftState {
protected Lift lift;
/**
* 开门动作
*/
public abstract void open();
/**
* 关门动作
*/
public abstract void close();
/**
* 运行动作
*/
public abstract void run();
/**
* 停止动作
*/
public abstract void stop();
}
```
**开门状态---具体状态实现**
```java
public class OpeningLiftState extends LiftState {
/**
* 开门动作
*/
@Override
public void open() {
System.out.println("电梯门慢慢打开。。。");
}
/**
* 关门动作
*/
@Override
public void close() {
super.lift.setCurrentLiftState(Lift.CLOSE_STATE);
super.lift.getCurrentLiftState().close();
}
/**
* 运行动作
*/
@Override
public void run() {
}
/**
* 停止动作
*/
@Override
public void stop() {
}
}
```
**关门状态---具体状态实现**
```java
public class ClosingLiftState extends LiftState {
/**
* 开门动作
*/
@Override
public void open() {
super.lift.setCurrentLiftState(Lift.OPEN_STATE);
super.lift.getCurrentLiftState().open();
}
/**
* 关门动作
*/
@Override
public void close() {
System.out.println("电梯关门。。。");
}
/**
* 运行动作
*/
@Override
public void run() {
super.lift.setCurrentLiftState(Lift.RUNNING_STATE);
super.lift.getCurrentLiftState().run();
}
/**
* 停止动作
*/
@Override
public void stop() {
super.lift.setCurrentLiftState(Lift.STOPPING_STATE);
super.lift.getCurrentLiftState().stop();
}
}
```
**运行状态---具体状态实现**
```java
public class RunningLiftState extends LiftState {
/**
* 开门动作
*/
@Override
public void open() {
}
/**
* 关门动作
*/
@Override
public void close() {
}
/**
* 运行动作
*/
@Override
public void run() {
System.out.println("电梯正在运行。。。");
}
/**
* 停止动作
*/
@Override
public void stop() {
super.lift.setCurrentLiftState(Lift.STOPPING_STATE);
super.lift.getCurrentLiftState().stop();
}
}
```
**停止状态---具体状态实现**
```java
public class StoppingLiftState extends LiftState {
/**
* 开门动作
*/
@Override
public void open() {
super.lift.setCurrentLiftState(Lift.OPEN_STATE);
super.lift.getCurrentLiftState().open();
}
/**
* 关门动作
*/
@Override
public void close() {
}
/**
* 运行动作
*/
@Override
public void run() {
super.lift.setCurrentLiftState(Lift.RUNNING_STATE);
super.lift.getCurrentLiftState().run();
}
/**
* 停止动作
*/
@Override
public void stop() {
System.out.println("电梯停止。。。");
}
}
```
#### 运行结果
**当运行时**
```java
public class Client {
public static void main(String[] args) {
Lift lift = new Lift();
lift.setCurrentLiftState(Lift.RUNNING_STATE);
lift.open();
lift.run();
lift.close();
lift.stop();
}
}
```
**运行结果**
```java
电梯正在运行。。。
电梯停止。。。
```
---
## 模板方法模式---行为型
将定义好的按步骤执行的内容进行封装,模板方法是比较单间的设计模式,是代码复用的基本技术,在类库中尤其重要,遵循:“抽象类应当拥有尽可能多的可能性,应当拥有尽可能少的数据”。
![image-20250203163253869](./images/设计模式-v2/image-20250203163253869.png)
需要的角色抽象类Abstract Class、具体类Concrete Class
比如做一些比较固定的事情(支付流程处理),但是其中几项内容可能会发生改变。
### 简单示例
#### 示例代码
```java
public class PaymentProcess {
public static void main(String[] args) {
ConcretePaymentProcess concretePaymentProcess = new ConcretePaymentProcess();
concretePaymentProcess.startProcess();
}
// 抽象模板方法
static abstract class AbstractPaymentProcess {
/**
* 开始流程
*/
public void startProcess() {
authenticationUser();
checkBalance();
executePayment();
returnPayment();
}
/**
* 验证用户身份
*/
private void authenticationUser() {
System.out.println("验证用户身份。。。");
}
/**
* 检查余额
*/
public abstract void checkBalance();
/**
* 执行支付
*/
private void executePayment() {
System.out.println("执行支付。。。");
}
/**
* 返回支付结果
*/
public abstract void returnPayment();
}
static class ConcretePaymentProcess extends AbstractPaymentProcess {
/**
* 检查余额
*/
@Override
public void checkBalance() {
System.out.println("检查完成我的余额还有1999亿元");
}
/**
* 返回支付结果
*/
@Override
public void returnPayment() {
System.out.println("支付成功我的余额还有1994亿元");
}
}
}
```
#### 运行结果:
```java
验证用户身份。。。
检查完成我的余额还有1999亿元
执行支付。。。
支付成功我的余额还有1994亿元
```
---
## 备忘录模式---行为型
**定义**:在不破坏封闭的前提下,捕获一个对象内部状态,并在该对象之外保存这个状态,这样以后就将该对象恢复到原先保存的状态。
需要角色Originator发起人、Memento备忘录、Caretaker管理者
备忘录可以实现功能:撤销、重做、历史记录、快照。
### 简单示例
#### 示例代码
```java
public class Memo {
public static void main(String[] args) {
// 定义记事本
NoteEditText noteEditText = new NoteEditText();
// 负责管理记事本
NoteCaretaker noteCaretaker = new NoteCaretaker();
// 写入记录
noteEditText.content = "创建第一条记录。。。";
noteCaretaker.saveMemo(noteEditText.createMemo());
// 再次写入
noteEditText.content = "第三条记录。。。";
noteCaretaker.saveMemo(noteEditText.createMemo());
// 写错撤销下
noteEditText.restoreMemo(noteCaretaker.getPrevMemo());
}
// 备忘录角色-备忘录
@Getter
static class Memento {
private final String content;
public Memento(String content) {
this.content = content;
}
}
// 存储备忘录--管理者
static class NoteCaretaker {
private final List<Memento> mementoList = new ArrayList<>();
// 存档位置
private int index = 0;
/**
* 添加内容到备忘录中
*
* @param memento 备忘录
*/
public void saveMemo(Memento memento) {
mementoList.add(memento);
index = mementoList.size() - 1;
for (Memento memento1 : mementoList) {
System.out.print(memento1.content + " ");
}
System.out.println();
}
/**
* 获取下一个
*
* @return 备忘录
*/
public Memento getNextMemo() {
index = index > (mementoList.size() - 1) ? index : mementoList.size() - 1;
return mementoList.get(index);
}
/**
* 获取上一个
*
* @return 备忘录
*/
public Memento getPrevMemo() {
index = index > 0 ? (index - 1) : 0;
return mementoList.get(index);
}
}
// 负责创建备忘录-发起人
@Data
static class NoteEditText {
private String content;
public Memento createMemo() {
return new Memento(content);
}
public void restoreMemo(Memento memento) {
this.content = memento.content;
System.out.println("撤销记录:" + content);
}
}
}
```
#### 运行结果:
```java
创建第一条记录。。。
创建第一条记录。。。 第三条记录。。。
撤销记录创建第一条记录。。。
```
---
## 中介者模式---行为型
---
## 迭代器模式---行为型
**定义:**提供一种方法顺序访问一个聚合对象中的哥哥元素,而不是暴露其内部的表示。
![image-20250203173419155](./images/设计模式-v2/image-20250203173419155.png)
需要角色:抽象迭代器、具体迭代器、抽象聚合类、具体聚合类。
### 简单示例
#### 示例代码
```java
public class Iterator {
public static void main(String[] args) {
ListContainer listContainer = new ListContainer();
listContainer.add("序号1");
listContainer.add("序号2");
listContainer.add("序号3");
listContainer.add("序号4");
MyIterator iterator = listContainer.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
}
// 迭代器接口
interface MyIterator {
boolean hasNext();
Object next();
}
// 定义容器
interface MyContainer {
void add(Object o);
void remove(Object o);
MyIterator iterator();
}
// 列表操作容器
static class ListContainer implements MyContainer {
private final List<Object> list = new ArrayList<>();
@Override
public void add(Object o) {
list.add(o);
}
@Override
public void remove(Object o) {
list.remove(o);
}
@Override
public MyIterator iterator() {
return new MyIteratorImpl();
}
class MyIteratorImpl implements MyIterator {
private int index = 0;
@Override
public boolean hasNext() {
return index < list.size();
}
@Override
public Object next() {
Object object = list.get(index);
index++;
return object;
}
}
}
}
```
#### 运行结果:
```java
序号1
序号2
序号3
序号4
```
---
## 访问者模式---行为型
---
## 解释器模式---行为型
---
## 责任链模式---行为型-未完成。。。
主要有两个角色抽象处理者Handler、具体处理者Concrete Handler
![image-20250202201204954](./images/设计模式-v2/image-20250202201204954.png)
### 简单示例
#### 代码示例
```java
public class Chain {
// 过滤垃圾请求,为了演示需要清除【垃圾,辣鸡,腊鸡】这些词
public static void main(String[] args) {
Handler handlerA = new ConcreteHandlerA();
Handler handlerB = new ConcreteHandlerB();
Handler handlerC = new ConcreteHandlerC();
// 设置责任链
handlerA.setNextHandler(handlerB);
handlerB.setNextHandler(handlerC);
// 发起请求
handlerA.handleRequest("过滤垃圾请求,为了演示需要清除【垃圾,辣鸡,腊鸡】这些词");
}
// ConcreteHandler类
static class ConcreteHandlerA extends Handler {
@Override
public void handleRequest(String request) {
// 处理"垃圾"
String updatedRequest = request.replaceAll("垃圾", "");
System.out.println("Handler A处理后: " + updatedRequest);
if (nextHandler != null) {
nextHandler.handleRequest(updatedRequest); // 传递修改后的请求
}
}
}
static class ConcreteHandlerB extends Handler {
@Override
public void handleRequest(String request) {
// 处理"辣鸡"
String updatedRequest = request.replaceAll("辣鸡", "");
System.out.println("Handler B处理后: " + updatedRequest);
if (nextHandler != null) {
nextHandler.handleRequest(updatedRequest); // 传递修改后的请求
}
}
}
static class ConcreteHandlerC extends Handler {
@Override
public void handleRequest(String request) {
// 处理"腊鸡"
String updatedRequest = request.replaceAll("腊鸡", "");
System.out.println("Handler C处理后: " + updatedRequest);
if (nextHandler != null) {
nextHandler.handleRequest(updatedRequest); // 传递修改后的请求
}
}
}
// Handler类
@Setter
abstract static class Handler {
protected Handler nextHandler;
public abstract void handleRequest(String request);
}
}
```
#### 运行结果:
```java
Handler A处理后: 过滤请求为了演示需要清除【,辣鸡腊鸡这些词
Handler B处理后: 过滤请求为了演示需要清除【,,腊鸡这些词
Handler C处理后: 过滤请求为了演示需要清除【,,】这些词
```