行为型设计模式之策略模式
- 策略模式
- 应用场景
- 优缺点
- 主要角色
- 策略模式的基本使用
- 创建抽象策略角色
- 创建具体策略角色
- 创建上下文角色
- 客户端执行
- 策略模式实现支付方式的选择
- 创建抽象策略角色
- 创建具体策略角色
- 创建上下文角色
- 客户端执行
策略模式
策略模式(Strategy Pattern)也叫政策模式(Policy Pattern),属于行为型模式。
它是将定义的一系列算法、分别封装起来,让它们之间可以互相替换,从而让算法的变化不会影响到使用算法的用户。
策略模式能让你定义一系列算法, 并将每种算法分别放入独立的类中, 以使算法的对象能够相互替换。
应用场景
1、针对同一类型问题,有多种处理方式,每一种都能独立解决问题。2、算法需要自由切换的场景。3、需要屏蔽算法规则的场景。
优缺点
优点:
1.可以在运行时切换对象内的算法。2.避免使用多重条件转移语句,如if.else.语句、switch语句3.使用策略模式可以提高算法的保密性和安全性。4.可以将算法的实现和使用算法的代码隔离开来。
缺点:
1.客户端必须知道所有的策略,所有策略类都需要对外暴露,并且自行决定使用哪一个策略类。2.代码中会产生非常多策略类,增加维护难度。
主要角色
1.抽象策略角色(Strategy)
规定策略或算法的行为。
2.具体策略角色(ConcreteStrategy)
具体的策略或算法实现。
3.上下文角色(Context)
用来操作策略的上下文环境,屏蔽高层模块(客户瑞)对策略,算法的直接访问,封装可能存在的变化。
策略模式的基本使用
创建抽象策略角色
public interface IStrategy {/*** 算法、策略*/void algorithm();
}
创建具体策略角色
public class ConcreteStrategyA implements IStrategy {public void algorithm() {System.out.println("Strategy A 打9折");}
}
public class ConcreteStrategyB implements IStrategy {public void algorithm() {System.out.println("Strategy B 打8折");}
}
创建上下文角色
public class Context {private IStrategy mStrategy;public Context(IStrategy strategy) {this.mStrategy = strategy;}public void algorithm() {this.mStrategy.algorithm();}
}
客户端执行
public static void main(String[] args) {// 创建具体策略IStrategy strategyA = new ConcreteStrategyA();IStrategy strategyB = new ConcreteStrategyB();// 创建上下文环境Context contextA = new Context(strategyA);Context contextB = new Context(strategyB);//客户端直接让上下文环境执行算法contextA.algorithm();contextB.algorithm();}
Strategy A 打9折
Strategy B 打8折
策略模式实现支付方式的选择
创建抽象策略角色
创建支付抽象类,定义支付逻辑
public abstract class Payment {/*** 支付类型*/public abstract String getName();/*** 支付* @param uid 用户id* @param amount 金额* @return 支付结果*/public String pay(String uid, double amount){if(queryBalance(uid) < amount){return "支付失败,"+"商品金额:"+amount+" ,用户余额:"+queryBalance(uid);}return "支付成功,"+"商品金额:"+amount+" ,用户余额:"+(queryBalance(uid)-amount);}/*** 余额查询* @param uid 用户id* @return 余额*/protected abstract double queryBalance(String uid);
}
创建具体策略角色
创建具体支付方式,如AliPay 、WechatPay 、UnionPay等三种方式。
public class AliPay extends Payment {public String getName() {return "支付宝";}protected double queryBalance(String uid) {return 500;}
}public class WechatPay extends Payment {public String getName() {return "微信支付";}protected double queryBalance(String uid) {return 600;}
}public class UnionPay extends Payment {public String getName() {return "银联支付";}protected double queryBalance(String uid) {return 800;}
}
创建上下文角色
创建上下文角色,
public class PayStrategy {public static final String ALI_PAY = "AliPay";public static final String WECHAT_PAY = "WechatPay";public static final String UNION_PAY = "UnionPay";public static final String DEFAULT_PAY = ALI_PAY;private static Map<String, Payment> strategy = new HashMap<String, Payment>();static {strategy.put(ALI_PAY, new AliPay());strategy.put(WECHAT_PAY, new WechatPay());strategy.put(UNION_PAY, new UnionPay());}public static Payment get(String payKey) {if (!strategy.containsKey(payKey)) {return strategy.get(DEFAULT_PAY);}return strategy.get(payKey);}
}
客户端执行
public class Order {private String uid;private String name;private double price;public Order(String uid, String name, double price) {this.uid = uid;this.name = name;this.price = price;}public String pay() {return pay(PayStrategy.DEFAULT_PAY);}public String pay(String payKey) {Payment payment = PayStrategy.get(payKey);System.out.println("购买:"+name+" ,使用" + payment.getName() + "支付, " + "支付金额为: " + price);return payment.pay(uid, price);}
}
public static void main(String[] args) {Order order = new Order("001","皮皮虾",500.5);System.out.println(order.pay());System.out.println("----------------------------------------------------");System.out.println(order.pay(PayStrategy.WECHAT_PAY));}
购买:皮皮虾 ,使用支付宝支付, 支付金额为: 500.5
支付失败,商品金额:500.5 ,用户余额:500.0
----------------------------------------------------
购买:皮皮虾 ,使用微信支付支付, 支付金额为: 500.5
支付成功,商品金额:500.5 ,用户余额:99.5