项目重构之命令模式

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

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

 

 

 
项目重构之命令模式_第1张图片
 处理请求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版本在附件中

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(设计模式,spring,工作)