2.【设计模式.行为型.策略模式】策略模式实现
【设计模式.行为型.策略模式】
一、说明
策略模式封装了不同的实现,可以基于不同的策略标识选择不同的执行策略,从而避免书写过多的if...else,switch等语句,扩展时不需要改动原代码,只需要扩招不同的策略实现即可,符合开闭原则。常常搭配工厂模式一起使用。
一、最基本的策略模式使用
定义策略接口,实际执行的策略通过设置上下环境类的方式调用不同的策略。
package com.fatsea.news.pattern.behavioral;
/**
* @Author: Chunhai.Hu
* @Date: 2021/4/28 17:41
* @Desc: 行为型.策略模式
* @最基本的策略模式使用
*/
public class BaseStrategyTest {
public static void main(String[] args) {
// 策略环境实例
Context context = new Context();
// 使用策略A
IBaseStrategy baseStrategyA = new BaseStrategyA();
context.setStrategy(baseStrategyA);
baseStrategyA.strategyMethod();
// 使用策略B
IBaseStrategy baseStrategyB = new BaseStrategyB();
context.setStrategy(baseStrategyB);
baseStrategyB.strategyMethod();
}
}
// 策略抽象
interface IBaseStrategy {
void strategyMethod ();
}
// 具体策略类A
class BaseStrategyA implements IBaseStrategy {
@Override
public void strategyMethod() {
System.out.println("aliPay支付策略......");
}
}
// 具体策略类B
class BaseStrategyB implements IBaseStrategy {
@Override
public void strategyMethod() {
System.out.println("weChatPay支付策略......");
}
}
// 上下文环境类
class Context {
private IBaseStrategy strategy;
public Context() {
}
public Context(IBaseStrategy strategy) {
this.strategy = strategy;
}
public void setStrategy(IBaseStrategy strategy) {
this.strategy = strategy;
}
public void strategyMethod () {
strategy.strategyMethod();
}
}
二、促销策略测试[策略+工厂+单例]
使用工厂模式初始化各个策略的单例,放入一个Map集合中,调用时根据标识获取不同策略的实现执行。
package com.fatsea.news.pattern.behavioral;
import java.util.HashMap;
import java.util.Map;
/**
* @Author: Chunhai.Hu
* @Date: 2021/4/30 16:14
* @Desc: 行为型.策略模式.促销策略测试[策略+工厂+单例]
*/
public class PromotionalStrategyTest {
public static void main(String[] args) {
// 使用工厂和枚举类型调用
IPromotional strategy = PromotionalStrategyFactory.getPromotionalStrategy(PromotionalStrategyFactory.PromotionalKey.COUPON);
strategy.doPromotional();
// 使用上下文环境类调用
PromotionalActivity activity = new PromotionalActivity();
activity.doPromotional();
}
}
// 促销抽象接口
interface IPromotional {
void doPromotional();
}
// 促销手段:无(默认方式)
class EmptyStrategy implements IPromotional {
@Override
public void doPromotional() {
System.out.println("原价购买,无促销手段");
}
}
// 促销手段:团购
class GroupByStrategy implements IPromotional {
@Override
public void doPromotional() {
System.out.println("团购促销.满5人即可享受团购价");
}
}
// 促销手段:返现
class CashBackStrategy implements IPromotional {
@Override
public void doPromotional() {
System.out.println("返现实付款的20%至付款账户");
}
}
// 促销手段:优惠券
class CouponStrategy implements IPromotional {
@Override
public void doPromotional() {
System.out.println("使用优惠券抵扣");
}
}
// 上下文环境类:具体活动[如需要.可将活动也进行抽象]
class PromotionalActivity {
IPromotional strategy;
// 默认使用无优惠策略
public PromotionalActivity() {
this.strategy = new EmptyStrategy();
}
public PromotionalActivity(IPromotional strategy) {
this.strategy = strategy;
}
public void setStrategy(IPromotional strategy) {
this.strategy = strategy;
}
public void doPromotional () {
strategy.doPromotional();
}
}
// 策略生成工厂
class PromotionalStrategyFactory {
// 单例初始话所有促销策略到PROMOTIONS中,或者使用初级工厂动态生成不同的Strategy
private static Map<PromotionalKey, Object> PROMOTIONS = new HashMap<PromotionalKey, Object>();
static {
PROMOTIONS.put(PromotionalKey.EMPTY, new EmptyStrategy());
PROMOTIONS.put(PromotionalKey.GROUPBY, new GroupByStrategy());
PROMOTIONS.put(PromotionalKey.CASHBACK, new CashBackStrategy());
PROMOTIONS.put(PromotionalKey.COUPON, new CouponStrategy());
}
// 默认为public、static、final属性
enum PromotionalKey {
EMPTY, GROUPBY, CASHBACK, COUPON
}
// 不传时,采用无优惠策略
public static IPromotional getPromotionalStrategy() {
return (IPromotional) PROMOTIONS.get(PromotionalKey.EMPTY);
}
// 根据优惠标识获取实际优惠策略
public static IPromotional getPromotionalStrategy(PromotionalKey key) {
return (IPromotional) PROMOTIONS.get(key);
}
}
三、支付策略测试[策略+工厂+单例]
模式与二中的模式一致,只是用在了不同的业务场景,上述是优惠策略,这个是支付策略。
package com.fatsea.news.pattern.behavioral;
import lombok.Data;
import java.util.HashMap;
import java.util.Map;
/**
* @Author: Chunhai.Hu
* @Date: 2021/4/30 17:22
* @Desc: 行为型.策略模式.支付策略测试[策略+工厂+单例]
*/
public class PayStrategyTest {
public static void main(String[] args) {
// 生成订单
Order order = new Order();
order.setTradeNo("JD079825648546845");
order.setPrice(1000);
order.setNum(5);
// 使用工厂和枚举类型调用支付策略
IPayStrategy strategy = PayStrategyFactory.getPayStrategy(PayStrategyFactory.PayWay.GOOGLEPAY);
System.out.println(strategy.getVoucher(order));
System.out.println(strategy.verifyPayResult(order.getTradeNo()));
}
}
// 订单类
@Data
class Order {
// 单号
private String tradeNo;
// 单价
private Integer price;
// 数量
private Integer num;
}
// 支付策略抽象
interface IPayStrategy {
// 获取支付凭证,调起支付
String getVoucher (Order order);
// APP主动上报,校验支付结果
String verifyPayResult (String tradeNo);
}
// 支付策略:支付宝
class AliPay implements IPayStrategy {
@Override
public String getVoucher(Order order) {
String result = "支付宝,订单号:" + order.getTradeNo() +
",单价:" + order.getPrice() +
",数量:" + order.getNum() +
",总价:" + order.getPrice() * order.getNum();
return result;
}
@Override
public String verifyPayResult(String tradeNo) {
return "支付宝支付成功,单号" + tradeNo;
}
}
// 支付策略:微信支付
class WeChatPay implements IPayStrategy {
@Override
public String getVoucher(Order order) {
String result = "微信支付,订单号:" + order.getTradeNo() +
",单价:" + order.getPrice() +
",数量:" + order.getNum() +
",总价:" + order.getPrice() * order.getNum();
return result;
}
@Override
public String verifyPayResult(String tradeNo) {
return "微信支付成功,单号" + tradeNo;
}
}
// 支付策略:谷歌支付
class GooglePay implements IPayStrategy {
@Override
public String getVoucher(Order order) {
String result = "谷歌支付,订单号:" + order.getTradeNo() +
",单价:" + order.getPrice() +
",数量:" + order.getNum() +
",总价:" + order.getPrice() * order.getNum();
return result;
}
@Override
public String verifyPayResult(String tradeNo) {
return "谷歌支付成功,单号" + tradeNo;
}
}
// 支付策略生成工厂
class PayStrategyFactory {
// 单例初始化所有支付策略
private static Map<PayWay, IPayStrategy> payStrategyMap = new HashMap<PayWay, IPayStrategy>();
static {
payStrategyMap.put(PayWay.ALIPAY, new AliPay());
payStrategyMap.put(PayWay.WECHATPAY, new WeChatPay());
payStrategyMap.put(PayWay.GOOGLEPAY, new GooglePay());
}
// 默认为public、static、final属性
enum PayWay {
ALIPAY, WECHATPAY, GOOGLEPAY
}
// 默认使用支付宝
public static IPayStrategy getPayStrategy () {
return payStrategyMap.get(PayWay.ALIPAY);
}
// 根据PayWay返回不同的支付策略
public static IPayStrategy getPayStrategy (PayWay payWay) {
return payStrategyMap.get(payWay);
}
}