当前位置: 首页 > news >正文

策略模式 + 工厂模式

策略模式:

简单来说解决的行为的封装与选择。如HandlerMapping,将 HTTP 请求映射到对应的处理器(Controller 或方法)。

工厂模式:

解决的是具有相同属性的对象创建问题,如BeanFactory创建bean对象。

解决的代码问题:

// 1. 定义具体支付类,但没有统一的接口
public class Alipay {public void pay(double amount) {System.out.println("使用支付宝支付:" + amount + "元");// 调用支付宝SDK的具体逻辑}
}public class WechatPay {public void executePayment(double amount) { // 方法名都不统一System.out.println("使用微信支付:" + amount + "元");// 调用微信支付SDK的具体逻辑}
}// 2. 客户端代码直接创建具体对象并调用
public class PaymentService {public void processPayment(String paymentType, double amount) {if ("alipay".equalsIgnoreCase(paymentType)) {Alipay alipay = new Alipay(); // 直接依赖具体类Alipayalipay.pay(amount);} else if ("wechat".equalsIgnoreCase(paymentType)) {WechatPay wechatPay = new WechatPay(); // 直接依赖具体类WechatPaywechatPay.executePayment(amount); // 方法名不统一,增加使用难度} else {throw new IllegalArgumentException("不支持的支付方式");}// 如果日后要为Alipay的创建增加缓存、初始化等复杂逻辑,这里会变得臃肿}
}// 3. 另一个服务也可能需要创建支付对象,导致代码重复
public class OrderService {public void createOrder(String paymentType) {// ... 订单创建逻辑// 又一套if-else来判断支付类型并创建对象if ("alipay".equalsIgnoreCase(paymentType)) {Alipay alipay = new Alipay(); // 创建逻辑重复// ... 可能还有其他操作} else if ("wechat".equalsIgnoreCase(paymentType)) {WechatPay wechatPay = new WechatPay();// ...}}
}

问题:

  • 高耦合(Tight Coupling)​​:PaymentServiceOrderService等客户端代码直接依赖具体的支付类(Alipay, WechatPay)。一旦这些具体类发生变化(如构造函数改变),所有创建它们的地方都需要修改

  • 违反开闭原则(Violates Open/Closed Principle)​​:当需要增加一个新的支付方式(如UnionPay银联支付)时,​必须修改所有包含支付类型判断 if-else分支的客户端代码(如 PaymentService, OrderService)。这使得系统难以扩展,也容易在修改时引入错误

  • 代码重复(Code Duplication)​​:对象的创建逻辑分散在应用程序的多个地方。如果创建过程很复杂(例如需要配置密钥、初始化连接等),这些重复的代码会难以维护

  • 可读性和可维护性差(Poor Readability and Maintainability)​​:客户端代码中充斥着具体的实例化操作和类型判断,​掩盖了核心的业务逻辑,使得代码难以理解和维护

  • 难以测试(Hard to Test)​​:由于客户端直接实例化具体对象,在进行单元测试时,很难模拟(Mock)​​ 这些依赖,从而难以隔离测试目标单元

策略模式解决的代码问题:

// ❌ 未使用策略模式的支付处理函数 - 圈复杂度高,难以维护
public class PaymentService {public void processPayment(String paymentType, double amount) {if ("alipay".equalsIgnoreCase(paymentType)) {System.out.println("调用支付宝SDK,支付¥" + amount);// 实际的支付宝支付逻辑,可能很复杂,包括参数组装、加密、调用网关等} else if ("wechat".equalsIgnoreCase(paymentType)) {System.out.println("调用微信支付SDK,支付¥" + amount);// 实际的微信支付逻辑} else if ("creditCard".equalsIgnoreCase(paymentType)) {System.out.println("调用银联接口,支付¥" + amount);// 实际的信用卡支付逻辑,可能包括卡号验证、有效期检查、3D认证等} else if ("applePay".equalsIgnoreCase(paymentType)) {System.out.println("调用Apple Pay API,支付¥" + amount);// 实际的Apple Pay支付逻辑} else {throw new IllegalArgumentException("不支持的支付方式: " + paymentType);}// 未来新增一种支付方式(如数字货币),就必须修改这个函数,增加一个else if分支}
}

问题:

  • 违反开闭原则​:每当需要增加一种新的支付方式(例如 unionPay(银联)或 digitalCurrency(数字货币)),你都必须修改这个 processPayment函数的内部逻辑,增加一个新的 else if分支。这违反了面向对象设计原则中的“对扩展开放,对修改关闭”的原则。

  • 代码臃肿,可读性差​:所有的支付逻辑都堆积在一个方法里。如果每种支付方式的逻辑都很复杂(例如涉及不同的参数组装、加密算法、第三方API调用),这个方法会变得非常长,难以阅读和理解。

  • 可维护性低​:不同支付方式的逻辑相互纠缠。修改一种支付方式的逻辑时,可能会无意中影响到其他支付方式的代码(虽然逻辑上独立,但物理上靠近,容易误触)。调试时也需要在这个庞大的函数中一步步跟踪。

  • 难以测试​:要为这个 processPayment方法编写单元测试,你需要覆盖所有的 if-else分支,测试用例会又长又复杂。你很难模拟(Mock)各种支付方式的具体实现,因为它们都紧耦合在这个方法里。

  • 重复代码​:如果其他业务逻辑(如退款、查询订单)也需要根据支付类型进行类似的判断,那么同样的 if-else语句可能会散布在代码库的多个地方,导致代码重复。

正确的使用样例步骤:

  1. 定义策略接口,策略接口共同方法
  2. 实现策略接口的具体实现类
  3. 定义工厂类,并设置缓存map(键为策略类型(即Bean名称),值为对应的策略实例)
  4. 可设置监控,控制策略的注册

策略接口

package com.luojie.strategy;/*** 支付策略接口* <p>* 这是策略模式的核心接口,定义了所有支付策略必须实现的共同方法。* 通过这个接口,不同的支付方式可以被统一对待,实现了策略的封装和替换。* </p>* <p>* 在策略模式中,这个接口扮演了"策略"角色,定义了算法族的共同接口,* 任何具体的支付方式都需要实现这个接口,提供自己的支付逻辑。* </p>*/
public interface PaymentStrategy {/*** 支付方法* <p>* 所有支付策略都必须实现的核心方法,用于执行具体的支付操作。* 不同的支付策略(如支付宝、微信支付、银联支付)会提供各自不同的实现。* </p>* @param amount 支付金额,使用double类型表示* @return 支付结果,返回一个描述支付过程的字符串信息*/String pay(double amount);
}

策略实现类--支付宝

package com.luojie.strategy;import org.springframework.stereotype.Component;/*** 支付宝支付策略实现* <p>* 这是支付策略接口的具体实现类,专门处理支付宝支付逻辑。* 在策略模式中,这个类扮演了"具体策略"角色,实现了策略接口定义的算法。* </p>* <p>* 通过Spring的@Component注解将该类标记为Spring组件,* 并指定Bean名称为"alipay",这样策略工厂可以通过这个名称来获取该策略实例。* </p>*/
@Component("alipay")  // 将该策略注册为Spring Bean,名称为"alipay"
public class AlipayStrategy implements PaymentStrategy {/*** 实现支付宝支付逻辑* <p>* 该方法提供了使用支付宝进行支付的具体实现。* 在实际应用中,这里会包含与支付宝API交互的代码,* 如构建支付请求、调用支付宝SDK、处理支付结果等。* </p>* <p>* 当前示例为了演示策略模式的基本结构,使用了简化的实现,* 仅返回一个描述支付过程的字符串。* </p>* @param amount 支付金额* @return 支付结果描述*/@Overridepublic String pay(double amount) {// 实际应用中,这里会包含真实的支付宝支付逻辑// 例如调用支付宝API、处理支付请求等return "使用支付宝支付了" + amount + "元";}
}

策略实现类--银联支付

package com.luojie.strategy;import org.springframework.stereotype.Component;/*** 银联支付策略实现* <p>* 这是支付策略接口的具体实现类,专门处理银联支付逻辑。* 在策略模式中,这个类扮演了"具体策略"角色,实现了策略接口定义的算法。* </p>* <p>* 通过Spring的@Component注解将该类标记为Spring组件,* 并指定Bean名称为"unionPay",这样策略工厂可以通过这个名称来获取该策略实例。* </p>*/
@Component("unionPay")  // 将该策略注册为Spring Bean,名称为"unionPay"
public class UnionPayStrategy implements PaymentStrategy {/*** 实现银联支付逻辑* <p>* 该方法提供了使用银联支付进行支付的具体实现。* 在实际应用中,这里会包含与银联支付API交互的代码,* 如构建支付请求、调用银联支付SDK、处理支付结果等。* </p>* <p>* 当前示例为了演示策略模式的基本结构,使用了简化的实现,* 仅返回一个描述支付过程的字符串。* </p>* @param amount 支付金额* @return 支付结果描述*/@Overridepublic String pay(double amount) {// 实际应用中,这里会包含真实的银联支付逻辑// 例如调用银联支付API、处理支付请求等return "使用银联支付了" + amount + "元";}
}

策略实现类--微信支付

package com.luojie.strategy;import org.springframework.stereotype.Component;/*** 微信支付策略实现* <p>* 这是支付策略接口的具体实现类,专门处理微信支付逻辑。* 在策略模式中,这个类扮演了"具体策略"角色,实现了策略接口定义的算法。* </p>* <p>* 通过Spring的@Component注解将该类标记为Spring组件,* 并指定Bean名称为"wechatPay",这样策略工厂可以通过这个名称来获取该策略实例。* </p>*/
@Component("wechatPay")  // 将该策略注册为Spring Bean,名称为"wechatPay"
public class WechatPayStrategy implements PaymentStrategy {/*** 实现微信支付逻辑* <p>* 该方法提供了使用微信支付进行支付的具体实现。* 在实际应用中,这里会包含与微信支付API交互的代码,* 如构建支付请求、调用微信支付SDK、处理支付结果等。* </p>* <p>* 当前示例为了演示策略模式的基本结构,使用了简化的实现,* 仅返回一个描述支付过程的字符串。* </p>* @param amount 支付金额* @return 支付结果描述*/@Overridepublic String pay(double amount) {// 实际应用中,这里会包含真实的微信支付逻辑// 例如调用微信支付API、处理支付请求等return "使用微信支付了" + amount + "元";}
}

工厂类

package com.luojie.strategy;import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;import com.luojie.config.StrategyConfig.StrategyConfigurationInfo;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;/*** 支付策略工厂* <p>* 这是工厂模式与策略模式结合使用的核心类,负责管理和提供各种支付策略实例。* 在策略模式中,这个类扮演了"策略选择器"的角色,客户端通过工厂来获取具体策略,* 而不需要直接实例化具体策略类,从而实现了客户端与具体策略的解耦。* </p>* <p>* 通过Spring的依赖注入机制和StrategyConfigurationInfo配置,该工厂能够根据配置* 决定是否自动收集所有实现了PaymentStrategy接口的Bean,提供了更灵活的策略管理方式。* </p>*/
@Component  // 注册为Spring组件,使其能够被自动发现和注入
public class PaymentStrategyFactory {// 日志记录器,用于记录工厂的操作日志private static final Logger logger = LoggerFactory.getLogger(PaymentStrategyFactory.class);// 使用ConcurrentHashMap存储所有策略实现,保证线程安全// 键为策略类型(即Bean名称),值为对应的策略实例private final Map<String, PaymentStrategy> strategyMap = new ConcurrentHashMap<>();// 注入策略配置信息,用于控制策略的自动注册行为private final StrategyConfigurationInfo configInfo;/*** 构造函数,注入策略配置信息和所有策略实现* <p>* 根据StrategyConfigurationInfo中的autoRegisterStrategies配置决定是否自动注册所有策略。* 这样可以灵活控制策略的管理方式。* </p>* @param strategyMap 包含所有策略实现的Map,由Spring自动注入* @param configInfo 策略配置信息,控制自动注册行为*/@Autowiredpublic PaymentStrategyFactory(Map<String, PaymentStrategy> strategyMap, StrategyConfigurationInfo configInfo) {this.configInfo = configInfo;// 根据配置决定是否自动注册所有策略if (configInfo != null && configInfo.isAutoRegisterStrategies()) {this.strategyMap.putAll(strategyMap);// 记录策略注册信息,便于调试和监控logger.info("支付策略工厂初始化完成,共自动加载了{}种支付策略", strategyMap.size());logger.info("已加载的支付策略类型:{}", strategyMap.keySet());} else {logger.info("支付策略工厂初始化完成,策略自动注册功能已禁用");}}/*** 手动注册支付策略* <p>* 当autoRegisterStrategies设置为false时,可以通过此方法手动注册策略。* 这提供了更精细的策略管理控制。* </p>* @param strategyType 策略类型(唯一标识符)* @param strategy 策略实现实例* @return 当前工厂实例,支持链式调用*/public PaymentStrategyFactory registerStrategy(String strategyType, PaymentStrategy strategy) {if (strategyType == null || strategy == null) {logger.error("注册策略失败:策略类型或策略实例不能为空");throw new IllegalArgumentException("策略类型或策略实例不能为空");}strategyMap.put(strategyType, strategy);logger.info("手动注册支付策略成功:{}", strategyType);return this;}/*** 移除已注册的支付策略* <p>* 提供移除策略的功能,便于动态调整可用的支付方式。* </p>* @param strategyType 要移除的策略类型* @return 被移除的策略实例,如果不存在则返回null*/public PaymentStrategy unregisterStrategy(String strategyType) {PaymentStrategy removedStrategy = strategyMap.remove(strategyType);if (removedStrategy != null) {logger.info("移除支付策略成功:{}", strategyType);}return removedStrategy;}/*** 根据策略类型获取对应的策略实现* <p>* 这是工厂的核心方法,用于根据客户端提供的策略类型,返回对应的策略实例。* 客户端只需要知道策略类型(如"alipay"、"wechatPay"等),* 不需要知道具体的策略实现类,从而实现了客户端与具体策略的解耦。* </p>* @param strategyType 策略类型(即Bean名称)* @return 对应的策略实现实例* @throws IllegalArgumentException 如果请求的策略类型不存在*/public PaymentStrategy getStrategy(String strategyType) {// 日志记录请求的策略类型logger.debug("请求获取支付策略:{}", strategyType);// 从Map中获取对应的策略实现PaymentStrategy strategy = strategyMap.get(strategyType);// 如果策略不存在,抛出异常if (strategy == null) {logger.error("不支持的支付方式:{}", strategyType);throw new IllegalArgumentException("不支持的支付方式:" + strategyType);}// 返回获取到的策略实例logger.debug("成功获取支付策略:{},对应的实现类:{}", strategyType, strategy.getClass().getSimpleName());return strategy;}
}

扩展的控制类

package com.luojie.config;import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;/*** 策略模式配置类* <p>* 该类是整个策略模式实现的核心配置类,主要负责:* 1. 启用策略包的组件扫描* 2. 配置策略监控机制* 3. 提供策略配置信息管理* <p>* 通过Spring的@Configuration注解标记为配置类,确保在Spring Boot应用启动时被自动加载* </p>*/
@Configuration
// 主组件扫描由Spring Boot自动处理,这里使用StrategyConfigurationInfo中的packageToScan进行更灵活的配置
// @ComponentScan注解本身不支持动态路径,但我们在后续的BeanPostProcessor中使用packageToScan参数
public class StrategyConfig {// 日志记录器,使用SLF4J框架记录配置和监控信息private static final Logger logger = LoggerFactory.getLogger(StrategyConfig.class);/*** 构造函数,用于记录配置类初始化信息* <p>* 在配置类实例化时记录初始化日志,便于跟踪系统启动过程中的策略模式初始化状态* </p>*/public StrategyConfig() {logger.info("策略模式配置类[StrategyConfig]初始化完成");logger.info("开始扫描策略包: com.luojie.strategy");}/*** 创建策略模式监控的BeanPostProcessor* <p>* 通过Spring的BeanPostProcessor机制,在所有Bean初始化完成后进行拦截处理,* 专门用于监控和记录策略实现类的加载情况,帮助开发者确认所有策略都已正确注册到Spring容器* </p>* @param strategyConfigurationInfo 策略配置信息,用于控制监控行为* @return 自定义的BeanPostProcessor实例,用于策略实现类的监控*/@Beanpublic BeanPostProcessor strategyBeanPostProcessor(StrategyConfigurationInfo strategyConfigurationInfo) {return new BeanPostProcessor() {/*** 在Bean初始化完成后进行处理* <p>* 此方法会在每个Spring Bean初始化完成后被调用,我们在这里专门处理策略包中的Bean* </p>* @param bean 初始化完成的Bean实例* @param beanName Bean在Spring容器中的名称* @return 处理后的Bean实例(此处直接返回原实例,不做修改)* @throws BeansException Bean处理过程中的异常*/@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {// 根据配置信息决定是否启用监控if (strategyConfigurationInfo.isMonitorEnabled()) {// 检查是否为支付策略实现类(排除配置类、工厂类和上下文类本身)// 使用配置中的packageToScan参数进行判断,实现动态配置if (bean.getClass().getPackage() != null && strategyConfigurationInfo.getPackageToScan() != null &&bean.getClass().getPackage().getName().startsWith(strategyConfigurationInfo.getPackageToScan()) && !beanName.equals("strategyConfig") && !beanName.equals("paymentStrategyFactory") && !beanName.equals("paymentContext")) {// 记录策略实现类的初始化和注册信息logger.info("策略实现类[{}] (Bean名称: {}) 初始化完成并注册到Spring容器", bean.getClass().getSimpleName(), beanName);}}return bean;  // 返回原Bean,不做任何修改}};}/*** 获取策略模式配置信息的方法* <p>* 创建并配置一个StrategyConfigurationInfo实例,用于封装当前策略模式的配置状态* 将其注册为Spring Bean,便于在系统其他地方获取和使用这些配置信息* </p>* <p>* 该配置实例包含三个核心参数,都有实际应用场景:* 1. packageToScan:用于策略实现类的包路径识别,在BeanPostProcessor中使用* 2. monitorEnabled:控制是否启用策略监控功能* 3. autoRegisterStrategies:控制策略工厂是否自动注册所有策略* </p>* @return 配置完成的StrategyConfigurationInfo实例*/@Beanpublic StrategyConfigurationInfo strategyConfigurationInfo() {StrategyConfigurationInfo info = new StrategyConfigurationInfo();// 设置要扫描的策略包路径 - 用于BeanPostProcessor中的策略类识别info.setPackageToScan("com.luojie.strategy");// 启用策略监控功能 - 控制是否记录策略实现类的加载日志info.setMonitorEnabled(true);// 启用策略自动注册功能 - 控制策略工厂是否自动注册所有策略实现info.setAutoRegisterStrategies(true);// 记录配置信息日志logger.info("策略模式配置信息: {}", info);return info;}/*** 内部类,用于封装策略模式的配置信息* <p>* 该类作为StrategyConfig的内部类,专门用于封装和管理策略模式的配置参数,* 提供了对策略扫描、监控和自动注册等功能的配置管理* </p>*/public static class StrategyConfigurationInfo {// 策略实现类所在的包路径,用于组件扫描private String packageToScan;// 是否启用策略监控功能private boolean monitorEnabled;// 是否自动注册策略实现到工厂类private boolean autoRegisterStrategies;/*** 获取策略实现类所在的包路径* @return 包路径字符串*/public String getPackageToScan() {return packageToScan;}/*** 设置策略实现类所在的包路径* @param packageToScan 包路径字符串*/public void setPackageToScan(String packageToScan) {this.packageToScan = packageToScan;}/*** 获取是否启用策略监控功能* @return true表示启用监控,false表示禁用监控*/public boolean isMonitorEnabled() {return monitorEnabled;}/*** 设置是否启用策略监控功能* @param monitorEnabled true表示启用监控,false表示禁用监控*/public void setMonitorEnabled(boolean monitorEnabled) {this.monitorEnabled = monitorEnabled;}/*** 获取是否自动注册策略实现* @return true表示自动注册,false表示手动注册*/public boolean isAutoRegisterStrategies() {return autoRegisterStrategies;}/*** 设置是否自动注册策略实现* @param autoRegisterStrategies true表示自动注册,false表示手动注册*/public void setAutoRegisterStrategies(boolean autoRegisterStrategies) {this.autoRegisterStrategies = autoRegisterStrategies;}/*** 返回配置信息的字符串表示* @return 包含所有配置项的字符串*/@Overridepublic String toString() {return "StrategyConfigurationInfo{" +"packageToScan='" + packageToScan + '\'' +", monitorEnabled=" + monitorEnabled +", autoRegisterStrategies=" + autoRegisterStrategies +'}';}}
}

实际的调用类--根据type,直接调用具体的对象方法

package com.luojie.strategy;import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;/*** 支付上下文类* <p>* 这是策略模式中的上下文类,负责持有和使用策略,为客户端提供统一的调用入口。* 在策略模式中,上下文类封装了策略的选择和使用细节,客户端不需要直接与策略交互,* 只需与上下文类交互即可,从而进一步降低了客户端与具体策略的耦合。* </p>* <p>* 该上下文类提供了两种使用策略的方式:* 1. 先设置策略,然后执行操作(分步式)* 2. 直接指定策略类型执行操作(一步式)* </p>*/
@Component  // 注册为Spring组件,使其能够被自动发现和注入
public class PaymentContext {// 日志记录器,用于记录上下文的操作日志private static final Logger logger = LoggerFactory.getLogger(PaymentContext.class);// 策略工厂,用于获取具体的策略实例private final PaymentStrategyFactory paymentStrategyFactory;// 当前使用的支付策略实例private PaymentStrategy currentStrategy;/*** 构造函数,注入策略工厂* <p>* 通过Spring的依赖注入机制,自动获取PaymentStrategyFactory的实例,* 以便后续通过工厂获取具体的策略实现。* </p>* @param paymentStrategyFactory 支付策略工厂实例*/@Autowiredpublic PaymentContext(PaymentStrategyFactory paymentStrategyFactory) {this.paymentStrategyFactory = paymentStrategyFactory;logger.info("支付上下文初始化完成");}/*** 设置支付策略* <p>* 这是分步式使用策略的第一步,用于设置后续操作要使用的支付策略。* 通过策略工厂获取指定类型的策略实例,并存储在当前上下文中。* </p>* @param strategyType 策略类型(如"alipay"、"wechatPay"等)*/public void setPaymentStrategy(String strategyType) {logger.debug("设置支付策略:{}", strategyType);this.currentStrategy = paymentStrategyFactory.getStrategy(strategyType);logger.info("支付策略设置成功:{}", strategyType);}/*** 执行支付操作* <p>* 这是分步式使用策略的第二步,使用已设置的支付策略执行支付操作。* 在调用此方法前,必须先调用setPaymentStrategy方法设置策略。* </p>* @param amount 支付金额* @return 支付结果描述* @throws IllegalStateException 如果未设置支付策略*/public String executePayment(double amount) {// 检查是否已设置支付策略if (currentStrategy == null) {logger.error("执行支付失败:未设置支付策略");throw new IllegalStateException("请先设置支付策略");}logger.debug("执行支付操作,金额:{}元,使用策略:{}", amount, currentStrategy.getClass().getSimpleName());// 调用当前策略的pay方法执行支付String result = currentStrategy.pay(amount);logger.info("支付操作执行完成,结果:{}", result);return result;}/*** 直接执行支付,一步完成策略选择和支付操作* <p>* 这是一步式使用策略的方法,将策略选择和执行操作合并为一步,* 适用于只需单次使用特定策略的场景,无需先设置再执行。* </p>* @param strategyType 策略类型(如"alipay"、"wechatPay"等)* @param amount 支付金额* @return 支付结果描述*/public String pay(String strategyType, double amount) {logger.debug("直接执行支付,策略类型:{},金额:{}元", strategyType, amount);// 通过工厂获取指定的策略实例并直接调用其pay方法PaymentStrategy strategy = paymentStrategyFactory.getStrategy(strategyType);String result = strategy.pay(amount);logger.info("直接支付操作执行完成,结果:{}", result);return result;}
}

调用测试

http://www.dtcms.com/a/365340.html

相关文章:

  • 海伯森检测应用案例之--光学板轮廓及瑕疵检测
  • 嵌入式 Linux 启动流程详解 (以 ARM + U-Boot 为例)
  • [Ai Agent] 打造一个真正可落地的客服智能体
  • 论文理解:Reflexion: Language Agents with Verbal Reinforcement Learning
  • 封装一个redis获取并解析数据的工具类
  • 基于web的云智教育在线平台设计与实现
  • 利用 openssl api 实现 TLS 双向认证
  • Jenkins和Fastlane的原理、优缺点、用法、如何选择
  • SpringAI Alibaba Graph 流式对话
  • python sqlalchemy模型的建立
  • 嵌入式硬件学习-2
  • Algorithms library
  • Qoder如何免费续杯,立即参与实践分享,赢 1000Credits
  • 解决windows下火狐浏览器开机会同时启动两个或多个页面
  • 为何quest3设备会强制更新,如何屏蔽更新
  • GoogleNet:更深的网络与更高的效率
  • 大模型的偏见:从训练数据到推理结果,如何检测与修正?
  • Voicemod-免费即时变声器
  • 【程序人生】有梦想就能了不起,就怕你没梦想
  • Redis 集群模式与高可用机制
  • 深度学习篇---Adam优化器
  • 计算机网络模型总概述
  • python抖音弹幕获取方案
  • 考研复习-计算机网络-第二章-物理层
  • 服务器安装vnc服务端
  • 深度学习篇---InceptionNet网络结构
  • Ecovadis评估认证准备期间对于公司员工培训有没有什么技巧?
  • 对轮询的理解
  • 手持式气象观测仪在短期监测项目的作用
  • 深度学习之第六课卷积神经网络 (CNN)如何保存和使用最优模型