switch方法重构案例

面向对象语言开发过程中对于switch语句是很敏感的,大多数switch基本都可以通过多态方式进行重构,从而使程序获得较好的拓展能力,最近项目开发中遇到这样一个案例,在此分享一下。

重构前程序

Java代码 复制代码 收藏代码
  1. public void update(Request newReq){
  2. Request existReq=dao.getExist();
  3. Type _type=newReq.getMsgType();//Type为枚举类型
  4. ...
  5. switch (_type) {
  6. case A_MSG:
  7. existMsg = methodA(existReq);
  8. case B_MSG:
  9. existMsg = methodB(existReq, newReq);
  10. case C_MSG:
  11. if(...) {existReq = methodA(existReq);}
  12. else { existReq=methodB(existReq, newReq);}
  13. }
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);}
                }
Java代码 复制代码 收藏代码
  1. dao.update(existReq);
                dao.update(existReq);
}
Java代码 复制代码 收藏代码
 

根据重构一般原则需要对_type进行抽象并建立继承关系,这里命名基类为MsgType

Java代码 复制代码 收藏代码
  1. public abstract MsgType{
  2. protected Request methodA(Request existReq,
  3. Request newReq) {
  4. ...
  5. }
  6. protected Request methodB(Request existReq) {
  7. ...
  8. }
  9. public abstract Request changeRequest(Request existReq, Request newReq);
  10. }
public abstract MsgType{
	protected Request methodA(Request existReq,
			Request newReq) {
		...
	}

	
	protected Request methodB(Request existReq) {
		...
	}

	public abstract Request changeRequest(Request existReq, Request newReq); 
}
Java代码 复制代码 收藏代码
  1. 然后针对各Msg类型建立相应子类,并实现changeRequest方法
然后针对各Msg类型建立相应子类,并实现changeRequest方法

Java代码 复制代码 收藏代码
  1. public AMsgType extends MsgType{
  2. public Request changeRequest(Request existReq, Request newReq){
  3. return super.methodA();
  4. }
  5. }
public AMsgType extends MsgType{
	
	public  Request changeRequest(Request existReq, Request newReq){
              return super.methodA(); 
  }
}
Java代码 复制代码 收藏代码
  1. public BMsgType extends MsgType{
  2. public Request changeRequest(Request existReq, Request newReq){
  3. return super.methodB();
  4. }
  5. }
public BMsgType extends MsgType{
	
	public  Request changeRequest(Request existReq, Request newReq){
              return super.methodB(); 
  }
}
Java代码 复制代码 收藏代码
 

之后创立一个工厂方法,注意,这里仍然有一个switch,因为我们需要根据msgType来创建相应的type类。

Java代码 复制代码 收藏代码
  1. public class MsgTypeFactory {
  2. public static MsgType createMsgType(Request newReq) {
  3. switch (newReq.getMsgType()) {
  4. case A_MSG:
  5. return new AMsgType();
  6. case B_MSG:
  7. return new BMsgType();
  8. case C_MSG:
  9. return new CMsgType();
  10. default:
  11. throw new RuntimeException("不兼容消息类型:"+newReq.getMsgType());
  12. }
  13. }
  14. }
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());
		}
	}
}

工具已经齐备,可以向原程序开炮了,重构后程序如下:

Java代码 复制代码 收藏代码
  1. public void update(Request newReq){
  2. Request existReq=dao.getExist();
  3. MsgType msgType=MsgTypeFactory.createMsgType(newReq);
  4. //根据不同消息类型做不同作更新操作
  5. existReq=msgType.changeRequest(existReq, newReq);
  6. dao.update(existReq);
  7. }
 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,但是重构的目的达到了就已经算是成功。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值