学习命令模式后,使用命令模式对项目中switch做一些优化
在重构一书Switch Statements(switch惊悚现身)
这一节中也阐述了重构switch的理由
使用命令模式来重构,本质上是使用多态来取代switch
原代码如下:
switch (fieldType) {
case enum1:
doSomething(parameter);
break;
case enum2:
...
break;
...
default:
break;
}
原本的代码根据fieldType值的不同执行不同的逻辑,而这个fieldType来源于一个注解的参数
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD})
public @interface Annotation {
/**
* 根据不同的类别选择不同的处理方式
*
* @return 类别枚举
*/
FieldType fieldType();
...
}
FieldType 则是一个枚举类
public enum FieldType {
...
}
重构方式如下:
-
接收者:这里将具体的业务逻辑执行类看作接收者,原本的代码已经可以复用,不做特别的关注
-
命令角色
/**
* 命令抽象接口
*
* @author Jenson
*/
public interface Command {
/**
* 设置参数
*
* @param parameter 参数
*/
void setParameter(Parameter parameter);
/**
* 执行命令
*/
void execute();
}
- 具体的命令们
/**
* @author Jenson
*/
@Component
public class DoSomethingCommand implements Command {
private Parameter parameter;
@Override
public void setParameter(Parameter parameter) {
this.parameter = parameter;
}
@Override
public void execute() {
doSomething(parameter);
}
}
具体的命令实现命令接口,在这里完成原本应该在case
中完成的工作,每一个case
对应一个具体的命令实现。这样即使以后需要增加别的情况,也只需要增加命令实现类就好了,无需再去动、去阅读研究以前的代码。撒花~
- 调用者
这里做的比较简单就是个没得感情的调用机器
/**
* 调用者抽象角色
*
* @author Jenson
*/
public interface Invoker {
/**
* 执行命令
*
* @param command 命令
*/
void action(Command command);
}
/**
* @author Jenson
*/
@Component
public class InvokerImpl implements Invoker {
@Override
public void action(Command command) {
command.execute();
}
}
- 重构原代码
Invoker invoker = SpringContextUtil.getBean(InvokerImpl.class);
Command command = (Command) SpringContextUtil.getBean(concreteCommand);
command.setParameter(currentTenantId, fieldValueList, valueMap);
invoker.action(command);
// --------------原代码对比如下----------------
// switch (fieldType) {
// case enum1:
// doSomething(parameter);
// break;
// case enum2:
// ...
// break;
// ...
// default:
// break;
// }
上述代码将fieldType替换为concreteCommand,concreteCommand是具体的命令实现类,
此处修改了注解的传入参数
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD})
public @interface Annotation {
/**
* 选择不同的命令来处理
*
* @return 命令类
*/
Class concreteCommand();
// --------------原代码对比如下----------------
// /**
// * 根据不同的类别选择不同的处理方式
// *
// * @return 类别枚举
// */
// FieldType fieldType();
// ...
}
类图如下:
图片.png后记:虽说是命令模式,但从使用的结果来看,却是策略模式
网友评论