switch方法重构案例
来源:互联网 发布:python keras 编辑:程序博客网 时间:2024/06/07 08:16
面向对象语言开发过程中对于switch语句是很敏感的,大多数switch基本都可以通过多态方式进行重构,从而使程序获得较好的拓展能力,最近项目开发中遇到这样一个案例,在此分享一下。
重构前程序
- public void update(Request newReq){
- Request existReq=dao.getExist();
- Type _type=newReq.getMsgType();//Type为枚举类型
- ...
- switch (_type) {
- case A_MSG:
- existMsg = methodA(existReq);
- case B_MSG:
- existMsg = methodB(existReq, newReq);
- case C_MSG:
- if(...) {existReq = methodA(existReq);}
- else { existReq=methodB(existReq, newReq);}
- }
public void update(Request newReq){ Request existReq=dao.getExist(); Type _type=newReq.getMsgType();//Type为枚举类型 ... switch (_type) { case A_MSG: existMsg = methodA(existReq); case B_MSG: existMsg = methodB(existReq, newReq); case C_MSG: if(...) {existReq = methodA(existReq);} else { existReq=methodB(existReq, newReq);} }
- dao.update(existReq);
dao.update(existReq);}
根据重构一般原则需要对_type进行抽象并建立继承关系,这里命名基类为MsgType
- public abstract MsgType{
- protected Request methodA(Request existReq,
- Request newReq) {
- ...
- }
- protected Request methodB(Request existReq) {
- ...
- }
- public abstract Request changeRequest(Request existReq, Request newReq);
- }
public abstract MsgType{protected Request methodA(Request existReq,Request newReq) {...}protected Request methodB(Request existReq) {...}public abstract Request changeRequest(Request existReq, Request newReq); }
- 然后针对各Msg类型建立相应子类,并实现changeRequest方法
然后针对各Msg类型建立相应子类,并实现changeRequest方法
- public AMsgType extends MsgType{
- public Request changeRequest(Request existReq, Request newReq){
- return super.methodA();
- }
- }
public AMsgType extends MsgType{public Request changeRequest(Request existReq, Request newReq){ return super.methodA(); }}
- public BMsgType extends MsgType{
- public Request changeRequest(Request existReq, Request newReq){
- return super.methodB();
- }
- }
public BMsgType extends MsgType{public Request changeRequest(Request existReq, Request newReq){ return super.methodB(); }}
之后创立一个工厂方法,注意,这里仍然有一个switch,因为我们需要根据msgType来创建相应的type类。
- public class MsgTypeFactory {
- public static MsgType createMsgType(Request newReq) {
- switch (newReq.getMsgType()) {
- case A_MSG:
- return new AMsgType();
- case B_MSG:
- return new BMsgType();
- case C_MSG:
- return new CMsgType();
- default:
- throw new RuntimeException("不兼容消息类型:"+newReq.getMsgType());
- }
- }
- }
public class MsgTypeFactory {public static MsgType createMsgType(Request newReq) {switch (newReq.getMsgType()) {case A_MSG:return new AMsgType();case B_MSG:return new BMsgType();case C_MSG:return new CMsgType();default:throw new RuntimeException("不兼容消息类型:"+newReq.getMsgType());}}}
工具已经齐备,可以向原程序开炮了,重构后程序如下:
- public void update(Request newReq){
- Request existReq=dao.getExist();
- MsgType msgType=MsgTypeFactory.createMsgType(newReq);
- //根据不同消息类型做不同作更新操作
- existReq=msgType.changeRequest(existReq, newReq);
- dao.update(existReq);
- }
public void update(Request newReq){ Request existReq=dao.getExist(); MsgType msgType=MsgTypeFactory.createMsgType(newReq); //根据不同消息类型做不同作更新操作 existReq=msgType.changeRequest(existReq, newReq); dao.update(existReq);}
之前还对factory里面的switch方法耿耿于怀,以为重构前功尽弃,但是仔细一想,其实现在的程序已经完成了service层的解耦,当有一个新Msg类型添加的时候只需要增加相应的子类,在工厂方法配制一下就可以了,同样当对某个msg变更处理策略时也可以控制在很小的修改范围。
据此,我的结论是:重构过程不是一个教条的过程,或许最后还是没办法完全消灭switch,但是重构的目的达到了就已经算是成功。
- switch方法重构案例
- 重构:消除switch
- 重构案例积累系列:get set方法重构
- 代码重构案例
- 【重构】使用简单工厂模式重构Switch语句
- 重构:第一个案例
- 一、重构,第一案例
- 重构--第一个案例
- 重构:运用Java反射加多态 “干掉” switch
- 重构:switch语句改成策略模式还是状态模式
- 使用注解加反射去除switch重构代码
- 重构,开始第一个案例
- 第一章 重构第一个案例
- 【转】遗留系统重构案例
- 第一章 重构,第一个案例
- 重构,第一个案例(三)
- 重构第一章 重构的第一个案例
- 重构 第1章 重构,第一个案例
- C++快速入门 (十一) 类的其他内容
- .net (C#) 中的比较[==] 操作符的深入理解
- 清平乐 -- 程序员 [诗词话程序]
- JDBC中的PreparedStatement
- Decorator(装饰)模式
- switch方法重构案例
- 黑马程序员-String类
- 黑马程序员-多线程2
- 黑马程序员-多线程1
- mongodb——java封装(id自增,gridFS)
- 重现山寨计算器
- 判断当前时间是否在限制时间段之内
- java web项目的文件路径
- 使用js对中文进行gbk编码