设计模式--策略模式


    策略模式(Strategy Pattern)是指定义了算法家族、分别封装起来,让它们之间可以互相替换,此模式让算法的变化不会影响到使用算法的用户。策略模式使得算法可以在不影响到客户端的情况下发生变化,可以避免多重分支的if...else...和switch语句。

    策略模式属于对象的行为模式。策略模式是对算法的包装,是把使用算法的责任和算法本身分割开来,委派给不同的对象管理。策略模式通常把一个系列的算法包装到一系列的策略类里面,作为一个抽象策略类的子类。用一句话来说,就是:“准备一组算法,并将每一个算法封装起来,使得它们可以互换”。


这个模式涉及到三个角色:

    1、环境(Context)角色:持有一个Strategy的引用。

    2、抽象策略(Strategy)角色:这是一个抽象角色,通常由一个接口或抽象类实现。此角色给出所有的具体策略类所需的接口。

    3、具体策略(ConcreteStrategy)角色:包装了相关的算法或行为。

public class Context {
    //持有一个具体策略的对象
    private Strategy strategy;
    
    public Context(Strategy strategy){
        this.strategy = strategy;
    }
    /**
     * 策略方法
     */
    public void doSomething(){ 
        strategy.doStrategy();
    }
}
public interface Strategy {
    /**
     * 策略方法
     */
    public void doStrategy();
}
public class StrategyA implements Strategy {
    @Override
    public void doStrategy() {
        //相关的业务
	System.out.println("StrategyA.doStrategy() ") ;
    }
}
public class StrategyB implements Strategy {
    @Override
    public void doStrategy() {
        //相关的业务
	System.out.println("StrategyB.doStrategy() ") ;
    }
}
public class StrategyC implements Strategy {
    @Override
    public void doStrategy() {
        //相关的业务
	System.out.println("StrategyC.doStrategy() ") ;
    }
}


模拟一个支付场景使用策略模式。

public abstract class Payment {
	// 支付类型
	public abstract String getName();
	// 查询余额
	protected abstract double queryBalance(String uid);
	// 扣款支付
	public PayState pay(String uid, double amount) {
		if (queryBalance(uid) < amount) {
			return new PayState(500, "支付失败", "余额不足");
		}
		return new PayState(200, "支付成功", "支付金额:" + amount);
	}
}
public class AliPay extends Payment {
	public String getName() {
		return "支付宝";
	}
	protected double queryBalance(String uid) {
		return 900;
	}
}
public class WechatPay extends Payment {
	public String getName() {
		return "微信支付";
	}
	protected double queryBalance(String uid) {
		return 256;
	}
}
public class UnionPay extends Payment {
	public String getName() {
		return "银联支付";
	}
	protected double queryBalance(String uid) {
		return 120;
	}
}


public class PayState {
	private int code;
	private Object data;
	private String msg;

	public PayState(int code, String msg, Object data) {
		this.code = code;
		this.data = data;
		this.msg = msg;
	}
	public String toString() {
		return ("支付状态:[" + code + "]," + msg + ",交易详情:" + data);
	}
}
public class PayStrategy {
	public static final String ALI_PAY = "AliPay";
	public static final String UNION_PAY = "UnionPay";
	public static final String WECHAT_PAY = "WechatPay";
	public static final String DEFAULT_PAY = ALI_PAY;
	private static Map<String, Payment> payStrategy = new HashMap<String, Payment>();
	static {
		payStrategy.put(ALI_PAY, new AliPay());
		payStrategy.put(WECHAT_PAY, new WechatPay());
		payStrategy.put(UNION_PAY, new UnionPay());
	}

	public static Payment get(String payKey) {
		if (!payStrategy.containsKey(payKey)) {
			return payStrategy.get(DEFAULT_PAY);
		}
		return payStrategy.get(payKey);
	}
}
public class Order {
	private String uid;
	private String orderId;
	private double amount;

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

	public PayState pay() {
		return pay(PayStrategy.DEFAULT_PAY);
	}

	public PayState pay(String payKey) {
		//这样可以避免if..else的使用
		Payment payment = PayStrategy.get(payKey);
		System.out.println("欢迎使用" + payment.getName());
		System.out.println("本次交易金额为:" + amount + ",开始扣款...");
		return payment.pay(uid, amount);
	}

}
public class PayStrategyTest {
	public static void main(String[] args) {

		// 省略把商品添加到购物车,再从购物车下单
		// 直接从点单开始
		Order order = new Order("1", "10995122458", 324.45);
		// 开始支付,选择微信支付、支付宝、银联卡...
		// 每个渠道它支付的具体算法是不一样的
		// 基本算法固定的
		// 这个值是在支付的时候才决定用哪个值
		System.out.println(order.pay(PayStrategy.ALI_PAY));
		
		Order order2 = new Order("1", "10995122459", 1000);
		System.out.println(order2.pay(PayStrategy.WECHAT_PAY));
	}
}

欢迎使用支付宝

本次交易金额为:324.45,开始扣款...

支付状态:[200],支付成功,交易详情:支付金额:324.45


欢迎使用微信支付

本次交易金额为:1000.0,开始扣款...

支付状态:[500],支付失败,交易详情:余额不足



设计模式 策略模式

2020.11.30 23:09

https://www.meihaocloud.com.com/1013.html , 欢迎转载,请在文章页标出原文连接 !


Copyright © 2020 千夕网 联系站长

粤公网安备 44030302001408号 粤ICP备19099833号-1