蓝盟IT小贴士,来喽!
1 .策略模式
1.1业务场景
假设有这样的业务场景,大数据系统推送文件,根据类型不同采取不同的分析方式。 大多数伙伴都会写下面的代码。
if (类型=' a ' ) {
根据//A格式进行分析
else if (类型=' b ' ) {
用//B格式进行分析
}else{
//用默认格式进行分析
}
这个代码可能有什么问题?
分支变多,这里的代码就会变得肥大,难以维护,可读性变低。
如果需要访问新的分析类型,则只能用原始代码进行修改。
从专业角度来说,上述代码违背了面向对象编程的开闭原则和单一原则。
要添加或删除某些逻辑(对扩展是开放的,但对修改是封闭的),必须修改为原始代码
单一原则(规定一个类只有一个更改的原因)要更改任何类型的分支逻辑代码,必须更改当前类的代码。
如果您的代码是味增:有多个条件分支(如if.else ),并且每个条件分支都将被封装和替换,则可以使用策略模式进行优化。
1.2策略模式的定义
策略模型定义算法系列,并单独封装,以便彼此替换。 该模型使算法的变化独立于使用算法的客户。 这个战略模型的定义有点抽象吧? 让我们来看看一个简单易懂的比喻:
如果要和性格不同的姐姐约会的话,有必要使用各种各样的战略。 有些人最好请电影,有些人去吃小吃很有效果,有些人去买东西不停地买最合适。 当然,目的是得到姐姐的心。 看电影、吃小吃、购物是不同的策略。
对于一组算法,策略模式将每个算法封装到一个具有公共接口的独立类中,这样它们就可以相互替换。
1.3使用策略模式
如何使用战略模式? 实现了紫色:
一个接口或抽象类,里面的两个方法(一个方法匹配类型,另一个可替换的逻辑实现方法) )。
不同战略的差异化实现(即不同战略的实现类) )。
使用策略模式
1.3.1一个接口、两种方法
公共界面文件存储
//属于哪种文件分析类型
filetyperesolveenumgainfiletype (;
//软件包的通用算法(具体分析方法)
声音解析(对象对象参数;}
1.3.2实现不同战略的差异化
类型a政策的具体实施
@Component
publicclassafileresolveimplementsifilestrategy {
@Override
publicfiletyperesolveenumgainfiletype {
returnfiletyperesolveenum .文件_ a _解析;
}
@Override
公共语音解析(对象对象参数) {
logger.info (类型a分析文件,参数: {} )、对象参数);
//A类型分析具体逻辑
}
}
b类政策的具体实施
@Component
publicclassbfileresolveimplementsifilestrategy {
@Override
publicfiletyperesolveenumgainfiletype {
returnfiletyperesolveenum .文件_ b _解析;
}
@Override
公共语音解析(对象对象参数) {
logger.info (类型b解析文件,参数: {} )、对象参数);
//B类型分析具体逻辑
}
}
默认类型策略的具体实现
@Component
publicclassdefaultfileresolveimplementsifilestrategy {
@Override
publicfiletyperesolveenumgainfiletype {
returnfiletyperesolveenum .文件_默认_解决;
}
@Override
公共语音解析(对象对象参数) {logger.info ('缺省类型解析文件,参数: {} ',对象参数);
//缺省类型分析的具体逻辑
}
}
1.3.3使用策略模式
怎么用? 利用spring的生命周期,使用应用程序上下文界面将使用的策略初始化为map。 然后对外提供resolveFile方法即可。
//*
* @author公众号:拾田螺的少年
*/
@Component
publicclassstrategyuseserviceimplementsapplicationcontextaware {
私有地图小于FileTypeResolveEnum,IFileStrategy大于ifilestrategymap=newconcurrenthashmap小于();
公共对象解析文件(文件类解析器文件类解析器,对象对象参数)
ilestrategyifilestrategy=ifilestrategymap.get (文件类型辅助卷);
文件战略!=空值) {
文件存储解决方案(对象参数);
}
}
//将不同的战略置于map
@Override
公共应用程序上下文(应用程序上下文) throws bean扩展{
贴图小于字符串,IFileStrategy大于TMEPMAP应用程序上下文. getbeansoftype (ifile strategy.class );
TM epmap.values (.策略服务-文件存储映射.输出)策略服务.增益文件类型,策略服务)}
}
2 .责任链模式
2.1业务场景
看看一般的商业场景,下单吧。 订单接口、基本逻辑有参数非空检查、安全检查、黑名单检查、规则拦截等。 许多合作伙伴通过例外来实现:
公共类订单{2}
公共对象参数(对象参数) {
//参数非空检查
新运行时执行(;
}
公共语音检查安全性(
//安全检查
新运行时执行(;
}
公共语音检查清单(
//黑名单检查
新运行时执行(;
}
公共语音检查规则
//拦截规则
新运行时执行(;
}
publicstaticvoidmain (字符串[ ]数组) {
订单=新订单(;
特里
order.checkNullParam (;
order.checkSecurity (;
order.checkBackList (;
order2.检查规则(;
system.out.println (订单成功);
} catch (运行时环境) {
系统.输出.打印(订单故障);
}
}
}
这个代码使用例外来判断逻辑条件。 如果后续的逻辑越来越复杂,则会出现异常只返回异常消息,不返回更多字段的问题。 在这种情况下,需要自定义异常类。而且,根据蚂蚁开发手册,禁止异常地进行逻辑判断。
【强制】请不要将异常用于流量控制、条件控制。 说明:异常设计的初衷是解决程序执行中的各种意外情况,异常的处理效率比条件判断方式要低得多。
如何优化这段代码? 可以考虑责任链模型
2.2责任链模型的定义
如果希望多个伙伴能够处理某个请求,请使用责任链接模式。
在责任链模式下,将为请求创建收件人对象链。 执行链中有多个对象节点,每个对象节点有处理请求事务处理的机会(条件一致),如果某个对象节点处理完毕,则可以根据实际的业务需要交给下一个节点继续处理或返回处理完毕这个模式给出了请求的类型,将请求的发送者和接收者解耦。
责任链模式实际上是处理请求的模式,允许多个处理器(对象节点)处理请求直到其中一个处理成功。 责任链模式链接多个处理器,并在链上传递请求。
责任链模式
打个比喻:
假设晚上去上选修课,为了能走一会儿坐在最后一排。 来到教室,发现前面坐着好几个漂亮的姐姐。 于是,我找了张纸条,说:“你好,可以做我的女朋友吗? 如果不愿意的话请事先告诉我”。 陆续收到了笔记,送到了第一排妹妹手里。 她把笔记交给了老师。 听说老师40多岁未婚.
2.3使用责任链模式
如何使用责任链模式?
接口或抽象类
每个对象的差别化处理
对象链(数组的初始化)连接) ) ) )。
2.3.1一个接口或抽象类
这个接口或抽象类必须:
包含责任的以下对象的属性
设置下一个对象的set方法
如何在子类对象上实现差别化。 例如,以下代码的doFilter方法)
文/上海蓝盟 IT外包专家