什么是策略模式官话: 策略模式(strategy pattern): 定义一系列算法类,将每一个算法封装起来,并让它们可以相互替换,策略模式让算法独立于使用它的客户而变化。
简单理解就是,针对不同的场景,使用不同的策略进行处理。
优点算法可以自由切换。避免使用多重条件判断。扩展性良好。缺点策略类会增多。所有策略类都需要对外暴露。使用场景如果在一个系统里面有许多类,它们之间的区别仅在于它们的行为,那么使用策略模式可以动态地让一个对象在许多行为中选择一种行为。一个系统需要动态地在几种算法中选择一种。如果一个对象有很多的行为,如果不用恰当的模式,这些行为就只好使用多重的条件选择语句来实现。结构图
策略模式结构图
策略模式的简单示例场景:最近太热了,想要降降温,有什么办法呢
首先,定义一个降温策略的接口
public interface coolingstrategy { /** * 处理方式 */ void handle();}定义3种降温策略;实现策略接口
public class icecoolingstrategy implements coolingstrategy { @override public void handle() { system.out.println(使用冰块降温); }}public class fancoolingstrategy implements coolingstrategy { @override public void handle() { system.out.println(使用风扇降温); }}public class airconditionercoolingstrategy implements coolingstrategy { @override public void handle() { system.out.println(使用空调降温); }}定义一个降温策略的上下文
public class coolingstrategycontext { private final coolingstrategy strategy; public coolingstrategycontext(coolingstrategy strategy) { this.strategy = strategy; } public void coolinghandle() { strategy.handle(); }}测试
public class main { public static void main(string[] args) { coolingstrategycontext context = new coolingstrategycontext(new fancoolingstrategy()); context.coolinghandle(); context = new coolingstrategycontext(new airconditionercoolingstrategy()); context.coolinghandle(); context = new coolingstrategycontext(new icecoolingstrategy()); context.coolinghandle(); }}运行结果:
使用风扇降温使用空调降温使用冰块降温以上就是一个策略模式的简单实现
策略模式的项目实战场景以我自己在工作中遇到的场景为例,《企业微信会话存档》功能,获取各种格式的消息内容,进行解析并保存数据。这里只针对消息处理的功能模块,其他关于《企业微信会话存档》的功能,有时间整理一下再发出来。
企业微信会话聊天会产生如下多种消息,在springboot项目中应该如何使用策略模式来完成消息的解析呢?
企业微信消息格式
获取会话内容 - api 看api内容,数据都是json格式。思考应该如何处理:
首先,既然要解析各种数据,而每种数据格式结构都不一样,那么就需要先根据每种消息格式定义各自的对象,然后根据不同的需求,将json格式处理成pojo对象;根据场景,需要定义两个策略接口,一个是针对普通的文本格式消息的策略,另一个则是需要处理文件格式消息的策略;定义策略处理上下文操作类,用于使用策略每种消息,都会有一些相同的数据,比如发送人、接收人、消息类型等;根据消息类型的不同,使用 key-value 的方式,让调用者确定应该使用哪个策略来处理数据因为格式太多,这里只使用两个格式作为例子
实现两个策略接口
public interface strategy { /** * 处理会话存档的内容 * * @param content json格式的消息内容 * @return 结果 */ t handlecontent(string content);}public interface mediastrategy { /** * 处理会话存档媒体内容 * * @param msgdata 消息内容 */ void handlemedia(t msgdata);}策略的具体实现(伪代码)
@component(link)public class linkstrategy implements strategy { @override public linkpo handlecontent(string content) { // json 转换为具体对象 linkwrapdto linkwrapdto = jacksonutils.json2obj(content, linkwrapdto.class); // 将对象处理成业务需要的格式 return convert.convert(linkpo.class, linkwrapdto); }}@component(image)public class imagestrategy implements strategy, mediastrategy { @autowired private imsgfileservice msgfileservice; @override public imagepo handlecontent(string content) { // json 转换为具体对象 imagewrapdto imagewrapdto = jacksonutils.json2obj(content, imagewrapdto.class); // 将对象处理成业务需要的格式 return convert.convert(imagepo.class,imagewrapdto); } @override public void handlemedia(t msgdata) { // 将数据格式转换为具体实现的数据格式 imagepo imagepo = convert.convert(imagepo.class, msgdata); // 调用文件服务,进一步处理文件 msgfileservice.newfiletask(imagepo.getimage().getsdkfileid(), imagepo.getmsgid() + .jpg, imagepo.getmsgid(), imagepo.getseq(), imagepo.getimage().getfilesize(), imagepo.getimage().getmd5sum(), messageenum.image); }}策略上下文
@componentpublic class strategycontext { @resource map strategys = new concurrenthashmap(); @resource map mediastrategys = new concurrenthashmap(); public strategy getstrategy(string component) { return strategys.get(component); } public mediastrategy getmediastrategy(string component) { return mediastrategys.get(component); }}使用方式(伪代码)
public class msgservice { @resource private strategycontext strategycontext; public void handlermessage() { // 请求api获取消息的json json = api(); // 转为通用格式对象 basepo = jsonutils.json2obj(json, basepo.class); // 选取不同的策略 strategy strategy = strategycontext.getstrategy(basepo.getmsgtype()); // 进行处理 strategy.handlecontent(json); // 关于文件类消息的处理 mediastrategy mediastrategy = strategycontext.getmediastrategy(basepo.getmsgtype()); if (null != mediastrategy) { mediastrategy.handlemedia(basepo); } }}以上就是策略模式的一种实现方式;
使用策略模式来处理不同格式的消息,虽然多了很多策略类,但是让整个功能模块的代码变得清晰,松耦合,而且很容易扩展和修改,并不会影响其他流程。
小结从以上的例子很明显的可以看出,策略模式的灵活性;如果此时企业微信提供了一种新的消息格式,那么根本无需修改之前的代码,只需要再写一个新的类,实现消息处理策略的接口,重写处理方法即可;
了解策略模式的优点和缺点,合理的使用策略模式,会让你的代码更加的整洁优雅。
一文详解什么是逆功率保护
手机护眼模式真的有用吗?
长城上架国产芯片笔记本:飞腾处理器+中国船舶重工709所独显
车载摄像头防水检测的作用
开箱评测:研华边缘智能系统EI-52
什么是策略模式
垄断锂电池价格,松下、索尼遭欧盟罚款12亿
NaviForum 将于今年9月 再度登陆上海
光模块的5种WDM波分复用技术,你都知道吗?
防水连接器是什么,它的优势是怎样的
京东正在投资虚拟和增强现实技术打造线上和线下全新的购物场景
5G对智能网联汽车意味着什么?
航空航天企业被打压 美将7家中国实体列入出口管制清单
高通不愧是5G商用领先人 已在多个频段均推出重磅产品
工信部将积极维护良好的5G国际发展环境
亿纬锂能官宣200亿电池项目!
军事MRO:通过增强现实解决维护技能短缺问题
微孔滤膜的基本原理与分类是怎样的
户外运动选什么蓝牙耳机好?入耳式还是骨传导?
STC单片机实现电开水机自动供水的设计