策略模式基本概念
策略模式是对算法的包装,是把使用算法的责任和算法本身分割开来,委派给不同的对象管理,最终可以实现解决多重if判断问题。
1.环境(Context)角色:持有一个Strategy的引用。
2.抽象策略(Strategy)角色:这是一个抽象角色,通常由一个接口或抽象类实现。此角色给出所有的具体策略类所需的接口。
3.具体策略(ConcreteStrategy)角色:包装了相关的算法或行为。
定义策略接口->实现不同的策略类->利用多态或其他方式调用策略
抽象行为概念:都是在做同一件事情,底层实现不一样。
多重if判断问题 有多个不同的策略情况下, 选择其中一种策略模式。
策略模式应用场景
- 异步实现发送短信 比如阿里云、腾讯云、其他短信渠道等
- 聚合支付系统 银联支付、支付宝、微信支付等
- 联合登陆 QQ、钉钉、微信联合登陆渠道等
策略模式实现的方式
基于工厂模式实现
public interface MsgStrategy { String sendMsg(); }
public class AliYunStrategy implements MsgStrategy { public String sendMsg() { return "阿里云"; } } public class HuaWeiStrategy implements MsgStrategy { public String sendMsg() { return "华为云"; } } public class TencentStrategy implements MsgStrategy { public String sendMsg() { return "腾讯云"; } }
|
public class FactoryStrategy { /** * 存放策略的容器 */ private static Map<String, MsgStrategy> strategys = new ConcurrentHashMap<String, MsgStrategy>(); static { strategys.put("aliYunStrategy", new AliYunStrategy()); strategys.put("tencentStrategy", new TencentStrategy()); strategys.put("huaWeiStrategy", new HuaWeiStrategy()); } public static MsgStrategy getMsgStrategy(String strategyId) { return strategys.get(strategyId); } }
|
基于数据库模式实现
数据库表结构
DROP TABLE IF EXISTS `meite_strategy`; CREATE TABLE `meite_strategy` ( `ID` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID', `strategy_NAME` varchar(32) NOT NULL COMMENT '策略名称', `strategy_ID` varchar(32) NOT NULL COMMENT '策略ID', `strategy_type` varchar(32) NOT NULL COMMENT '策略ID', `strategy_bean_id` varchar(255) DEFAULT NULL COMMENT '策略执行beanid', PRIMARY KEY (`ID`) ) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8 COMMENT='策略';
-- ---------------------------- -- Records of meite_strategy -- ---------------------------- INSERT INTO `meite_strategy` VALUES ('6', '腾讯云', 'tencent_sms', 'send_msg', 'tencentStrategy'); INSERT INTO `meite_strategy` VALUES ('7', '阿里云', 'aliYun_sms', 'send_msg', 'aliYunStrategy'); INSERT INTO `meite_strategy` VALUES ('8', '华为云', 'huaWei_sms', 'send_msg', 'huaWeiStrategy'); INSERT INTO `meite_strategy` VALUES ('9', '阿里Pay', 'ali_pay', 'pay', 'aliPayStrategy'); INSERT INTO `meite_strategy` VALUES ('10', '银联Pay', 'yinlian_pay', 'pay', 'unionPayStrategy');
|
根据策略ID查询策略
@Component public class StrategyManage { @Autowired private StrategyMapper strategyMapper; public <T> T getStrategy(String strategyId, String strategyType, Class<T> t) { if (StringUtils.isEmpty(strategyId)) { return null; } if (StringUtils.isEmpty(strategyType)) { return null; } if (t == null) { return null; } QueryWrapper tQueryWrapper = new QueryWrapper<>(); tQueryWrapper.eq("strategy_id", strategyId); MeiteStrategy meiteStrategy = strategyMapper.selectOne(tQueryWrapper); String strategyBeanId = meiteStrategy.getStrategyBeanId(); if (StringUtils.isEmpty(strategyBeanId)) { return null; } return SpringUtils.getBean(strategyBeanId, t); } } 策略模式可以减少多重if判断,同一种行为不同实现用一种策略去获取不一样的bean,减少代码的冗余 |