餐厅老板要累疯了No.2
我是小蕉。
从前有座山,山里有座庙,庙里有个老和尚,阿不,有个餐厅的老板,在每天午餐之前,都要自己亲力亲为为各个小伙伴分配任务,大喊一声开饭啦,大家就屁颠屁颠跑过来领任务。炒菜嘛,就交给A来做,他的厨艺好。搬桌子嘛,交给B来做,他身强力壮。煮饭嘛,交给C来做,他比较细心。陪客人唠嗑嘛,就交给小蕉,毕竟他嘴皮子可厉害了。每天都这样,虽然很累,但老板倒也乐此不疲。直到有一天。
餐厅发展越来越好,员工越来越多,老板的员工达到了19876名,老板明显已经力不从心了,经常记错员工的名字,也经常记错要给员工安排的任务,又一次竟然把我当成隔壁老王,让我去扫厕所T_T。这也太委屈了,该怎么帮帮老板,顺便帮帮我自己呢?
在老板累死之前,我决定做一点事情,来解除这个死循环。
我们换一个思路,每个员工在入职的时候都会得到一份”工作要点“,然后老板快开饭的时候大喊一声,开饭啦。各个员工就观察老板的脸色,就各自行动去啦。A呢就自己去炒菜,搬桌子的事情就交给B啦,C自从没被派去扫地饭也煮得越来越好吃,一切都好起来了。
按照这样安排呢,这样后面就算新进一个员工,也只是多一发一份工作要点的事。
辟如一个员工太老了炒不了菜,给他换一份说明或者直接办理退休不处理事务就,在老板喊开饭的时候就直接忽略就好。就在机智的小蕉的建议下,老板进行了组织重整,终于闲下来了,又回到了整天唠嗑收钱的好日子了,我呢,也再也没有被派去扫厕所。
这!!!天哪!!!这跟今天要大家分享的,在实际工作中遇到的一个问题不谋而合啊!!!就是if else!!!看过一个多分支任务重跑类,就是由一个CODE来决定如何重跑。我的屏幕有24寸那么长,一屏幕看下来,满屏幕都是if else!!!What the。
if(some){}
else if(some else){
if(some){}
else{}
}
else if(some others){}
else if(some etc.){}...
看着这些代码这太难受了,后面也不好维护啊,这后面加一个功能岂不是要废?这么一大坨万一我还不敢轻易改,怕怕,怕怕。本着“我不管我就要改的”的善心,我决定重构一下这个代码。说走咱就走啊。天上的星星参北斗啊...
下面是纯技术干货,非技术宅的看官老爷可以直接左上角退出。
我们项目使用的是SpringMVC嘛,所以就大胆地使用Spring容器了。首先要有一个定时JOB吧,不然怎么来设计重跑,经验上来说,每五分钟跑一次,跑三次不成功,要么就是目标服务有问题,要么就是本地抛异常挂掉了。那就脑袋一拍,咱就使用观察者模式,让各个执使用Quartz来驱动这个定时任务好了。 定义一个bean然后类是下面这个,还有targetMethod属性要定义好就行了。
class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
定义一个调度中心,也就是上面那玩意,用来管理整批的重跑任务。
@Service(ObserverCenter.SERVICE_ID)
class ObserverCenter{
public static final String SERVICE_ID="ObserverCenter";
//hold住所有的调度任务处理器,在下面会定义的
List<Observer> registedObservers = new ArrayList<Observer>();
//提供一个给处理器注册的接口
public void register(Observer observer){
this.registedObservers.add(observer);
}
//提供一个给处理器注销的接口
public void unRegister(Observer observer){
this.registedObservers.remove(observer);
}
//Quartz执行的方法
public void execute(){
//获得需要重跑的任务列表
List<SomeRecords> somethingNeedToRun = new ArrayList<SomeRecords>();
//将任务广播到所有的任务观察者中,由观察者决定是否处理以及如何处理
for(SomeRecords somethingNeedToRun in somethingNeedToRun){
for(Observer observer : registedObservers){
observer.handle(somethingNeedToRun);
}
}
}
}
好了,驱动类写完啦~谈谈观察类的子类把。首先会定义一个抽象类,作为所有调度任务的父类。每个观察者类都会注册到调度中心,所以预先实现好调度方法。@PostConstruct注解用于在实例构造完执行,这里用于把自己注册到调度中心。@PreDestory注解用于在实例销毁之前,这里用于把自己从调度中心注销。
public abstract class Observer(){
@Resource(name=ObserverCenter.SERVICE_ID)
private ObserverCenter observerCenter;
@PostConstruct
private registerToCenter(){
observerCenter.register(this);
}
@PreDestory
private unRegisterFromCenter(){
observerCenter.register(this);
}
void abstract handle(SomeRecords);
}
定义一个抽记录类。
public class SomeRecords{
}
每个继承了Observer的子类,在使用Spring的单实例模式,被容器构造完成后,都会自动注册到调度中心,在接受到来自调度中心的任务后,各个子类可以决定自己需不需要处理,以及怎么处理。接下来是一个驱动类的DEMO,
public class extends Observer(){
@Override
public void handle(SomeRecords){
Logger.log("I don't give a shit to the record!")
}
}
在这个设计模式下,不会有非常长的if else,可维护性大大提高。后续在增加一个调度子类,以及删除一个调度子类,都非常方便,不会影响任何其他的处理器。
好啦今天的分享就到这里,大家有什么建议可以在后台吐槽,反正我也不会回的,毕竟我懒。
- Cnm%(个人模版)
- Selenium2+python自动化33-文件上传(send_keys)
- hive的partition的作用和使用方法
- 线段树,最大值查询位子(个人模版)
- set使用实例1+lower_bound(val)(个人模版)
- Selenium2+python自动化29-js处理多窗口
- 谷歌「机弦」有何玄机?
- 01字典树贪心查询+建立+删除(个人模版)
- 优先队列(个人模版)
- Numpy教程第2部分 - 数据分析的重要功能
- 最小表示法(个人模版)
- 基于Python-ChatterBot搭建不同adapter的聊天机器人(使用NB进行场景分类)
- 并查集(个人模版)
- Markdown 语法和 MWeb 写作使用说明既然都整理了,捎带手把这个也整理了吧第一级标题<h1>
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 对于 JavaScript 中循环之间的技术差异概述
- 初识 webpack 原理——自定义插件
- 高性能解决线程饥饿的利器 StampedLock
- 前端应该知道的web调试工具——whistle
- 最强大的 CSS 布局 —— Grid 布局
- SAP Spartacus ProductConnector和ProductService实现
- Sorted Adjacent Differences(CodeForces - 1339B)【思维+贪心】
- Redis 发布订阅,小功能大用处,真没那么废材!
- R语言实现生物序列的降维比对
- Tomcat NIO(9)-IO线程-Overall流程和关键类
- 有限元平面四边形等差单元python编程
- 动图演示:手撸堆栈的两种实现方法!
- [Go] 实战项目在线客服GO-FLY -在gin框架使用IP识别库转换IP为城市
- leetcode1552题解【二分+贪心】
- 这三年被分布式坑惨了,曝光十大坑