设计模式之四策略模式

设计模式之四策略模式

譬如商城有优惠策略,①优惠券抵扣,拼多多有月卡就是一种②返现促销,满100返回20.③拼团,拼多多的核心模式。下面我们用代码模拟这个场景,首先我们创建一个促销策略的接口PromotionStrategy。

Promotion促销的意思, Stragegy策略的意思

案例一

package com.hanker.io;
//创建策略接口
interface PromotionStrategy{
	void doPromotion();//执行促销策略
}
//优惠券策略类
class CouponStrategy implements PromotionStrategy{
	public void doPromotion() {
		System.out.println("领取优惠券,商品价格直接减优惠券面值抵扣.");
	}
}
//返现策略
class CashbackStrategy implements PromotionStrategy{
	public void doPromotion() {
		System.out.println("返现促销,返回的金额转到支付宝账号.");
	}
}
//拼团策略
class GroupbuyStrategy implements PromotionStrategy{
	public void doPromotion() {
		System.out.println("拼团,满2人成团,全团享受团购特价");
	}
}
//没有优惠策略
class EmptyStrategy implements PromotionStrategy{
	public void doPromotion() {
		System.out.println("无促销活动..");
	}
}
//创建促销活动方案类
class PromotionActivity{
	private PromotionStrategy promotionStrategy;
	public PromotionActivity(PromotionStrategy promotionStrategy) {
		this.promotionStrategy = promotionStrategy;
	}
	public void execute() {
		promotionStrategy.doPromotion();
	}
}
public class StragegyPatternDemo {

	public static void main(String[] args) {
		//创建优惠券的促销策略
		CouponStrategy couponStrategy = new CouponStrategy();
		//创建返现的促销策略
		CashbackStrategy cashbackStrategy = new CashbackStrategy();
		//创建两个促销活动
		PromotionActivity p618 = new PromotionActivity(couponStrategy);
		PromotionActivity p1111  =new PromotionActivity(cashbackStrategy);
		p618.execute();
		p1111.execute();

	}

}

代码到这里还有可以优化的地方,也就是营销策略最好集成存放,用户想使用哪种策略直接取出。

//为了管理方便做一个工厂类
class PromotionStrategyFactory{
	//创建一个map存储所有的策略,管理方便
	private static final Map<String,PromotionStrategy> PROMOTION_STRATEGY_MAP = new HashMap<>();
	static {
		PROMOTION_STRATEGY_MAP.put(PromotionKey.COUPON, new CouponStrategy());
		PROMOTION_STRATEGY_MAP.put(PromotionKey.CASHBACK,new CashbackStrategy());
		PROMOTION_STRATEGY_MAP.put(PromotionKey.GROUPBY, new GroupbuyStrategy());
	}
	//空策略
	private static final PromotionStrategy NON_PROMOTION = new EmptyStrategy();
	//获取策略的方法
	public static PromotionStrategy getPromotionStrategy(String promotionKey) {
		PromotionStrategy promotionStrategy  = PROMOTION_STRATEGY_MAP.get(promotionKey);
		return  promotionStrategy == null ? NON_PROMOTION : promotionStrategy;
	}
	
	//定义一个常量接口
	static interface PromotionKey{
		String COUPON = "COUPON";
		String CASHBACK = "CASHBACK";
		String GROUPBY = "GROUPBY";
	}
}

客户端:

public class StragegyPatternDemo {
	public static void main(String[] args) {
		//key是一个普通字符串,很可能出现错误,如何解决:做一个常量
		String promotionKey = PromotionStrategyFactory.PromotionKey.CASHBACK;
		//从工厂获取一个策略
		PromotionStrategy promotionStrategy = PromotionStrategyFactory.getPromotionStrategy(promotionKey);
		//创建促销活动
		PromotionActivity p51 = new PromotionActivity(promotionStrategy);
		p51.execute();
	}
}

案例二

网上支付的案例: 支付宝支付,微信支付,银联支付,京东白条支付;一个场景的应用场景是大家在支付的时候回提示选择支付方式,如果用户没有选择,系统也会使用默认的支付方式结算。

package com.hanker.io;

import java.util.HashMap;
import java.util.Map;
//支付状态类
class PayState{
	private int code; //编码 200 一般是 ok 
	private Object data;//数据
	private String msg;//提示信息
	public PayState(int code, Object data, String msg) {
		super();
		this.code = code;
		this.data = data;
		this.msg = msg;
	}
	public String toString() {
		return "支付状态:[" + code + "],"+ msg+",交易详情:"+data;
	}
}
//策略抽象类
abstract class Payment{
	//支付类型
	public abstract String getName();
	
	//查询余额
	protected abstract double queryBalance(String uid);
	
	//扣款支付 uid用户编号,amount支付金额
	public PayState pay(String uid,double amount) {
		if(queryBalance(uid) < amount) {
			return new PayState(500,"支付失败","余额不足");
		}
		return new PayState(200,"支付成功","支付金额:"+amount);
	}
}
//支付宝支付
class AliPay extends Payment{

	@Override
	public String getName() {
		return "支付宝";
	}
	@Override
	protected double queryBalance(String uid) {
		return 900;
	}
}
//微信支付
class WechatPay extends Payment{
	public String getName() {
		return "微信支付";
	}
	protected double queryBalance(String uid) {
		return 256;
	}
}
//银联支付
class UnionPay extends Payment{
	public String getName() {
		return "银联支付";
	}
	protected double queryBalance(String uid) {
		return 120;
	}
}
//京东支付
class JDPay extends Payment{
	public String getName() {
		return "京东支付";
	}
	protected double queryBalance(String uid) {
		return 500;
	}
}
//策略工厂类
class PaymentStrategyFactory{
	public static final String ALI_PAY = "ALI_PAY";
	public static final String JD_PAY = "JDPAY";
	public static final String UNION_PAY = "UNION_PAY";
	public static final String WECHAT_PAY = "WECHAT_PAY";
	public static final String DEFAULT_PAY = ALI_PAY;//默认支付方式:支付宝
	private static final Map<String,Payment> PAY_MAP = new HashMap<>();
	static {
		PAY_MAP.put(ALI_PAY, new AliPay());
		PAY_MAP.put(JD_PAY, new JDPay());
		PAY_MAP.put(UNION_PAY, new UnionPay());
		PAY_MAP.put(WECHAT_PAY, new WechatPay());
	}
	
	public static Payment getPayment(String payKey) {
		if( !PAY_MAP.containsKey(payKey) ) {
			return PAY_MAP.get(DEFAULT_PAY);
		}
		return PAY_MAP.get(payKey);
	}
}
//提交一个订单,调用支付方式
class Order{
	private String uid;
	private String orderId;
	private double amount;
	public Order(String uid, String orderId, double amount) {
		super();
		this.uid = uid;
		this.orderId = orderId;
		this.amount = amount;
	}
	
	public PayState pay() {
		return pay(PaymentStrategyFactory.DEFAULT_PAY);
	}
	
	public PayState pay(String payKey) {
		Payment payment = PaymentStrategyFactory.getPayment(payKey);
		System.out.println("欢迎使用:"+payment.getName());
		System.out.println("本次交易金额为:"+amount +",开始扣款.....");
		return payment.pay(payKey, amount);
	}
}
public class StragegyPatternDemo2 {
	public static void main(String[] args) {
		Order order = new Order("1001","202003180001",3000);
		PayState payState = order.pay(PaymentStrategyFactory.ALI_PAY);
		System.out.println(payState);
	}
}

在这里插入图片描述

优缺点

优点:
①策略模式符合开闭原则
②策略模式可避免使用多重条件语句,如if—else语句、switch语句
③使用策略模式可以提高算法的保密性和安全性
缺点:
①客户端必须知道所有的策略,并且自行决定使用哪一个策略类
②代码中会产生非常多的策略类,增加了代码的维护难度。

发布了91 篇原创文章 · 获赞 43 · 访问量 14万+

猜你喜欢

转载自blog.csdn.net/kongfanyu/article/details/104951262