项目重构之命令模式

    项目中有个业务处理类大小117K,代码2700行,看此类差点雷死我,如今如要增加业务逻辑大约20个吧,此类如果随着项目工程的二期、三期如次添加逻辑迟早有一天大小达到M,噢、mygod。细心研读前人的工作总结,发现其中有点可改造的蛛丝马迹(本人很笨、别笑我才发现如何改造)。

     下面我们对业务流程、以及涉及的相关类进行介绍,Msg代表接受到客户端的一个消息报文,消息报文结构:消息头+消息体,消息头参数固定、消息体参数不定,下面是一个简单的类图,这只是一个模拟场景,****Req代表各户端请求类,***Rsp代表返回给客户端的参数类。实际比此复杂,为描述问题我们简单摘除几个类介绍,别问我为何这么设计继承。类图msgmsgHead是组合关系也许画错了、不当之处请指出,勿恶语向伤;

 


 

 处理请求Handler类的代码逻辑如下:



//类中主要方法如下
public void execute(Object object) {
Message message = (Message)object;
int opcode = message.getOpcode();
int connectId = message.getConnectId();
//消息头已经解析,获取消息体,即子类属性字节数组
byte[] bytes = message.getBytes();
if (opcode == MsgInfo.ADD_RING) {
// 订购彩铃
orderRing(connectId, bytes);
} else if (opcode == MsgInfo.PRESENT_RING) {
// 赠送彩铃
presentRing(connectId, bytes);
} else if (opcode == MsgInfo.DEL_RING) {
// 删除个人铃音
delPersonalRing(connectId, bytes);
}
//此处省略n个else if
}
//其他删除、赠送与省略的else if中的处理逻辑与之基本相同
private void orderRing(int connectId, byte[] bytes) {
//处理方法分为四步,具体代码省略
//1、解析字节数组为订购铃音类
//2、处理订购关系
//3、处理结果封装为订购响应类
//4、发送回客户端
}
//省略presentRing、delPersonalRing等一系列其他方法,所有的处理方法参数相同……


    鉴于此、想到使用命令模式改造此类,如果不了解命令模式请阅读相关书籍,大话设计模式或设计与模式,这里我们仅给出大致的定于与类图。

何谓命令模式:将一个请求封装为一个对象,从而是你可用不同的请求对客户端参数化,对请求排队或记录日志,以及支持可撤销的操作。

 Shit、这句话很难理解哦,那就先别理解了,我们看下命令模式的类图,然后介绍如何使用命令模式改造上面的elseif

类图先省略,上班偷空写的;

 

下面进入正题,对Handler小手术开始,主要考虑如下:

1、提炼方法

     将每个if语句块中的逻辑提取为一个方法,这里我们的handler已经实现,就是:orderRingpresentRingdelPersonalRing、……。

2、提炼类

  将每个业务处理方法提取为以各类,然后对具体类进行抽象,提取父类或者接口;代码如下:


public Abstract class Command{
public void execute()
}
public class OrderRingCommand extends Command {
private Handler hander;
public OrderRingCommand(Handler hander){
this.hander = hander;
}
public void execute(int connectId, byte[] bytes){
//1、解析字节数组为订购铃音类
//2、增加订购关系
//3、处理结果封装为订购响应类
//4、发送回客户端
}
/**
* 1、解析字节数组为订购铃音类
*/
public void method1(){
}
/**
* 2、处理订购关系
*/
public void method2(){
}
/**
* 3、处理结果封装为订购响应类
*/
public void method3(){
}
/**
* 4、结果发送回客户端
*/
public void method4(){
}
}
public class DelRingCommand extends Command {
private Handler hander;
public DelRingCommand(Handler hander){
this.hander = hander;
}
public void execute(int connectId, byte[] bytes){
//1、解析字节数组为订购铃音类
//2、删除购关系
//3、处理结果封装为订购响应类
//4、发送回客户端
}
//提取方法
}

  


3、命令模式改造替换elseif:


Map<Integer, Command> map = new HashMap<Integer,Command>();
static{
map.put(MsgInfo.ADD_RING, new OrderRingCommand());
//省却其他,这里仅为演示,实际项目中实例化类通过spring容器或者其他方法
}
public void execute(Object object) {
Message message = (Message)object;
int opcode = message.getOpcode();
int connectId = message.getConnectId();
//消息头已经解析,获取消息体,即子类属性字节数组
byte[] bytes = message.getBytes();
map.get(opcode).execute(connectId,bytes);
}


     

 命令模式替换else if代码坏味道的重构结束,众多的if条件块烟消云散,取而代之的是一个个精简的类,doc版本在附件中




 




 










posted on 2011-05-10 21:03 空白 阅读(340) 评论(0)  编辑  收藏 所属分类: Java


只有注册用户登录后才能发表评论。


网站导航:
 
<2011年5月>
24252627282930
1234567
891011121314
15161718192021
22232425262728
2930311234

导航

统计

常用链接

留言簿(1)

随笔分类(15)

积分与排名

最新评论

阅读排行榜

评论排行榜