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

策略模式 vs 适配器模式

一、模式本质

1 策略模式:行为的选择

核心思想:定义一组算法,将每个算法封装起来,并使它们可以互相替换,让算法的变化独立于使用它的客户端。

2 适配器模式:接口的转换

核心思想:将一个类的接口转换成客户端期望的另一个接口,使原本因接口不兼容而无法协同工作的类能够协同工作。

二、策略模式应用

1、策略模式模拟商品折扣算法

      Vip折扣、促销折扣、满减折扣

2、策略实现

2.1定义策略接口

public interface DiscountStrategy {    BigDecimal calculateDiscount(Order order);

}

2.2vip折扣

@Service("vipDiscount")

public class VipDiscountStrategy implements DiscountStrategy {    @Override    public BigDecimal calculateDiscount(Order order) {        return order.getAmount().multiply(BigDecimal.valueOf(0.9));    }}

2.3促销折扣

@Service("promotionDiscount")

public class PromotionDiscountStrategy implements DiscountStrategy {    @Override    public BigDecimal calculateDiscount(Order order) {        return order.getAmount().multiply(BigDecimal.valueOf(0.8));     }}

2.4满减折扣

@Service("fullReductionDiscount")

public class FullReductionDiscountStrategy implements DiscountStrategy {    @Override    public BigDecimal calculateDiscount(Order order) {        if (order.getAmount().compareTo(BigDecimal.valueOf(100)) > 0) {            return order.getAmount().subtract(BigDecimal.valueOf(20));         }        return order.getAmount();    }}

2.5策略核心

@Service

public class DiscountContext {    private final Map<String, DiscountStrategy> strategyMap;

    @Autowired    public DiscountContext(Map<String, DiscountStrategy> strategyMap) {        this.strategyMap = strategyMap;    }

    public BigDecimal applyDiscount(String strategyName, Order order) {        DiscountStrategy strategy = strategyMap.get(strategyName);        if (strategy == null) {            throw new IllegalArgumentException("未知折扣策略: " + strategyName);        }        return strategy.calculateDiscount(order);    }}

2.6控制器调用

@RestController

@RequestMapping("/orders")

public class OrderController {    @Autowired    private DiscountContext discountContext;
    @PostMapping("/calculate")    public BigDecimal calculatePrice(@RequestParam String discountType,                                     @RequestBody Order order) {        return discountContext.applyDiscount(discountType + "Discount", order);    }}

3、策略模式优势

    新增折扣策略只需添加新类

    避免多层if-else判断

    策略算法可独立测试

三、适配器模式应用

1、适配器模式模拟统一支付接口

       需要接入支付宝、微信支付和PayPal,但三家接口完全不同

2、适配器实现

2.1定义统一支付接口

public interface PaymentGateway {    PaymentResult pay(BigDecimal amount, String orderId);

}

2.2支付宝适配器

2.2.1原生接口

public class AlipayService {    public AlipayResponse createPayment(AlipayRequest request) {        // 支付宝原生逻辑    }

}

2.2.2支付宝适配器

@Service

public class AlipayAdapter implements PaymentGateway {    private final AlipayService alipayService;
    @Override    public PaymentResult pay(BigDecimal amount, String orderId) {        // 转换参数        AlipayRequest request = new AlipayRequest(amount, orderId);
        // 调用原生接口        AlipayResponse response = alipayService.createPayment(request);
        // 转换结果        return new PaymentResult(         response.isSuccess(),         response.getTransactionId()        );    }

}

2.3微信支付适配器

@Service

public class WechatPayAdapter implements PaymentGateway {    private final WechatPayService wechatService;
    @Override    public PaymentResult pay(BigDecimal amount, String orderId) {        // 转换并调用微信接口    }

}

2.4Paypal支付适配器

@Service

public class PayPalAdapter implements PaymentGateway {    private final PayPalClient paypalClient;
    @Override    public PaymentResult pay(BigDecimal amount, String orderId) {        // 转换并调用PayPal接口    }

}

2.5统一支付实现

@Service

public class PaymentService {    private final Map<String, PaymentGateway> gateways;
    @Autowired    public PaymentService(List<PaymentGateway> gatewayList) {        this.gateways = gatewayList.stream()            .collect(Collectors.toMap(                g -> g.getClass().getSimpleName().replace("Adapter", "").toLowerCase(),                Function.identity()            ));    }
    public PaymentResult processPayment(String gatewayType,                                        BigDecimal amount, String orderId) {        PaymentGateway gateway = gateways.get(gatewayType);        if (gateway == null) {            throw new IllegalArgumentException("不支持的支付方式: " + gatewayType);        }        return gateway.pay(amount, orderId);    }

}

3适配器模式优势

   无需修改三方支付SDK

   统一支付接口简化调用

   新增支付渠道只需添加适配器

四、对比

 

 五、如何正确选择何种模式

1 选择策略模式

需要动态选择算法或行为

有多个相似类仅在行为上

有差异需要消除复杂的件语句

希望算法能够独立于客户端变化

2 选择适配器模式

需要使用现有类但其接口不符合要求

需要创建可复用的类与不兼容接口协同工作

需要统一多个独立开发的模块接口

需要兼容旧系统或第三方库

3流程示意图

 

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

相关文章:

  • 基于STM32设计的大棚育苗管理系统(4G+华为云IOT)_265
  • 移动应用抓包与调试实战 Charles工具在iOS和Android中的应用
  • 数据结构初阶:详解二叉树(三):链式二叉树
  • system\core\init\init.cpp----LoadBootScripts()解析init.rc(1)
  • STM32之串口详解
  • 学习Linux嵌入式(正点原子imx课程)开发到底是在学什么
  • Spring Cloud Netflix学习笔记06-Zuul
  • Kafka消息持久化机制全解析:存储原理与实战场景
  • Kafka集成Flume
  • 人工智能 -- 循环神经网络day1 -- 自然语言基础、NLP基础概率、NLP基本流程、NLP特征工程、NLP特征输入
  • 算法 之 拓 扑 排 序
  • LeetCode 回文链表
  • 桥梁设计模式
  • RabbitMQ事务消息原理是什么
  • RabbitMQ:延时消息(死信交换机、延迟消息插件)
  • 领域专用AI模型训练指南:医疗、法律、金融三大垂直领域微调效果对比
  • 28、工业网络资产漏洞扫描与风险评估 (模拟) - /安全与维护组件/industrial-network-scanner
  • 深度解析Atlassian 团队协作套件(Jira、Confluence、Loom、Rovo)如何赋能全球分布式团队协作
  • Whisk for Mac 网页编辑器 PHP开发
  • 牛客:链表的回文结构详解
  • NewsNow搭建喂饭级教程
  • SQL中对视图的操作命令汇总
  • STM32H750 CoreMark跑分测试
  • [最新]Dify v1.7.2版本更新:工作流可视化和节点搜索
  • 2025 年 8 月《GPT-5 家族 SQL 能力评测报告》发布
  • SQL视图、存储过程和触发器
  • OBCP第四章 OceanBase SQL 调优学习笔记:通俗解读与实践指南
  • CentOS 7安装FFmpeg
  • QT QProcess, WinExec, ShellExecute中文路径带空格程序或者脚本执行并带参数
  • Qt实现TabWidget通过addTab函数添加的页,页内控件自适应窗口大小