场景
最近看公司的代码,经常看到很多的switch语句,想到如果要加case改动比较大,代码也比较长,违反了开闭原则,所以想着用简单工厂重构下,方便以后的扩展。
原代码
private void dealMessage(int type) {
//对消息类型分类处理
switch (type) {
//客户端心跳报文 -0
case HEART_BEAT: {
//处理逻辑
break;
}
//1
case PUSH_RESPONSE: {
//处理逻辑
break;
}
//司机上传位置报文 -2
case UPLOAD_LOCATION: {
//处理逻辑
break;
}
//乘客获取司机订单中定位点报文 -3
case GET_LOCATION_ORDER :{
//处理逻辑
break;
}
default:
break;
}
}
重构后代码
private void dealMessage( int type) {
//对消息类型分类处理
IMessageHandler iMessageHandler=MessageHandlerFactory.getMessageHandlerByType(type);
//执行处理逻辑
iMessageHandler.handler();
}
简单工厂
public class MessageHandlerFactory {
public static IMessageHandler getMessageHandlerByType(int type) {
//对消息类型分类处理
switch (type) {
//客户端心跳报文 -0
case HEART_BEAT: {
return new HeartBeatHandler();
}
//1
case PUSH_RESPONSE: {
return new PushResponseHandler();
}
//司机上传位置报文-2
case UPLOAD_LOCATION: {
return new UploadLocationHandler();
}
//乘客获取司机订单中定位点报文-3
case GET_LOCATION_ORDER :{
//省略
break;
}
default:
//省略
break;
}
}
}
消息处理接口
public interface IMessageHandler {
void handler();
}
各消息处理实现类
public class HeartBeatHandler implements IMessageHandler {
@Override
public void handler() {
//处理逻辑
System.out.println("处理心跳消息");
}
}
public class PushResponseHandler implements IMessageHandler {
@Override
public void handler() {
//处理逻辑
System.out.println("处理推送反馈消息");
}
}
public class UploadLocationHandler implements IMessageHandler {
@Override
public void handler() {
//处理逻辑
System.out.println("处理司机上传位置消息");
}
}
简单工厂模式的缺陷:
- 1.甲方必须知道工厂能产出什么,否则工厂要抛出异常。
- 2.新增了case后,虽然不用再去找散落各处的switch语句,但是工厂中的switch语句还是要跟着改的,违反了开闭原则。
针对简单工厂还是有switch的改进方案
- 在配置文件配置映射,一个类型映射一个类名,工厂类通过反射获取类
- 约定大于配置,类名前缀保持一致,加上后面的type,工厂类通过反射获取处理类