策略模式 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定义统一支付接口

2.2支付宝适配器

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

2.2.1原生接口

public class AlipayService {

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

2.2.2支付宝适配器

@Service
public class AlipayAdapter implements PaymentGateway {
    private finalAlipayService 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流程示意图

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值