目录
[1. 单例模式(Singleton)](#1. 单例模式(Singleton))
[代码实现(3 种常用方式)](#代码实现(3 种常用方式))
[2. 工厂方法模式(Factory Method)](#2. 工厂方法模式(Factory Method))
[3. 建造者模式(Builder)](#3. 建造者模式(Builder))
[二、结构型模式(负责类 / 对象的组合,优化结构)](#二、结构型模式(负责类 / 对象的组合,优化结构))
[1. 代理模式(Proxy)](#1. 代理模式(Proxy))
[代码实现(JDK 动态代理:日志增强)](#代码实现(JDK 动态代理:日志增强))
[2. 装饰器模式(Decorator)](#2. 装饰器模式(Decorator))
[1. 观察者模式(Observer)](#1. 观察者模式(Observer))
[2. 策略模式(Strategy)](#2. 策略模式(Strategy))
Java 设计模式是一套 经过反复验证的、解决特定场景问题的代码设计经验总结 ,核心目标是 解耦、提高代码复用性、增强可维护性和扩展性 。设计模式分为三大类(共 23 种核心模式),下面我会挑选 最常用、最实用的 8 种模式,结合「理论讲解 + 完整代码实现 + 场景落地」,帮你彻底理解并能用起来。
先铺垫核心基础:
- 设计模式的核心原则:SOLID 原则(单一职责、开闭原则、里氏替换、接口隔离、依赖倒置),所有模式都围绕这些原则设计;
- 学习重点:理解「模式要解决的问题」,而不是死记代码模板。
一、创建型模式(负责对象创建,解耦对象创建与使用)
创建型模式专注于「如何灵活创建对象」,避免硬编码 new 关键字导致的耦合。
1. 单例模式(Singleton)
理论部分
- 定义 :确保一个类在整个应用中 只有一个实例,并提供一个全局唯一的访问入口。
- 解决问题:避免重复创建重量级对象(如数据库连接池、配置类),节省资源。
- 核心思想:私有化构造器(禁止外部 new),通过静态方法返回唯一实例。
- 常用实现:饿汉式(线程安全)、懒汉式(延迟加载)、枚举式(最优)。
代码实现(3 种常用方式)
java
运行
java
/**
* 单例模式:3种核心实现
*/
public class SingletonDemo {
// 1. 饿汉式(线程安全,类加载时初始化,无延迟加载)
static class HungrySingleton {
// 类加载时直接创建实例(JVM 类加载是线程安全的)
private static final HungrySingleton INSTANCE = new HungrySingleton();
// 私有化构造器,禁止外部 new
private HungrySingleton() {}
// 全局访问入口
public static HungrySingleton getInstance() {
return INSTANCE;
}
}
// 2. 懒汉式(线程安全,延迟加载,双重校验锁 DCL)
static class LazySingleton {
// volatile 禁止指令重排(避免多线程下拿到未初始化的实例)
private static volatile LazySingleton INSTANCE;
private LazySingleton() {}
public static LazySingleton getInstance() {
// 第一次判断:避免频繁加锁(提高性能)
if (INSTANCE == null) {
synchronized (LazySingleton.class) { // 类锁,保证线程安全
// 第二次判断:防止多个线程同时进入临界区后重复创建
if (INSTANCE == null) {
INSTANCE = new LazySingleton(); // 禁止指令重排
}
}
}
return INSTANCE;
}
}
// 3. 枚举式(最优方案:线程安全、防反射、防序列化,简洁)
enum EnumSingleton {
INSTANCE; // 唯一实例
// 可以添加自定义方法
public void doSomething() {
System.out.println("枚举单例执行操作");
}
}
// 测试:验证实例唯一性
public static void main(String[] args) {
// 饿汉式测试
HungrySingleton h1 = HungrySingleton.getInstance();
HungrySingleton h2 = HungrySingleton.getInstance();
System.out.println("饿汉式实例是否唯一:" + (h1 == h2)); // true
// 懒汉式测试
LazySingleton l1 = LazySingleton.getInstance();
LazySingleton l2 = LazySingleton.getInstance();
System.out.println("懒汉式实例是否唯一:" + (l1 == l2)); // true
// 枚举式测试
EnumSingleton e1 = EnumSingleton.INSTANCE;
EnumSingleton e2 = EnumSingleton.INSTANCE;
System.out.println("枚举式实例是否唯一:" + (e1 == e2)); // true
e1.doSomething();
}
}
优缺点与场景
- 饿汉式:优点(简单、线程安全),缺点(无延迟加载,浪费资源)→ 适合实例占用资源少的场景;
- 懒汉式(DCL):优点(延迟加载、线程安全),缺点(代码复杂)→ 适合实例占用资源多的场景;
- 枚举式:优点(线程安全、防反射破解、防序列化破解、代码简洁)→ 推荐优先使用。
2. 工厂方法模式(Factory Method)
理论部分
- 定义:定义一个「创建对象的接口」,但让子类决定「实例化哪个类」,将对象创建延迟到子类。
- 解决问题:避免简单工厂模式的「违背开闭原则」(新增产品需修改工厂类)。
- 核心思想:「工厂接口 + 具体工厂 + 产品接口 + 具体产品」,新增产品只需新增「具体产品类 + 具体工厂类」,无需修改原有代码。
- 对比简单工厂:简单工厂是「一个工厂造所有产品」,工厂方法是「一个工厂造一种产品」。
代码实现(场景:支付方式工厂)
java
运行
java
/**
* 工厂方法模式:支付方式场景
* 产品接口:Payment → 具体产品:Alipay、WechatPay → 工厂接口:PaymentFactory → 具体工厂:AlipayFactory、WechatPayFactory
*/
public class FactoryMethodDemo {
// 1. 产品接口(定义产品的统一行为)
interface Payment {
void pay(double amount); // 支付方法
}
// 2. 具体产品1:支付宝支付
static class Alipay implements Payment {
@Override
public void pay(double amount) {
System.out.println("使用支付宝支付:" + amount + "元");
}
}
// 3. 具体产品2:微信支付
static class WechatPay implements Payment {
@Override
public void pay(double amount) {
System.out.println("使用微信支付:" + amount + "元");
}
}
// 4. 工厂接口(定义创建产品的方法)
interface PaymentFactory {
Payment createPayment(); // 创建支付对象
}
// 5. 具体工厂1:支付宝工厂(造支付宝对象)
static class AlipayFactory implements PaymentFactory {
@Override
public Payment createPayment() {
return new Alipay();
}
}
// 6. 具体工厂2:微信支付工厂(造微信支付对象)
static class WechatPayFactory implements PaymentFactory {
@Override
public Payment createPayment() {
return new WechatPay();
}
}
// 测试
public static void main(String[] args) {
// 支付宝支付
PaymentFactory alipayFactory = new AlipayFactory();
Payment alipay = alipayFactory.createPayment();
alipay.pay(100);
// 微信支付
PaymentFactory wechatFactory = new WechatPayFactory();
Payment wechatPay = wechatFactory.createPayment();
wechatPay.pay(200);
// 新增产品(如银联支付):只需新增 UnionPay(产品)+ UnionPayFactory(工厂),无需修改原有代码
}
}
运行结果
plaintext
使用支付宝支付:100.0元
使用微信支付:200.0元
适用场景
- 产品种类较多,且后续可能新增产品(如支付方式、日志框架、数据库驱动);
- 希望将对象创建与使用解耦(调用方无需知道产品的创建细节)。
3. 建造者模式(Builder)
理论部分
- 定义:将复杂对象的「构建过程」与「表示」分离,使得同样的构建过程可以创建不同的表示。
- 解决问题:复杂对象的构造参数多(如 5 个以上),且部分参数可选,避免构造器参数过长( telescoping constructor 反模式)。
- 核心思想:「导演类(可选)+ 建造者接口 + 具体建造者 + 产品」,分步构建对象,最后统一返回。
代码实现(场景:构建电脑对象)
java
运行
java
/**
* 建造者模式:构建复杂对象(电脑)
* 产品:Computer → 建造者接口:ComputerBuilder → 具体建造者:GamingComputerBuilder、OfficeComputerBuilder → 导演类:ComputerDirector(可选)
*/
public class BuilderDemo {
// 1. 产品:电脑(复杂对象,有多个组件,部分可选)
static class Computer {
private String cpu; // 必选:CPU
private String ram; // 必选:内存
private String graphics; // 可选:显卡
private String hardDisk; // 可选:硬盘
private String keyboard; // 可选:键盘
// 私有化构造器,只能通过建造者创建
private Computer(Builder builder) {
this.cpu = builder.cpu;
this.ram = builder.ram;
this.graphics = builder.graphics;
this.hardDisk = builder.hardDisk;
this.keyboard = builder.keyboard;
}
// 2. 内部建造者类(常用简化写法,无需单独定义建造者接口)
public static class Builder {
// 必选参数(在构造器中强制传入)
private final String cpu;
private final String ram;
// 可选参数(默认值)
private String graphics = "集成显卡";
private String hardDisk = "512G SSD";
private String keyboard = "普通键盘";
// 构造器:接收必选参数
public Builder(String cpu, String ram) {
this.cpu = cpu;
this.ram = ram;
}
// 可选参数的 setter 方法(返回 Builder 自身,支持链式调用)
public Builder graphics(String graphics) {
this.graphics = graphics;
return this;
}
public Builder hardDisk(String hardDisk) {
this.hardDisk = hardDisk;
return this;
}
public Builder keyboard(String keyboard) {
this.keyboard = keyboard;
return this;
}
// 构建产品对象
public Computer build() {
return new Computer(this);
}
}
// toString 方法(方便打印)
@Override
public String toString() {
return "Computer{" +
"cpu='" + cpu + '\'' +
", ram='" + ram + '\'' +
", graphics='" + graphics + '\'' +
", hardDisk='" + hardDisk + '\'' +
", keyboard='" + keyboard + '\'' +
'}';
}
}
// 测试:链式构建电脑对象
public static void main(String[] args) {
// 构建游戏本(必选参数 + 自定义可选参数)
Computer gamingComputer = new Computer.Builder("Intel i9", "32G DDR5")
.graphics("NVIDIA RTX 4090")
.hardDisk("2TB SSD")
.keyboard("机械键盘")
.build();
System.out.println("游戏本:" + gamingComputer);
// 构建办公本(只传必选参数,使用默认可选参数)
Computer officeComputer = new Computer.Builder("AMD R7", "16G DDR4")
.build();
System.out.println("办公本:" + officeComputer);
}
}
运行结果
plaintext
游戏本:Computer{cpu='Intel i9', ram='32G DDR5', graphics='NVIDIA RTX 4090', hardDisk='2TB SSD', keyboard='机械键盘'}
办公本:Computer{cpu='AMD R7', ram='16G DDR4', graphics='集成显卡', hardDisk='512G SSD', keyboard='普通键盘'}
适用场景
- 复杂对象的构造参数多(必选 + 可选),如 POJO 类、配置类、实体类;
- 希望代码简洁,支持链式调用(如 Lombok 的
@Builder注解就是基于建造者模式)。
二、结构型模式(负责类 / 对象的组合,优化结构)
结构型模式专注于「如何组合类和对象」,实现更灵活的结构设计。
1. 代理模式(Proxy)
理论部分
- 定义:为其他对象提供一种「代理」,以控制对这个对象的访问。
- 解决问题:在不修改目标对象代码的前提下,增强目标对象的功能(如日志、缓存、权限校验)。
- 核心思想:「代理类 + 目标类」实现同一接口,代理类持有目标类引用,调用目标方法前后添加增强逻辑。
- 常用类型:静态代理(编译期生成代理类)、动态代理(运行时生成代理类,如 JDK 动态代理、CGLIB)。
代码实现(JDK 动态代理:日志增强)
JDK 动态代理依赖「接口 + 反射」,之前讲过反射底层,这里可以呼应:
java
运行
java
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* 代理模式:JDK 动态代理(日志增强)
* 目标接口:UserService → 目标类:UserServiceImpl → 代理类(运行时生成)→ InvocationHandler(增强逻辑)
*/
public class ProxyDemo {
// 1. 目标接口
interface UserService {
void addUser(String username);
void deleteUser(String username);
}
// 2. 目标类(真实业务逻辑)
static class UserServiceImpl implements UserService {
@Override
public void addUser(String username) {
System.out.println("执行核心业务:添加用户 " + username);
}
@Override
public void deleteUser(String username) {
System.out.println("执行核心业务:删除用户 " + username);
}
}
// 3. InvocationHandler(增强逻辑处理器,反射调用目标方法)
static class LogInvocationHandler implements InvocationHandler {
private Object target; // 持有目标对象引用
// 构造器:传入目标对象
public LogInvocationHandler(Object target) {
this.target = target;
}
// 代理方法:所有代理对象的方法调用都会走到这里(反射底层)
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 增强逻辑:方法执行前打印日志
System.out.println("日志增强:开始执行 " + method.getName() + " 方法,参数:" + args[0]);
// 反射调用目标对象的方法(核心:通过 Method.invoke 执行目标逻辑)
Object result = method.invoke(target, args);
// 增强逻辑:方法执行后打印日志
System.out.println("日志增强:" + method.getName() + " 方法执行完成\n");
return result;
}
}
// 4. 代理工厂(生成代理对象)
static class ProxyFactory {
// 生成代理对象(JDK 动态代理:只能代理接口)
public static Object getProxy(Object target) {
return Proxy.newProxyInstance(
target.getClass().getClassLoader(), // 类加载器
target.getClass().getInterfaces(), // 目标对象实现的接口(JDK 代理核心依赖)
new LogInvocationHandler(target) // 增强逻辑处理器
);
}
}
// 测试
public static void main(String[] args) {
// 1. 创建目标对象
UserService userService = new UserServiceImpl();
// 2. 生成代理对象(运行时通过反射动态生成代理类)
UserService proxy = (UserService) ProxyFactory.getProxy(userService);
// 3. 调用代理对象的方法(实际执行的是 InvocationHandler.invoke)
proxy.addUser("张三");
proxy.deleteUser("李四");
}
}
运行结果
plaintext
日志增强:开始执行 addUser 方法,参数:张三
执行核心业务:添加用户 张三
日志增强:addUser 方法执行完成
日志增强:开始执行 deleteUser 方法,参数:李四
执行核心业务:删除用户 李四
日志增强:deleteUser 方法执行完成
适用场景
- 日志记录、权限校验、缓存、事务管理(如 Spring AOP 的底层就是动态代理);
- 远程调用(如 RPC 框架,代理对象负责网络通信,目标对象负责本地业务)。
2. 装饰器模式(Decorator)
理论部分
- 定义:动态地给一个对象添加一些额外的职责,就像给房子刷漆、贴壁纸一样,不改变对象本身。
- 解决问题:避免使用继承导致的类爆炸(如 1 个基础类 + 3 个增强功能 = 7 个继承类,而装饰器只需 3 个装饰类)。
- 核心思想:「装饰器类 + 目标类」实现同一接口,装饰器类持有目标类引用,层层包装增强。
- 对比继承:继承是「静态增强」(编译期确定),装饰器是「动态增强」(运行时组合)。
代码实现(场景:饮料加配料)
java
运行
java
/**
* 装饰器模式:饮料加配料(动态增强)
* 目标接口:Beverage → 基础目标类:Coffee、Tea → 装饰器类:MilkDecorator、SugarDecorator
*/
public class DecoratorDemo {
// 1. 目标接口(饮料)
interface Beverage {
String getName(); // 饮料名称
double getPrice(); // 饮料价格
}
// 2. 基础目标类1:咖啡(无装饰)
static class Coffee implements Beverage {
@Override
public String getName() {
return "咖啡";
}
@Override
public double getPrice() {
return 15.0;
}
}
// 3. 基础目标类2:茶(无装饰)
static class Tea implements Beverage {
@Override
public String getName() {
return "茶";
}
@Override
public double getPrice() {
return 10.0;
}
}
// 4. 装饰器抽象类(实现 Beverage 接口,持有 Beverage 引用)
static abstract class BeverageDecorator implements Beverage {
protected Beverage beverage; // 持有被装饰的饮料对象
// 构造器:传入被装饰的对象
public BeverageDecorator(Beverage beverage) {
this.beverage = beverage;
}
}
// 5. 具体装饰器1:加牛奶
static class MilkDecorator extends BeverageDecorator {
public MilkDecorator(Beverage beverage) {
super(beverage);
}
@Override
public String getName() {
return beverage.getName() + " + 牛奶"; // 增强名称
}
@Override
public double getPrice() {
return beverage.getPrice() + 3.0; // 增强价格
}
}
// 6. 具体装饰器2:加糖
static class SugarDecorator extends BeverageDecorator {
public SugarDecorator(Beverage beverage) {
super(beverage);
}
@Override
public String getName() {
return beverage.getName() + " + 糖";
}
@Override
public double getPrice() {
return beverage.getPrice() + 1.0;
}
}
// 测试:动态组合装饰器
public static void main(String[] args) {
// 1. 基础咖啡(无装饰)
Beverage coffee = new Coffee();
System.out.println(coffee.getName() + ":" + coffee.getPrice() + "元");
// 2. 咖啡 + 牛奶(一层装饰)
Beverage coffeeWithMilk = new MilkDecorator(coffee);
System.out.println(coffeeWithMilk.getName() + ":" + coffeeWithMilk.getPrice() + "元");
// 3. 咖啡 + 牛奶 + 糖(两层装饰)
Beverage coffeeWithMilkAndSugar = new SugarDecorator(coffeeWithMilk);
System.out.println(coffeeWithMilkAndSugar.getName() + ":" + coffeeWithMilkAndSugar.getPrice() + "元");
// 4. 茶 + 糖(动态组合不同装饰)
Beverage teaWithSugar = new SugarDecorator(new Tea());
System.out.println(teaWithSugar.getName() + ":" + teaWithSugar.getPrice() + "元");
}
}
运行结果
plaintext
咖啡:15.0元
咖啡 + 牛奶:18.0元
咖啡 + 牛奶 + 糖:19.0元
茶 + 糖:11.0元
适用场景
- 需动态给对象添加 / 移除职责(如 IO 流:
BufferedInputStream装饰FileInputStream,增强缓存功能); - 增强功能较多,避免继承导致的类爆炸。
三、行为型模式(负责对象的交互,优化通信)
行为型模式专注于「对象之间的协作与通信」,让代码逻辑更清晰、更灵活。
1. 观察者模式(Observer)
理论部分
- 定义:定义对象之间的「一对多依赖」,当一个对象(被观察者)状态变化时,所有依赖它的对象(观察者)都会自动收到通知并更新。
- 解决问题:解耦「被观察者」和「观察者」,观察者的增减不影响被观察者。
- 核心思想:「被观察者(Subject)+ 观察者(Observer)」,被观察者维护观察者列表,状态变化时遍历通知。
代码实现(场景:公众号推送)
java
运行
java
import java.util.ArrayList;
import java.util.List;
/**
* 观察者模式:公众号推送(一对多通知)
* 被观察者:WechatOfficialAccount → 观察者:User → 通知机制:update 方法
*/
public class ObserverDemo {
// 1. 观察者接口(定义更新方法)
interface Observer {
void update(String message); // 接收通知并更新
}
// 2. 被观察者抽象类(维护观察者列表,提供注册/移除/通知方法)
abstract class Subject {
// 观察者列表
protected List<Observer> observers = new ArrayList<>();
// 注册观察者
public void registerObserver(Observer observer) {
observers.add(observer);
}
// 移除观察者
public void removeObserver(Observer observer) {
observers.remove(observer);
}
// 通知所有观察者(核心方法)
public abstract void notifyObservers(String message);
}
// 3. 具体被观察者:微信公众号
static class WechatOfficialAccount extends Subject {
private String name; // 公众号名称
public WechatOfficialAccount(String name) {
this.name = name;
}
// 发布文章(状态变化)
public void publishArticle(String article) {
System.out.println("\n" + name + " 发布了新文章:" + article);
notifyObservers(article); // 通知所有观察者
}
@Override
public void notifyObservers(String message) {
// 遍历所有观察者,发送通知
for (Observer observer : observers) {
observer.update(name + " 推送:" + message);
}
}
}
// 4. 具体观察者:用户
static class User implements Observer {
private String username;
public User(String username) {
this.username = username;
}
@Override
public void update(String message) {
System.out.println(username + " 收到通知:" + message);
}
}
// 测试
public static void main(String[] args) {
// 1. 创建被观察者(公众号)
WechatOfficialAccount account = new ObserverDemo().new WechatOfficialAccount("Java编程助手");
// 2. 创建观察者(用户)
Observer user1 = new User("张三");
Observer user2 = new User("李四");
Observer user3 = new User("王五");
// 3. 注册观察者(用户关注公众号)
account.registerObserver(user1);
account.registerObserver(user2);
account.registerObserver(user3);
// 4. 公众号发布文章(状态变化,通知所有用户)
account.publishArticle("Java设计模式实战教程");
// 5. 移除观察者(用户取消关注)
account.removeObserver(user2);
System.out.println("\n李四取消关注后,公众号再次发布文章:");
account.publishArticle("反射底层原理详解");
}
}
运行结果
plaintext
java
Java编程助手 发布了新文章:Java设计模式实战教程
张三 收到通知:Java编程助手 推送:Java设计模式实战教程
李四 收到通知:Java编程助手 推送:Java设计模式实战教程
王五 收到通知:Java编程助手 推送:Java设计模式实战教程
李四取消关注后,公众号再次发布文章:
Java编程助手 发布了新文章:反射底层原理详解
张三 收到通知:Java编程助手 推送:反射底层原理详解
王五 收到通知:Java编程助手 推送:反射底层原理详解
适用场景
- 事件驱动场景(如 GUI 按钮点击、消息队列通知、公众号推送、Spring 的
ApplicationEvent); - 一个对象状态变化需要联动多个对象更新。
2. 策略模式(Strategy)
理论部分
- 定义:定义一系列算法,将每个算法封装起来,并且使它们可以互相替换,让算法的变化独立于使用算法的客户。
- 解决问题 :避免大量
if-else或switch语句(如不同支付方式、不同排序算法)。 - 核心思想:「策略接口 + 具体策略 + 上下文类」,上下文类持有策略接口引用,动态切换策略。
代码实现(场景:不同排序算法)
java
运行
java
import java.util.Arrays;
import java.util.List;
/**
* 策略模式:排序算法(替换 if-else)
* 策略接口:SortStrategy → 具体策略:BubbleSort、QuickSort → 上下文类:Sorter(使用策略)
*/
public class StrategyDemo {
// 1. 策略接口(定义算法的统一行为)
interface SortStrategy {
List<Integer> sort(List<Integer> list);
}
// 2. 具体策略1:冒泡排序
static class BubbleSort implements SortStrategy {
@Override
public List<Integer> sort(List<Integer> list) {
Integer[] arr = list.toArray(new Integer[0]);
int n = arr.length;
for (int i = 0; i < n - 1; i++) {
for (int j = 0; j < n - 1 - i; j++) {
if (arr[j] > arr[j + 1]) {
// 交换
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
System.out.println("使用冒泡排序");
return Arrays.asList(arr);
}
}
// 3. 具体策略2:快速排序(简化版)
static class QuickSort implements SortStrategy {
@Override
public List<Integer> sort(List<Integer> list) {
Integer[] arr = list.toArray(new Integer[0]);
quickSort(arr, 0, arr.length - 1);
System.out.println("使用快速排序");
return Arrays.asList(arr);
}
private void quickSort(Integer[] arr, int low, int high) {
if (low < high) {
int pivot = partition(arr, low, high);
quickSort(arr, low, pivot - 1);
quickSort(arr, pivot + 1, high);
}
}
private int partition(Integer[] arr, int low, int high) {
int pivot = arr[high];
int i = low - 1;
for (int j = low; j < high; j++) {
if (arr[j] <= pivot) {
i++;
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
int temp = arr[i + 1];
arr[i + 1] = arr[high];
arr[high] = temp;
return i + 1;
}
}
// 4. 上下文类(使用策略的类,持有策略接口引用)
static class Sorter {
private SortStrategy strategy;
// 构造器:传入策略(也可通过 setter 动态切换)
public Sorter(SortStrategy strategy) {
this.strategy = strategy;
}
// 动态切换策略
public void setStrategy(SortStrategy strategy) {
this.strategy = strategy;
}
// 执行排序(委托给策略)
public List<Integer> sort(List<Integer> list) {
return strategy.sort(list);
}
}
// 测试
public static void main(String[] args) {
List<Integer> list = Arrays.asList(3, 1, 4, 1, 5, 9, 2, 6);
// 1. 使用冒泡排序策略
Sorter sorter = new Sorter(new BubbleSort());
List<Integer> bubbleSorted = sorter.sort(list);
System.out.println("冒泡排序结果:" + bubbleSorted);
// 2. 动态切换为快速排序策略
sorter.setStrategy(new QuickSort());
List<Integer> quickSorted = sorter.sort(list);
System.out.println("快速排序结果:" + quickSorted);
}
}
运行结果
plaintext
使用冒泡排序
冒泡排序结果:[1, 1, 2, 3, 4, 5, 6, 9]
使用快速排序
快速排序结果:[1, 1, 2, 3, 4, 5, 6, 9]
适用场景
- 有多种算法 / 逻辑可选(如支付方式、排序算法、日志输出方式);
- 代码中存在大量
if-else分支,且分支逻辑独立(如if (type == 1) 冒泡排序 else if (type == 2) 快速排序)。
四、设计模式核心总结
- 核心价值:解耦、复用、可维护、可扩展,遵循 SOLID 原则;
- 选择技巧 :
- 需控制对象创建 → 单例、工厂方法、建造者;
- 需优化类 / 对象组合 → 代理、装饰器、适配器;
- 需优化对象交互 → 观察者、策略、模板方法;
- 避坑点 :
- 不要过度设计:简单问题用简单代码,不要强行套用设计模式;
- 优先组合,而非继承:组合更灵活(如装饰器、策略模式);
- 理解模式的本质,而非代码模板:如代理模式的核心是「控制访问」,装饰器的核心是「动态增强」。