策略模式(行为型)

定义

将定义的算法,分别进行分装,让他们之间可以互相替换,从而让算法的变化不会影响到使用算法的用户,避免多重if,switch

适用场景

  1. 系统中有很多类,区别仅在于它们的行为不同
  2. 一个系统需要动态的在几种算法选择一种
  3. 需要屏蔽算法规则

实例

public interface Promotion {
    void doPromotion();
}

public class CardDiscount implements Promotion {
    @Override
    public void doPromation() {
        System.out.println("优惠卷优惠");
    }
}

public class EmptyStategy implements Promotion {
    @Override
    public void doPromation() {
        System.out.println("无打折优惠");
    }
}

public class FestivalDiscount implements Promotion {
    @Override
    public void doPromotion() {
        System.out.println("节日优惠");
    }
}

public class GroupDiscount implements Promotion {
    @Override
    public void doPromotion() {
        System.out.println("成团打折");
    }
}


public class PromotionStrategyFactory {
     public interface PromotionKeys {
         String CARD = "card";
         String FESTIVAL = "festival";
         String GROUP = "group";
     }

     private static Map<String,Promotion> ptkeys = new HashMap<String,Promotion>();

     static {
         ptkeys.put(PromotionKeys.CARD,new CardDiscount());
         ptkeys.put(PromotionKeys.FESTIVAL, new FestivalDiscount());
         ptkeys.put(PromotionKeys.GROUP, new GroupDiscount());
     }

     private static final Promotion EMPTY = new EmptyStategy();

     public static Promotion getPromotionStrategy(String promotionKeys) {
         Promotion pmt = ptkeys.get(promotionKeys);
         return pmt == null ? EMPTY : pmt;
     }

     public static Set<String> getPromotionKeys() {
         return ptkeys.keySet();
     }

}


public class Test {
    public static void main(String[] args) {
        PromotionStrategyFactory.getPromotionKeys();
        String key = "group";
        PromotionStrategyFactory.getPromotionStrategy(key).doPromotion();
    }
}
public class MsgResult {
    private int code;
    private String msg;
    private String data;

    public MsgResult(int code, String msg, String data) {
        this.code = code;
        this.msg = msg;
        this.data = data;
    }

    @Override
    public String toString() {
        return "MsgResult{" +
                "code=" + code +
                ", msg='" + msg + '\'' +
                ", data='" + data + '\'' +
                '}';
    }
}

public abstract class BasePay {
    public abstract String getName();

    public abstract double queryAmount(int uid);


    public MsgResult pay(int uid, double amount) {
        if (queryAmount(uid) > amount) {
            return new MsgResult(500,"success","支付金额" + amount);
        }
        return  new MsgResult(200,"error","金额不足");
    }
}

public class AliyPay extends BasePay {
    @Override
    public String getName() {
        return "阿里支付";
    }

    @Override
    public double queryAmount(int uid) {
        return 500;
    }
}

public class JdPay extends BasePay {
    @Override
    public String getName() {
        return "京东支付";
    }

    @Override
    public double queryAmount(int uid) {
        return 400;
    }
}

public class QqPay extends BasePay {
    @Override
    public String getName() {
        return "qq支付";
    }

    @Override
    public double queryAmount(int uid) {
        return 300;
    }
}

public class WechatPay extends BasePay {
    @Override
    public String getName() {
        return "微信支付";
    }

    @Override
    public double queryAmount(int uid) {
        return 100;
    }
}

public class PayStrategy {

    public static final String ALIPAY = "AliPay";
    public static final String JDPAY = "JdPay";
    public static final String WECHATPAY = "WechatPay";
    public static final String QQPAY = "QqPay";
    public static final String DEFALUTPAY = ALIPAY;

    private static Map<String, BasePay> payMap = new HashMap<String, BasePay>();

    static {
        payMap.put(ALIPAY,new AliyPay());
        payMap.put(JDPAY,new JdPay());
        payMap.put(WECHATPAY,new WechatPay());
        payMap.put(QQPAY,new QqPay());
    }

    public static BasePay getPay(String payKey) {
        if (!payMap.containsKey(payKey)) {
            return payMap.get(DEFALUTPAY);
        }
        return payMap.get(payKey);
    }

}

public class Order {
    private int uid;
    private int orderId;
    private double amount;

    public Order(int uid, int orderId, double amount) {
        this.uid = uid;
        this.orderId = orderId;
        this.amount = amount;
    }

    public MsgResult pay() {
        return pay(PayStrategy.DEFALUTPAY);
    }

    public MsgResult pay(String key) {
        BasePay basePay = PayStrategy.getPay(key);
        System.out.println("本次交易方式为:" + basePay.getName());
        System.out.println("本次交易金额为:" + amount);
        return basePay.pay(uid,amount);
    }
}

public class Test {
    public static void main(String[] args) {
        Order order = new Order(111232312,21321323,100);
        System.out.println(order.pay("JdPay"));
    }
}

应用

  1. spring bean- Instantiantionstrategy
  2. comparation sort - Tree map
  3. spring core - Resource

优点

  1. 符合开闭原则
  2. 避免使用多重条件转移语句
  3. 提高算法的保密性和安全性

缺点

  1. 客户端必须知道所有的策略,自行决定使用哪个策略
  2. 代码中会产生很多的策略类,增加维护难度
### 策略模式行为型模式的关系 策略模式行为型设计模式的一种具体实现形式。行为型模式主要用于描述程序在运行时复杂的流程控制,以及多个类或对象之间的协作方式[^4]。这些模式关注的是如何分配职责、定义交互逻辑,并通过这种方式解决复杂问题。 策略模式的核心在于将一组可变的算法或行为封装到独立的类中,从而使得它们可以互换使用。这不仅提高了代码的灵活性,还增强了系统的扩展性和维护性[^1]。因此,在行为型模式分类下,策略模式被归为一种典型的对象行为模式,因为它依赖于组合而非继承来实现动态变化的功能需求[^3]。 --- ### 策略模式的作用 #### 1. 提高代码的灵活性 通过引入策略接口和具体的策略实现类,策略模式能够使上下文(Context)对象的行为随着所选策略的变化而调整。这意味着无需修改现有代码即可轻松增加新的功能或者替换已有功能[^2]。 #### 2. 遵循开闭原则(Open-Closed Principle) 根据面向对象编程的原则之一——开闭原则,软件实体应该对扩展开放但对修改关闭。策略模式正是这一理念的良好实践:当需要新增某种业务处理逻辑时,只需添加一个新的策略类并注册给Context即可完成操作,完全不需要改动原有代码结构。 #### 3. 解耦合度提升 由于每种特定算法都被隔离在一个单独的Strategy子类里,所以客户只需要知道有哪些可用选项就可以自由切换不同方案;同时各部分之间也不存在紧密联系,降低了整体架构的风险系数。 --- ### 应用场景分析 以下是几种适合运用策略模式的实际开发环境: #### 场景一:多种支付手段支持 电子商务平台通常提供多样化的付款渠道供消费者选择,比如信用卡、PayPal账户余额转账等等。此时可以通过构建PaymentStrategy抽象基类及其若干派生实例分别代表各类结算方法,再由OrderProcessingContext负责调用当前选定的那个payment strategy去实际扣款[^2]。 ```java // 定义统一接口 public interface PaymentStrategy { void pay(double amount); } // 实现具体策略 public class CreditCardPayment implements PaymentStrategy { @Override public void pay(double amount){ System.out.println("Paid "+amount+" using credit card."); } } public class PayPalPayment implements PaymentStrategy{ @Override public void pay(double amount){ System.out.println("Paid "+amount+" via PayPal account balance."); } } // 使用策略的地方 public class ShoppingCart { private PaymentStrategy paymentMethod; public void setPaymentMethod(PaymentStrategy pm){this.paymentMethod=pm;} public void checkout(){ double totalCost = calculateTotal(); this.paymentMethod.pay(totalCost); // 调用指定策略的方法 } } ``` #### 场景二:数据压缩工具插件化管理 假设有一款通用的数据文件压缩应用程序,它可以依据用户的偏好自动选用最高效的压缩技术(如ZIP, GZIP 或者RAR)。那么完全可以借助strategy pattern把各个备选的技术都做成对应的plugin模块,最终让用户自行决定到底要采用哪一款来进行打包作业[^4]。 --- ### 总结 综上所述,作为行为型设计模式的一员,策略模式凭借其强大的适应能力解决了许多现实世界中的难题。无论是简化大型项目的内部构造还是增强小型脚本的重用价值方面都有着不可替代的地位。只要合理规划好何时何处应用该模式,则必定能带来事半功倍的效果!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值