设计模式之策略模式

为什么需要使用到设计模式:

使用设计模式可以重构整体架构代码,可以使代码提高复用性,扩展性,减少代码冗余问题。

什么是策略模式:

策略模式是对算法的包装,是把使用算法的责任和算法本身分隔开来,委派给不同的对象管理,最终可以实现解决多重if判断问题:

为什么叫策略模式:

每个if判断都可以理解为就是一个策略。

 public String toPay(String payCode){
            if(payCode.equals("ali_pay")){
               return "调用支付宝接口支付";
            }
            if(payCode.equals("weixin_pay")){
               return "调用微信支付接口支付";
            }
            if(payCode.equals("yinlian_pay")){
               return "调用银联支付接口支付";
            }
            return "未找到该支付接口";
    }

我们来看上面一段代码,我们传不同的payCode,得到对应的支付平台,调用接口行为是相同的,调用接口代码是不同的,

我们来用策略模式实现下:

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

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

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

定义策略接口-》实现不同的策略类-》利用多态或其他方式调用策略。

我们来创建共同的行为:

public interface PayStrategy {

    /**
     * 共同方法行为
     * @return
     */
    public String toPay();
}

具体策略实现:

public class AliPayStrategy implements PayStrategy {
    @Override
    public String toPay() 
        return "调用支付宝接口。。。。。";
    }
}

public class WeXinPayStrategy implements PayStrategy {


    @Override
    public String toPay() {
        return "调用微信支付接口。。。。。";
    }
}

public class XiaoMiPayStrategy implements PayStrategy {

    @Override
    public String toPay() {
        return "调用小米支付接口。。。。。";
    }
}

策略枚举类   所有策略的具体实现:

public enum PayEnumStrategy {
    /**
     * 支付宝支付
     */
    ALI_PAY("com.zigao.com.strategy.impl.AliPayStrategy"),

    /**
     * 微信支付
     */
    WEICHAT_PAY("com.zigao.com.strategy.impl.WeXinPayStrategy"),

    /**
     * 小米支付
     */
    XIAOMI_PAY("com.zigao.com.strategy.impl.XiaoMiPayStrategy");

    /**
     * 完整地址
     */
   private String className;

    PayEnumStrategy(String className) {
        this.className = className;
    }

   public String getClassName() {
        return className;
    }

    public void setClassName(String className) {
        this.className = className;
    }
}

使用策略工厂获取具体测虐实现:

public class StrateFactory {

    public static PayStrategy  getPayStrategy(String strategyType){
       try {
            //1:获取枚举类中classname
            String classname = PayEnumStrategy.valueOf(strategyType).getClassName();
             //2:使用java反射技术初始化类
            return (PayStrategy)Class.forName(classname).newInstance();
       }catch (Exception e){
           return null;
       }
    }

}

使用Context上下文获取具体策略实现:
@Component
public class PayContextStrategy {

    /**
     * 获取具体策略实现
     */
    public String toPayHtml(String payCode){
        //判断是否为空
        if(StringUtils.isEmpty(payCode)){
            return "payCode======>>>>>不能为空";
        }
        //使用策略工厂获取具体策略实现
        PayStrategy payStrategy = StrateFactory.getPayStrategy(payCode);
        if(payStrategy == null){
              return "没有找到具体策略实现。。。。。";
        }
        return payStrategy.toPay();
    }
}

总代代码实现完了,我们来测试下:

@RestController
@RequestMapping("/pay")
public class PayController{

    //打印日志
    public Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private PayContextStrategy payContextStrategy;

    @PostMapping("/toPay")
    public ResponseMessage upload(@RequestBody Map map) {
        ResponseMessage responseMessage = new ResponseMessage(0);
        try {
            String payCode = (String) map.get("payCode");
            String payHtml = payContextStrategy.toPayHtml(payCode);
            responseMessage.setMessage(payHtml);
        } catch (Exception e) {
            logger.error("调用支付异常,", e);
            throw new RuntimeException(e.getMessage());
        }
        return responseMessage;
    }

}

上面虽然实现了,但是还是不完美,我们用另一种方式实现。

通过bean对象注入的方式实现:

<bean id = "weXinPayStrategy" class = “com.zigao.com.strategy.impl.WeXinPayStrategy”>

  使用类名小写名称  从Spring容器中获取具体策略对象;

这些可以放到数据库中


SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for payment
-- ----------------------------
DROP TABLE IF EXISTS `payment`;
CREATE TABLE `payment`  (
  `id` int(10) NOT NULL,
  `channel_name` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `channel_id` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `strategy_bean_id` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of payment
-- ----------------------------
INSERT INTO `payment` VALUES (1, '支付宝支付实现', 'ALI_PAY', 'aliPayStrategy');
INSERT INTO `payment` VALUES (2, '微信宝支付实现', 'WEICHAT_PAY', 'weXinPayStrategy');
INSERT INTO `payment` VALUES (3, '小米宝支付实现', 'XIAOMI_PAY', 'xiaoMiPayStrategy');

SET FOREIGN_KEY_CHECKS = 1;

 

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值