1.1 策略模式概念
策略模式:定义了算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。
1.2 策略模式结构
策略模式的结构包括三种角色:
策略模式接口的类图如下所示:
1.3 常规策略模式不足点
在我们平时写的策略模式代码中,具体采用哪个策略实现类,是在Context类中通过入参来判断的,如果随着需求扩展,需要增加一个新的策略实现类,必定要来修改Context类,这就违背了【开闭原则】。如果能做到:有新的策略实现需要增加时,只需要新建一个策略实现类,去实现策略接口就完事,其他旧代码完全不用修改。这才是我心目中的【开闭原则】,可喜的是,利用@Autowired注解与策略模式搭配,就能实现这一目标。
2.1 @Autowired自动装配多个实例
平时我们一般都是通过@Autowired自动装配单个实例,但这里我会告诉你,它也能自动装配多个实例。
2.2 @Autowired实现自动装配多个实例
用一个List集合接收IUser类型的参数
@Service
public class UserService {
@Autowired
private List userList;
@Autowired
private Set userSet;
@Autowired
private Map userMap;
public void test() {
System.out.println("userList:" + userList);
System.out.println("userSet:" + userSet);
System.out.println("userMap:" + userMap);
}
}
增加一个controller
@RequestMapping("/u")
@RestController
public class UController {
@Autowired
private UserService userService;
@RequestMapping("/test")
public String test() {
userService.test();
return "success";
}
}
userList、userSet和userMap都打印出了两个元素,说明@Autowired会自动把相同类型的IUser对象收集到集合中。
2.3 利用@Autowired自动装配多个实例与策略模式搭配
利用@Autowired自动装配多个实例与策略模式来搭配使用,变种后的策略模式:
3.1 需求背景
在我们平时开发的项目中,大部分都会有App站外推送的功能,通常,我们一般都会采用第三方推送集成平台,如某盟或某光。但我们项目为了更高的推送到达率以及更灵活的推送配置功能,我们采用了对接各厂商官方的推送平台的方式,比如对接华为、小米、Oppo等。这个需求场景就非常适合采用策略模式来开发,这次我们用@Autowired搭配策略模式来实现。
3.2 代码实现
/**
* 推送策略类
*/
public interface IPushStrategy {
/**
* @param userId:用户ID
* @param msg:推送消息
* @param supplier:推送供应商
* @return
*/
boolean push(Long userId, String msg, String supplier);
}
/**
* 华为推送策略
*/
@Service
public class HuaWeiPushService implements IPushStrategy {
@Override
public boolean push(Long userId, String msg, String supplier) {
if ("HuaWei".equals(supplier)) {
System.out.println("华为推送给用户" + userId + ",推送消息:" + msg);
return true;
}
return false;
}
}
/**
* Oppo推送策略
*/
@Service
public class OppoPushService implements IPushStrategy {
@Override
public boolean push(Long userId, String msg, String supplier) {
if ("Oppo".equals(supplier)) {
System.out.println("Oppo推送给用户" + userId + ",推送消息:" + msg);
return true;
}
return false;
}
}
/**
* 小米推送策略
*/
@Service
public class XiaoMiPushService implements IPushStrategy {
@Override
public boolean push(Long userId, String msg, String supplier) {
if ("XiaoMi".equals(supplier)) {
System.out.println("小米推送给用户" + userId + ",推送消息:" + msg);
return true;
}
return false;
}
}
/**
* 推送策略context
*/
@Component
public class PushContext implements IPushStrategy {
@Autowired
private List pushStrategyList;
@Override
public boolean push(Long userId, String msg, String supplier) {
boolean supplierMatched = false;
for (IPushStrategy pushStrategy : pushStrategyList) {
supplierMatched = pushStrategy.push(userId, msg, supplier);
if (supplierMatched) {
break;
}
}
return supplierMatched;
}
}
@Api(tags = "推送策略模式")
@RestController
@RequestMapping("strategy")
public class TestController {
@Resource
private PushContext pushContext;
@ApiOperation(value = "推送")
@GetMapping("push")
public boolean push() {
Long userId = 273L;
String msg = "您有新的订单";
String supplier = "HuaWei";
//调用的是华为推送实现策略
return pushContext.push(userId, msg, supplier);
}
}
3.3 后续故事
声明:以下故事纯属虚构,如有雷同,纯属巧合。
突然,某一天,产品小姐姐跑过来说,我们今天要完成Vivo推送平台的开发和相关功能测试,今天上线,行不行?
这时,我以往心中的那一万匹马这次竟然不见了,我嘴角微微上扬,露出我富有职业素养、标准而又职业的微笑,回答道:行(男人不能说不行)。 我回到工位,新建了一个Vivo推送的策略实现类并进行实现。
幸运的是,之前那些经过测试小妹妹九九八十一次测试好的推送功能代码,一行都不需要改动,保证了程序的稳定性,更降低了测试成本。此时,【开闭原则】在我的心中闪闪发光。
页面更新:2024-04-10
本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828
© CopyRight 2008-2024 All Rights Reserved. Powered By bs178.com 闽ICP备11008920号-3
闽公网安备35020302034844号