策略模式
2018-11-16 本文已影响0人
cjxz
策略模式
- 定义
既定的目标是固定的,在实现这个目标的过程中可以有多种方法。将每种方法封装起来,在运行中可以随意的选择不同的方法实现既定目标。
- 特点
- 目标已经确定
- 实现这个目标的方法很多
- 处理了多个if else问题
具体应用场景
- 购物时支付方式的选择
- 出发旅行目的地已定是选择什么交通工具,坐飞机,开车,火车,自行车,走路
- Spring的BeanFactory,读取配置文件的方式不同可以从classpath,url等
实现方式
以购物支付方式的选择为例看一下如何采用策略模式实现支付方式的操作。
-
不采用策略模式的情况下是这样的
类图
package com.pattern.strategy.not.order;
/**
* @Author: chao.zhu
* @description: 不采用策略模式支付
* @CreateDate: 2018/11/16
* @Version: 1.0
*/
public class Order {
private Long orderId;
private String orderList;
private Double amount;
public Order(Long orderId, String orderList, Double amount) {
this.orderId = orderId;
this.orderList = orderList;
this.amount = amount;
}
public PayResult pay(Integer payType){
PayResult payResult = null;
if(payType.equals(PayConstant.ALI_PAY)){
System.out.println("欢迎!支付宝支付为你服务");
System.out.println("支付开始");
payResult = new PayResult(200,"支付宝,支付成功","成功扣款"+amount);
}else if(payType.equals(PayConstant.WECHAT_PAY)){
System.out.println("欢迎!微信红包支付为你服务");
System.out.println("支付开始");
payResult = new PayResult(200,"微信红包支付成功","成功扣款"+amount);
}else if(payType.equals(PayConstant.UNION_PAY)){
System.out.println("欢迎!银联支付为你服务");
System.out.println("支付开始");
payResult = new PayResult(200,"银联支付成功","成功扣款"+amount);
}else if(payType.equals(PayConstant.QQ_PAY)){
System.out.println("欢迎!财付通为你服务");
System.out.println("支付开始");
payResult = new PayResult(200,"财付通支付成功","成功扣款"+amount);
}else{
System.out.println("您选择的支付方式暂未开通");
payResult = new PayResult(404,"未能找到你选择的支付方式","没有扣款"+amount);
}
return payResult;
}
}
package com.pattern.strategy.not.order;
/**
* @Author: chao.zhu
* @description:
* @CreateDate: 2018/11/16
* @Version: 1.0
*/
public class PayConstant {
public static final Integer ALI_PAY = 1;
public static final Integer WECHAT_PAY = 2;
public static final Integer UNION_PAY = 3;
public static final Integer QQ_PAY = 4;
}
package com.pattern.strategy.not.order;
/**
* @Author: chao.zhu
* @description:
* @CreateDate: 2018/11/16
* @Version: 1.0
*/
public class PayResult {
private Integer code;
private String message;
private Object data;
public PayResult(Integer code, String message, Object data) {
this.code = code;
this.message = message;
this.data = data;
}
public PayResult(){
}
public String toString(){
return "支付状态 【"+code+"】"+",支付消息:"+message+",返回数据:"+data;
}
}
package com.pattern.strategy.not.order;
import java.util.Scanner;
/**
* @Author: chao.zhu
* @description:
* @CreateDate: 2018/11/16
* @Version: 1.0
*/
public class Client {
public static void main(String[] args) {
Order order = new Order(98433849L,"iphoneX,ipad,imax",16769.99);
//用户选择支付方式
Scanner scan = new Scanner(System.in);
String read = scan.nextLine();
Integer payType = Integer.valueOf(read);
PayResult result = order.pay(payType);
System.out.println(result.toString());
}
}
存在的问题:
- 不符合对修改关闭,对扩展开发的开闭原则。因为如果新增了支付方式,需要修改订单对象的pay方法,只要是修改订单的方法就存在修改出现问题的情况
- 多层次的if else条件判断
-
采用策略模式的情况
采用策略模式的支付系统
package com.pattern.strategy.yes.order;
import com.pattern.strategy.not.order.PayResult;
/**
* @Author: chao.zhu
* @description:
* @CreateDate: 2018/11/16
* @Version: 1.0
*/
public interface Payment {
PayResult pay(Double amount);
}
package com.pattern.strategy.yes.order;
import com.pattern.strategy.not.order.PayResult;
/**
* @Author: chao.zhu
* @description:
* @CreateDate: 2018/11/16
* @Version: 1.0
*/
public class AliPay implements Payment {
@Override
public PayResult pay(Double amount) {
System.out.println("欢迎!支付宝支付为你服务");
System.out.println("支付开始");
PayResult payResult = new PayResult(200,"支付宝,支付成功","成功扣款"+amount);
return payResult;
}
}
package com.pattern.strategy.yes.order;
import com.pattern.strategy.not.order.PayResult;
/**
* @Author: chao.zhu
* @description:
* @CreateDate: 2018/11/16
* @Version: 1.0
*/
public class WechatPay implements Payment {
@Override
public PayResult pay(Double amount) {
System.out.println("欢迎!微信红包支付为你服务");
System.out.println("支付开始");
PayResult payResult = new PayResult(200,"微信红包支付成功","成功扣款"+amount);
return payResult;
}
}
package com.pattern.strategy.yes.order;
import com.pattern.strategy.not.order.PayResult;
/**
* @Author: chao.zhu
* @description:
* @CreateDate: 2018/11/16
* @Version: 1.0
*/
public class UnionPay implements Payment {
@Override
public PayResult pay(Double amount) {
System.out.println("欢迎!银联支付为你服务");
System.out.println("支付开始");
PayResult payResult = new PayResult(200,"银联支付成功","成功扣款"+amount);
return payResult;
}
}
package com.pattern.strategy.yes.order;
import com.pattern.strategy.not.order.PayResult;
/**
* @Author: chao.zhu
* @description:
* @CreateDate: 2018/11/16
* @Version: 1.0
*/
public class QQPay implements Payment {
@Override
public PayResult pay(Double amount) {
System.out.println("欢迎!财付通为你服务");
System.out.println("支付开始");
PayResult payResult = new PayResult(200,"财付通支付成功","成功扣款"+amount);
return payResult;
}
}
package com.pattern.strategy.yes.order;
import com.pattern.strategy.not.order.PayConstant;
import com.pattern.strategy.not.order.PayResult;
/**
* @Author: chao.zhu
* @description: 采用策略模式支付
* @CreateDate: 2018/11/16
* @Version: 1.0
*/
public class Order {
private Long orderId;
private String orderList;
private Double amount;
public Order(Long orderId, String orderList, Double amount) {
this.orderId = orderId;
this.orderList = orderList;
this.amount = amount;
}
public PayResult pay(Payment payment){
PayResult payResult = payment.pay(amount);
return payResult;
}
}
package com.pattern.strategy.yes.order;
import com.pattern.strategy.not.order.PayResult;
/**
* @Author: chao.zhu
* @description:
* @CreateDate: 2018/11/16
* @Version: 1.0
*/
public class Client {
public static void main(String[] args) {
Order order = new Order(98433849L,"iphoneX,ipad,imax",16769.99);
//用户选择支付方式
Payment payment = new AliPay();
PayResult result = order.pay(payment);
System.out.println(result.toString());
}
}
采用策略模式后的支付系统不用担心新增支付方式修改订单逻辑。只需要继承Payment就可以多一种支付方式。满足『对修改关闭,对扩展打开』的开闭原则。也去掉了N多个if-else逻辑判断。优势明显。
- 进一步优化一下上面代码
增加一个枚举类型,因为支付方式是固定的,我们不需要每次在Client中new新的支付方式。代码如下
package com.pattern.strategy.yes.order;
/**
* @Author: chao.zhu
* @description:
* @CreateDate: 2018/11/16
* @Version: 1.0
*/
public enum PayTypeEnum {
AliPay(new AliPay()),WechatPay(new WechatPay()),UnionPay(new UnionPay()),QQPay(new QQPay());
private Payment payment;
PayTypeEnum(Payment payment){
this.payment = payment;
}
public Payment get(){
return this.payment;
}
}
package com.pattern.strategy.yes.order;
import com.pattern.strategy.not.order.PayResult;
/**
* @Author: chao.zhu
* @description:
* @CreateDate: 2018/11/16
* @Version: 1.0
*/
public class ClientV2 {
public static void main(String[] args) {
Order order = new Order(98433849L,"iphoneX,ipad,imax",16769.99);
PayResult result = order.pay(PayTypeEnum.QQPay.get());
System.out.println(result.toString());
}
}
以上就是策略模式。
当目标固定(达到支付的目的)需要到达这个目的的算法有许多中(微信支付,支付宝,银联,财付通)我们将所有算法罗列出来,在运行过程中可以随意切换算法达到我们的目的