switch方法重构案例

来源:互联网 发布:python keras 编辑:程序博客网 时间:2024/06/07 08:16

面向对象语言开发过程中对于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. }
Java代码 复制代码 收藏代码
  1. 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. }
Java代码 复制代码 收藏代码
  1. 然后针对各Msg类型建立相应子类,并实现changeRequest方法

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

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

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. }

之前还对factory里面的switch方法耿耿于怀,以为重构前功尽弃,但是仔细一想,其实现在的程序已经完成了service层的解耦,当有一个新Msg类型添加的时候只需要增加相应的子类,在工厂方法配制一下就可以了,同样当对某个msg变更处理策略时也可以控制在很小的修改范围。

据此,我的结论是:重构过程不是一个教条的过程,或许最后还是没办法完全消灭switch,但是重构的目的达到了就已经算是成功。