策略模式新人笔记

一:为什么需要策略模式

策略模式的核心价值是把 "做什么" 和 "怎么做" 分离开 ,解决代码中大量 if-else/switch 堆砌、逻辑耦合 的问题,让不同的实现方案(策略)可以灵活替换 ,且新增方案时不用修改原有代码(符合 "开闭原则")。

开闭原则(Open/Closed Principle,OCP)是面向对象设计的五大原则(SOLID) 中最核心的一条,它的核心定义是:软件实体(类、模块、函数等)应该对扩展开放(Open for extension) ,对修改关闭(Closed for modification)。

用一句大白话解释:当需要给程序新增功能时,尽量通过 "新增代码" 实现,而不是修改已有的、正在运行的代码
就像你买了一辆汽车

  • 对扩展开放:你可以给车加装座椅套、行车记录仪、后备箱收纳箱(新增功能,不用改汽车本身的核心部件);
  • 对修改关闭:你不会去拆发动机、改变速箱来实现 "增加储物空间"(核心代码不能动,避免引入 bug)。 可以用一个非常贴近生活的例子:出行上班
场景还原(无策略模式的糟糕情况)

假设你每天上班需要根据天气、时间选择出行方式,用代码模拟的话,没有策略模式时会写成这样:

java 复制代码
public class GoToWork {
    // 出行方法,塞满了if-else
    public void travel(String way, double distance) {
        if ("bus".equals(way)) {
            System.out.println("坐公交上班," + distance + "公里,耗时约" + (distance * 5) + "分钟,花费2元");
        } else if ("subway".equals(way)) {
            System.out.println("坐地铁上班," + distance + "公里,耗时约" + (distance * 2) + "分钟,花费4元");
        } else if ("bike".equals(way)) {
            System.out.println("骑共享单车上班," + distance + "公里,耗时约" + (distance * 8) + "分钟,花费1.5元");
        } else if ("car".equals(way)) {
            System.out.println("开私家车上班," + distance + "公里,耗时约" + (distance * 3) + "分钟,花费油费" + (distance * 0.8) + "元");
        } else {
            System.out.println("未知出行方式");
        }
    }

    public static void main(String[] args) {
        GoToWork person = new GoToWork();
        // 今天起晚了,选地铁
        person.travel("subway", 10);
        // 明天想省钱,选公交
        person.travel("bus", 10);
    }
}

问题暴露

  1. 新增出行方式(比如 "打车")时,必须修改 travel 方法,违反 "开闭原则";
  2. 所有出行逻辑都堆在一个方法里,代码臃肿、可读性差;
  3. 若某类出行方式的逻辑变了(比如公交涨价),需要修改核心方法,容易影响其他逻辑。
用策略模式重构

我们把 "出行" 这个核心行为(做什么),和 "公交 / 地铁 / 骑车" 这些具体实现(怎么做)分开

步骤 1:定义 "出行策略" 接口(统一的行为规范)
java 复制代码
// 出行策略接口(做什么:出行)
public interface TravelStrategy {
    // 计算耗时和花费的方法(统一的行为)
    void calculate(double distance);
}
步骤 2:实现不同的出行策略(怎么做:具体方式)
java 复制代码
// 公交策略
public class BusStrategy implements TravelStrategy {
    @Override
    public void calculate(double distance) {
        double time = distance * 5;
        double cost = 2;
        System.out.println("坐公交上班," + distance + "公里,耗时约" + time + "分钟,花费" + cost + "元");
    }
}

// 地铁策略
public class SubwayStrategy implements TravelStrategy {
    @Override
    public void calculate(double distance) {
        double time = distance * 2;
        double cost = 4;
        System.out.println("坐地铁上班," + distance + "公里,耗时约" + time + "分钟,花费" + cost + "元");
    }
}

// 骑车策略
public class BikeStrategy implements TravelStrategy {
    @Override
    public void calculate(double distance) {
        double time = distance * 8;
        double cost = 1.5;
        System.out.println("骑共享单车上班," + distance + "公里,耗时约" + time + "分钟,花费" + cost + "元");
    }
}
步骤 3:定义 "上下文"(使用策略的主体)
java 复制代码
// 上班的人(上下文,负责选择和使用策略)
public class Person {
    // 持有一个策略对象(可以动态替换)
    private TravelStrategy strategy;

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

    // 执行出行逻辑(只关心"出行",不关心"怎么出行")
    public void goToWork(double distance) {
        strategy.calculate(distance);
    }

    public static void main(String[] args) {
        Person person = new Person();
        // 周一起晚了,选地铁
        person.setStrategy(new SubwayStrategy());
        person.goToWork(10);
        
        // 周二想省钱,选公交
        person.setStrategy(new BusStrategy());
        person.goToWork(10);
        
        // 周三天气好,选骑车(新增策略后,原有代码一行不用改)
        person.setStrategy(new BikeStrategy());
        person.goToWork(5);
    }
}
运行结果
java 复制代码
坐地铁上班,10.0公里,耗时约20.0分钟,花费4.0元
坐公交上班,10.0公里,耗时约50.0分钟,花费2.0元
骑共享单车上班,5.0公里,耗时约40.0分钟,花费1.5元

二:什么是策略模式

1、先给一个通俗定义

策略模式(Strategy Pattern)是一种行为型设计模式 ,核心思想是:把完成某件事的 "多种不同方法 / 规则 / 算法"(即 "策略")封装成独立的类,让它们可以互相替换,且不影响使用这些策略的主逻辑

简单说,就是把 "选择做什么" 和 "具体怎么做" 彻底分开 ------ 主逻辑只负责 "选策略、用策略",而 "怎么做" 的细节都封装在各自的策略类里。

2、策略模式的核心角色(规范且缺一不可)

策略模式有 3 个固定的核心角色,每个角色都有明确的职责,遵循 "单一职责原则"

角色名称 英文名称 核心职责
1. 抽象策略(Strategy) Strategy 定义所有具体策略必须实现的统一接口 / 抽象类,规定策略的行为规范(方法)
2. 具体策略(Concrete Strategy) ConcreteStrategy 实现抽象策略接口,封装具体的算法 / 逻辑 / 规则(不同的 "怎么做")
3. 上下文(Context) Context 持有策略对象的引用,负责调用策略,可以理解为策略的"调度器"

3.结合我们上文的乘车例子

1. 抽象策略(Strategy)

角色定义 :定义所有策略共同的行为接口,规定 "要做什么"。

在出行例子里:共同行为:出行(计算耗时、花费)

java 复制代码
// 抽象策略:出行策略
public interface TravelStrategy {
    void calculate(double distance);
}

2. 具体策略(ConcreteStrategy)

角色定义 :实现抽象策略接口,每一个类就是一种具体算法 / 方案

对应:

  • BusStrategy 公交方案
  • SubwayStrategy 地铁方案
  • BikeStrategy 骑车方案
java 复制代码
// 具体策略1:公交
public class BusStrategy implements TravelStrategy {
    @Override
    public void calculate(double distance) {
        System.out.println("公交:耗时≈" + distance*5 + "分钟,花费2元");
    }
}

// 具体策略2:地铁
public class SubwayStrategy implements TravelStrategy {
    @Override
    public void calculate(double distance) {
        System.out.println("地铁:耗时≈" + distance*2 + "分钟,花费4元");
    }
}

// 具体策略3:骑车
public class BikeStrategy implements TravelStrategy {
    @Override
    public void calculate(double distance) {
        System.out.println("骑车:耗时≈" + distance*8 + "分钟,花费1.5元");
    }
}

3. 上下文(Context)

角色定义

  • 持有抽象策略的引用
  • 提供设置策略的方法
  • 提供执行策略的方法(给外部调用)

对应:人(Person) 去上班,人持有 "出行方式",并执行出行。

java 复制代码
// 上下文:人
public class Person {

    // 持有抽象策略(不持有具体类)
    private TravelStrategy travelStrategy;

    // 设置策略(动态切换)
    public void setTravelStrategy(TravelStrategy travelStrategy) {
        this.travelStrategy = travelStrategy;
    }

    // 执行策略(对外统一方法)
    public void goToWork(double distance) {
        if (travelStrategy == null) {
            System.out.println("还没选出行方式");
            return;
        }
        travelStrategy.calculate(distance);
    }
}

4、客户端怎么用
java 复制代码
public class Client {
    public static void main(String[] args) {
        //创建上下文,即策略调度器,将想要的策略告诉他,他会替我们执行策略
        Person person = new Person();

        // 选地铁
        person.setTravelStrategy(new SubwayStrategy());
        //执行上下文提供的执行策略的方法
        person.goToWork(10);

        // 切换成公交
        person.setTravelStrategy(new BusStrategy());
        person.goToWork(10);

        // 切换成骑车
        person.setTravelStrategy(new BikeStrategy());
        person.goToWork(5);
    }
}

4.再来具体讲解一下上下文

一、策略模式中 "上下文(Context)" 的核心定义

上下文是策略模式的核心调度者 ,它不负责实现具体的策略逻辑 ,而是承担 "连接客户端与策略" 的桥梁作用。简单说:

上下文 = 策略的 "持有者 + 调度者 + 封装者"(结合出行例子:Person 类就是上下文,人不关心公交 / 地铁怎么算耗时,只负责选策略、用策略)

二、上下文的核心职责(结合出行例子)
1. 持有抽象策略的引用(核心)
  • 上下文只能持有抽象策略接口 / 抽象类 的引用(如 TravelStrategy),而非具体策略(如 BusStrategy),这是依赖倒置原则的体现,避免耦合具体实现。

  • 代码示例(出行例子):

    java 复制代码
    public class Person {
        // 只持有抽象策略,不耦合具体策略
        private TravelStrategy travelStrategy; 
        // ...
    }
2. 提供策略的 "设置 / 切换" 方法
  • 允许客户端在运行时动态更换策略(比如上班途中临时换出行方式),这是策略模式 "灵活替换" 的关键。

  • 代码示例:

    java 复制代码
    public class Person {
        // 动态设置/切换策略
        public void setTravelStrategy(TravelStrategy travelStrategy) {
            this.travelStrategy = travelStrategy;
        }
        // ...
    }
3. 封装策略的执行逻辑(对外提供统一接口)
  • 上下文会封装策略的调用过程 ,还可在执行策略前后添加公共逻辑(如参数校验、日志、异常处理),让具体策略只关注核心逻辑。

  • 代码示例(优化后的 Person 类,增加公共逻辑):

    java 复制代码
    public class Person {
        private TravelStrategy travelStrategy;
    
        public void setTravelStrategy(TravelStrategy travelStrategy) {
            this.travelStrategy = travelStrategy;
        }
    
        // 封装执行逻辑,添加公共处理
        public void goToWork(double distance) {
            // 公共逻辑1:参数校验
            if (distance <= 0) {
                System.out.println("错误:距离必须大于0!");
                return;
            }
            // 公共逻辑2:前置日志
            System.out.println("开始规划上班路线,距离:" + distance + "公里");
            
            // 核心:调用策略逻辑
            if (travelStrategy != null) {
                travelStrategy.calculate(distance);
            } else {
                System.out.println("未选择出行方式!");
            }
            
            // 公共逻辑3:后置处理
            System.out.println("路线规划完成\n");
        }
    }
4.封装策略的 "选择逻辑"(引入策略工厂)
java 复制代码
// 1. 抽象策略
public interface TravelStrategy {
    void calculate(double distance);
}

// 2. 具体策略(公交)
public class BusStrategy implements TravelStrategy {
    @Override
    public void calculate(double distance) {
        System.out.println("公交:耗时≈" + distance*5 + "分钟,花费2元");
    }
}

// 3. 策略工厂
public class TravelStrategyFactory {
    public static TravelStrategy getStrategy(String scene) {
        return switch (scene) {
            case "赶时间" -> new SubwayStrategy();
            case "省钱" -> new BusStrategy();
            case "健身" -> new BikeStrategy();
            default -> throw new IllegalArgumentException("无此场景策略");
        };
    }
}

// 4. 上下文(核心)
public class Person {
    private TravelStrategy travelStrategy;

    // 结合工厂选择策略
    public void chooseStrategyByScene(String scene) {
        this.travelStrategy = TravelStrategyFactory.getStrategy(scene);
    }

    // 封装执行逻辑(含公共处理)
    public void goToWork(double distance) {
        if (distance <= 0) {
            System.out.println("错误:距离必须大于0!");
            return;
        }
        System.out.println("开始规划上班路线,距离:" + distance + "公里");
        if (travelStrategy != null) {
            travelStrategy.calculate(distance);
        } else {
            System.out.println("未选择出行方式!");
        }
        System.out.println("路线规划完成\n");
    }
}

// 5. 客户端
public class Client {
    public static void main(String[] args) {
        Person person = new Person();
        // 选"赶时间"场景,上下文自动选地铁策略
        person.chooseStrategyByScene("赶时间");
        person.goToWork(10);
        
        // 切换为"省钱"场景,自动选公交策略
        person.chooseStrategyByScene("省钱");
        person.goToWork(10);
    }
}

这里我们是上下文结合策略工厂的实现类型,我们的客户端不直接new一个策略对象,交给上下文,而是客户端将想调用的策略告诉上下文,上下文內部调用策略工厂生产策略对象,客户端通过上下文提供的goToWork方法执行策略

为什么要引入策略工厂

策略工厂不是策略模式的 "必须项",但却是真实项目中优化策略模式的 "刚需项" ------ 它解决了策略模式直接使用时的两个核心痛点,结合出行例子讲最直观:

痛点 1:客户端直接 new 具体策略,耦合度高

没有工厂时,客户端代码是这样的:

java 复制代码
// 客户端
public class Client {
    public static void main(String[] args) {
        Person person = new Person();
        // 客户端必须知道所有具体策略类的名字,耦合严重
        person.setTravelStrategy(new SubwayStrategy()); 
        person.setTravelStrategy(new BusStrategy());
        person.setTravelStrategy(new BikeStrategy());
    }
}

问题

  • 客户端要硬编码所有具体策略类(如 SubwayStrategy),一旦策略类名修改、或新增 / 删除策略,所有客户端代码都要改;
  • 若策略创建逻辑复杂(比如初始化时需要传参数、读配置),这些逻辑会散落在所有客户端里,难以维护。
痛点 2:策略选择逻辑散落在客户端,代码冗余

如果需要根据 "场景" 选策略(比如 "赶时间" 选地铁、"省钱" 选公交),没有工厂时,选择逻辑会写在客户端:

java 复制代码
// 客户端堆满策略选择的if-else,冗余且难维护
public class Client {
    public static void main(String[] args) {
        Person person = new Person();
        String scene = "赶时间";
        
        if ("赶时间".equals(scene)) {
            person.setTravelStrategy(new SubwayStrategy());
        } else if ("省钱".equals(scene)) {
            person.setTravelStrategy(new BusStrategy());
        } else if ("健身".equals(scene)) {
            person.setTravelStrategy(new BikeStrategy());
        }
    }
}

问题

  • 若有 10 个客户端(比如手机端、PC 端、小程序端),这堆 if-else 要复制 10 遍,改一处要改 10 处;
  • 策略选择逻辑和客户端业务逻辑混在一起,违反 "单一职责原则"。

策略工厂的本质是把 "策略的创建 + 选择逻辑" 集中封装,让客户端只关注 "用什么策略",不用关注 "怎么创建 / 怎么选"。

价值 1:解耦客户端与具体策略类

客户端只需传 "标识 / 场景"(如 "赶时间"),不用知道具体策略类名,即使策略类改名 / 新增,客户端代码完全不用改:

java 复制代码
// 有工厂后的客户端(极简)
public class Client {
    public static void main(String[] args) {
        Person person = new Person();
        // 客户端只传场景,不用知道SubwayStrategy的存在
        TravelStrategy strategy = TravelStrategyFactory.getStrategy("赶时间");
        person.setTravelStrategy(strategy);
        person.goToWork(10);
    }
}
价值 2:集中管理策略选择逻辑,避免冗余

所有 if-else/switch 都集中在工厂里,改策略选择规则只需改工厂,所有客户端自动生效:

java 复制代码
// 策略工厂(集中管理创建+选择)
public class TravelStrategyFactory {
    // 所有选择逻辑都在这,改一处全生效
    public static TravelStrategy getStrategy(String scene) {
        return switch (scene) {
            case "赶时间" -> new SubwayStrategy();
            case "省钱" -> new BusStrategy();
            case "健身" -> new BikeStrategy();
            // 新增策略只需加一行,客户端无感知
            case "下雨" -> new TaxiStrategy();
            default -> throw new IllegalArgumentException("无此场景策略:" + scene);
        };
    }
}
价值 3:封装复杂的策略创建逻辑

如果策略创建需要初始化参数、读配置、甚至依赖其他对象,工厂可以封装这些细节,客户端无需关心:

java 复制代码
// 工厂封装复杂创建逻辑(比如公交策略需要读票价配置)
public class TravelStrategyFactory {
    public static TravelStrategy getStrategy(String scene) {
        if ("省钱".equals(scene)) {
            // 从配置读取公交票价,客户端完全不用知道
            double busFare = ConfigReader.getBusFare();
            return new BusStrategy(busFare); // 带参数的策略构造
        }
        // 其他策略...
    }
}
价值 4:方便扩展与维护
  • 新增策略:只需加一个具体策略类 + 工厂里加一行 case,无其他改动;
  • 删除策略:只需在工厂里注释掉对应 case,客户端传该场景会抛异常,便于排查;
  • 改策略逻辑:只需改具体策略类,工厂和客户端都不用动。

三:策略模式的其他用法

一、策略模式的进阶优化
1. 策略工厂:解决客户端频繁 new 具体策略的问题

客户端直接 new SubwayStrategy() 会耦合具体策略类,可通过简单工厂封装策略选择逻辑:

java 复制代码
// 出行策略工厂(统一创建策略对象)
public class TravelStrategyFactory {
    // 根据出行方式名称获取对应策略
    public static TravelStrategy getStrategy(String way) {
        return switch (way) {
            case "bus" -> new BusStrategy();
            case "subway" -> new SubwayStrategy();
            case "bike" -> new BikeStrategy();
            default -> throw new IllegalArgumentException("无此出行方式:" + way);
        };
    }
}

// 客户端优化后用法
public class Client {
    public static void main(String[] args) {
        Person person = new Person();
        // 只需传名称,无需直接new具体策略
        person.setTravelStrategy(TravelStrategyFactory.getStrategy("subway"));
        person.goToWork(10);
        
        person.setTravelStrategy(TravelStrategyFactory.getStrategy("bus"));
        person.goToWork(10);
    }
}

优势:策略创建逻辑集中管理,客户端只需关注 "选什么",不用关注 "怎么创建"。

这一点类似于我们的封装策略的 "选择逻辑"(引入策略工厂) 章节的讲解,但是这里我们是客户端手动创建策略工厂,将生产的策略对象交给上下文

2. 策略模式 + 枚举:简化策略标识与创建

用枚举替代字符串标识出行方式,避免拼写错误:

java 复制代码
// 出行方式枚举类,提前定义所有的可用策略
public enum TravelWay {
    BUS, SUBWAY, BIKE;

    // 枚举关联对应策略
    public TravelStrategy getStrategy() {
        return switch (this) {
            case BUS -> new BusStrategy();
            case SUBWAY -> new SubwayStrategy();
            case BIKE -> new BikeStrategy();
        };
    }
}

// 客户端用法
public class Client {
    public static void main(String[] args) {
        Person person = new Person();
        // 用枚举选策略,无拼写错误风险
        person.setTravelStrategy(TravelWay.SUBWAY.getStrategy());
        person.goToWork(10);
    }
}

这里引入枚举类,好处是我们提前将所有策略都定义在一个枚举类,用户可以直接从枚举类中选择策略,而不需要手动传入,避免用户输入出现语法错误,比如策略"Train",用户输入成"Tain",导致策略工厂无法根据策略生成对应的策略类,同时枚举类还能起到统一管理各种变量的作用,具体有以下原因

  1. 编译期校验,杜绝非法值(最核心)

枚举的取值是固定的(比如 HURRY_UP/SAVE_MONEY/KEEP_FIT),客户端只能选预定义的值,拼错 / 传错会直接编译报错,根本到不了运行时:

java 复制代码
// 枚举定义(限定所有合法场景)
public enum TravelScene {
    HURRY_UP,   // 赶时间
    SAVE_MONEY, // 省钱
    KEEP_FIT    // 健身
}

// 工厂改造(参数为枚举,而非字符串)
public class TravelStrategyFactory {
    public static TravelStrategy getStrategy(TravelScene scene) {
        return switch (scene) {
            case HURRY_UP -> new SubwayStrategy();
            case SAVE_MONEY -> new BusStrategy();
            case KEEP_FIT -> new BikeStrategy();
        };
    }
}

// 客户端使用:
// ✅ 正确写法:编译通过
TravelStrategy s1 = TravelStrategyFactory.getStrategy(TravelScene.HURRY_UP);
// ❌ 错误写法:编译直接报错(找不到HURRYUP这个枚举值)
TravelStrategy s2 = TravelStrategyFactory.getStrategy(TravelScene.HURRYUP);

效果:把 "运行时才发现的错误" 提前到 "编译期拦截",大幅降低线上 bug。

  1. 代码可读性提升,语义更清晰

枚举值是 "见名知意" 的常量(比如 HURRY_UP 比字符串 "赶时间" 更符合编程规范),且 IDE 会自动提示所有可选值,新人不用翻文档 / 源码:

java 复制代码
// 用枚举:一眼看懂是"赶时间"场景
person.chooseStrategy(TravelScene.HURRY_UP);
// 用字符串:要确认"赶时间"是不是工厂支持的写法
person.chooseStrategy("赶时间");
  1. 集中管理策略标识,避免取值混乱

所有策略标识都集中在枚举类里,新增 / 修改场景只需改枚举,所有客户端自动同步:

java 复制代码
// 新增"下雨"场景:只需在枚举里加一行
public enum TravelScene {
    HURRY_UP,   // 赶时间
    SAVE_MONEY, // 省钱
    KEEP_FIT,   // 健身
    RAINY_DAY   // 下雨(新增)
}

四、策略模式的适用场景

一、核心使用场景

特征 1:同一行为有多种不同的实现方案,且需动态切换
  • 核心判断:"做什么" 固定,但 "怎么做" 有多种选择,且运行时可能根据条件换方案。

  • 典型例子:

    1. 出行场景(核心案例):上班的 "出行行为" 固定,但公交 / 地铁 / 骑车 / 打车是不同实现,可根据天气、时间动态切换;
    2. 支付场景:电商下单的 "支付行为" 固定,微信 / 支付宝 / 银行卡 / 花呗是不同实现,用户可自选;
    3. 排序场景:"排序行为" 固定,冒泡 / 快排 / 归并 / 希尔排序是不同实现,可根据数据量大小动态选(小数据用冒泡,大数据用快排);
    4. 日志输出场景:"日志记录行为" 固定,控制台 / 文件 / 数据库 / ELK 是不同实现,可根据环境(开发 / 生产)切换。
特征 2:代码中出现大量 if-else/switch 选择不同逻辑
  • 核心判断:一个方法里堆满 if (type == A) { ... } else if (type == B) { ... },且每个分支逻辑独立、可拆分。

  • 反例(需要重构)

    java 复制代码
    // 支付逻辑堆满if-else,符合策略模式使用场景
    public void pay(String type, double amount) {
        if ("wechat".equals(type)) {
            // 微信支付逻辑
        } else if ("alipay".equals(type)) {
            // 支付宝支付逻辑
        } else if ("card".equals(type)) {
            // 银行卡支付逻辑
        }
    }
  • 重构后:把每种支付逻辑拆成 WechatPayStrategy/AlipayPayStrategy,用策略模式消除 if-else。

特征 3:新增 / 修改实现方案时,不想改动原有核心代码(符合开闭原则)
  • 核心判断:新增功能(比如新增 "打车" 出行方式、"花呗" 支付方式)时,希望只加新类,不修改原有逻辑。
  • 典型例子:电商促销系统:"计算优惠" 行为固定,满减 / 折扣 / 满赠 / 无优惠是不同实现,双十一新增 "跨店满减" 策略时,只需加 CrossShopDiscountStrategy,原有代码一行不改。
特征 4:不同实现方案的核心逻辑独立,且有统一的行为规范
  • 核心判断:所有实现方案都能抽象出一个统一的接口(比如 TravelStrategycalculate()PaymentStrategypay())。
  • 反例(不适合):如果不同实现的方法签名、返回值都不一样(比如 A 方案返回布尔值,B 方案返回字符串),无法抽象统一接口,就不适合用策略模式。
相关推荐
我叫黑大帅2 小时前
php 如何使用mysqli连接mysql
后端·面试·php
strayCat232552 小时前
4. Spring Boot 数据持久化(JPA)
java·spring boot·后端
杰杰7982 小时前
一文掌握在Flask使用SQLAlchemy(上)
后端·python·flask
Rabbit_QL2 小时前
[Token实战]Flask JWT 登录接口
后端·python·flask
荧焰2 小时前
Spring定时任务设计
后端
strayCat232552 小时前
2. Spring Boot 自动配置原理深度解析
java·spring boot·后端
SimonKing2 小时前
每月500 Credits+不限频对话,这款IDEA插件的免费版诚意拉满
java·后端·程序员
我叫黑大帅2 小时前
PHP mysqli 实用开发指南
后端·面试·php
polaris06302 小时前
Spring Boot 集成 MyBatis 全面讲解
spring boot·后端·mybatis