设计模式------策略模式
目录
1、什么是策略模式
什么是策略模式呢?他就是定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化,不会影响到使用算法的客户。
打个比方,我们出门的时候会选择不同的出行方式,比如骑自行车、坐公交、坐火车、坐飞机、坐火箭等等,这些出行方式,每一种都是一个策略。
再比如我们去逛商场,商场现在正在搞活动,有打折的、有满减的、有返利的等等,其实不管商场如何进行促销,说到底都是一些算法,这些算法本身只是一种策略,并且这些算法是随时都可能互相替换的,比如针对同一件商品,今天打八折、明天满100减30,这些策略间是可以互换的。
2、策略模式结构图
- 策略模式共分为三种角色:
- Context(上下文环境):持有抽象策略类,调用策略方法。
- Strategy(抽象策略类):声明策略方法。
- Concrete Strategy(具体策略类):实现策略方法。
- Context持有Stategy的引用,完成对ConcreteStrategy中策略方法的调用。
3、适用的场景
1、如果在一个系统里面有许多类,它们之间的区别仅在于它们的行为,那么使用策略模式可以动态地让一个对象在许多行为中选择一种行为。
2、一个系统需要动态地在几种算法中选择一种。
3、如果一个对象有很多的行为,如果不用恰当的模式,这些行为就只好使用多重的条件选择语句来实现。
4、优点与缺点
优点: (1)算法可以自由切换。
(2)避免使用多重条件判断。
(3)扩展性良好。
缺点:(1)策略类会增多。
(2)所有策略类都需要对外暴露。
5、模式的实例演示
下面的代码采用策略模式演示电商的支付方式
/**
* @description: 消息
* @author: zps
* @create: 2020-05-04 16:40
**/
@Data
public class MsgResult {
private int code;
private Object object;
private String msg;
public MsgResult(int code, Object object, String msg) {
this.code = code;
this.object = object;
this.msg = msg;
}
}
/**
* @description: 支付抽象类
* @author: zps
* @create: 2020-05-04 16:42
**/
public abstract class Payment {
//支付名称
public abstract String getName();
//支付
public MsgResult pay(String uid , double amount){
if(queryBalance(uid) < amount){ //余额不足
return new MsgResult(500 , "支付失败" , "余额不足!");
}
return new MsgResult(200 , "支付成功" , "余额:" + amount);
}
//钱包与余额
protected abstract double queryBalance(String uid);
}
/**
* @description: 支付宝支付
* @author: zps
* @create: 2020-05-04 16:46
**/
public class AliPay extends Payment {
@Override
public String getName() {
return "支付宝";
}
@Override
protected double queryBalance(String uid) { //默认余额900
return 900;
}
}
/**
* @description: 京东白条
* @author: zps
* @create: 2020-05-04 16:47
**/
public class JDPay extends Payment{
@Override
public String getName() {
return "京东白条";
}
@Override
protected double queryBalance(String uid) {
return 500;
}
}
/**
* @description: 微信支付
* @author: zps
* @create: 2020-05-04 16:48
**/
public class WebPay extends Payment {
@Override
public String getName() {
return "微信支付";
}
@Override
protected double queryBalance(String uid) {
return 1000;
}
}
/**
* @description: 支付策略上下文
* @author: zps
* @create: 2020-05-04 16:53
**/
public class PayStrategy {
public static final String ALI_PAY = "AliPay";
public static final String DJ_PAY = "DjPay";
public static final String WEB_PAY = "WebPay";
public static final String DEFAULT = "AliPay";
//把支付方式保存起来,其实这个相当与一个单例加简单工厂模式
private static Map<String , Payment> strategy = new HashMap<>();
static {
strategy.put(ALI_PAY , new AliPay());
strategy.put(DJ_PAY , new JDPay());
strategy.put(WEB_PAY , new WebPay());
}
//根据key获取支付的方式
public static Payment get(String payKey){
if(!strategy.containsValue(payKey)){
return strategy.get(DEFAULT);
}
return strategy.get(payKey);
}
}
**
* @description: 订单
* @author: zps
* @create: 2020-05-04 16:50
**/
@Data
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 MsgResult pay(){ //默认采用支付宝支付
return pay(PayStrategy.DEFAULT);
}
public MsgResult pay(String payKey){
Payment payment = PayStrategy.get(payKey);
System.out.println("欢迎使用" + payment.getName());
System.out.println("本次交易金额为" + amount + ",开始扣款");
return payment.pay(uid , amount);
}
}
/**
* @description: 测试
* @author: zps
* @create: 2020-05-04 17:04
**/
public class Test {
public static void main(String[] args) {
Order order = new Order("1" , "sdfdff" , 12);
System.out.println(order.pay(PayStrategy.DJ_PAY));
System.out.println("---------------------------------");
Order order2 = new Order("2" , "sdfdddddff" , 1200);
System.out.println(order2.pay(PayStrategy.DJ_PAY));
}
}
运行结果: