工作中用到的状态模式
状态模式涉及到的类有:
1.上下文,拥有一个或多个状态类实例,对客户端暴露接口;
2.状态接口,封装具体状态类所对应的行为;
3.具体状态类,真正实现状态行为。
类图如下:
文章图片
微信截图_20181121143455.png 代码示例:
先看一下之前同事写的代码:
@Override
public List getDrlOperationDTO(String typeId) {
List list = Operation.list;
List operationList = new ArrayList<>();
//字符串类型(等于,不等于,被包含于,不被包含于,不为空,为空,匹配,不匹配)
if (DataType.STR.getValue().toString().equals(typeId)) {
for (int i = 0;
i < list.size();
i++) {
if (!list.get(i).getIndex().equals(Operation.GRE.getIndex())
&& !list.get(i).getIndex().equals(Operation.GREEQL.getIndex())
&& !list.get(i).getIndex().equals(Operation.LESS.getIndex())
&& !list.get(i).getIndex().equals(Operation.LESSEQL.getIndex())
&& !list.get(i).getIndex().equals(Operation.BET.getIndex())
&& !list.get(i).getIndex().equals(Operation.CONTAINS.getIndex())
&& !list.get(i).getIndex().equals(Operation.EXCLUDES.getIndex())) {
operationList.add(list.get(i));
}
}//数值类型(等于,大于,大于等于,小于,小于等于,不等于,被包含于,不被包含于,不为空,为空)
} else if (DataType.INT.getValue().toString().equals(typeId) || DataType.FLOAT.getValue().toString().equals(typeId)
|| DataType.DOUBLE.getValue().toString().equals(typeId)) {
for (int i = 0;
i < list.size();
i++) {
if (!list.get(i).getIndex().equals(Operation.MATCHES.getIndex())
&& !list.get(i).getIndex().equals(Operation.NMATCHES.getIndex())
&& !list.get(i).getIndex().equals(Operation.BET.getIndex())
&& !list.get(i).getIndex().equals(Operation.CONTAINS.getIndex())
&& !list.get(i).getIndex().equals(Operation.EXCLUDES.getIndex())){
operationList.add(list.get(i));
}
}//布尔类型(等于,不等于,不为空,为空)
} else if (DataType.BOOLEAN.getValue().toString().equals(typeId)) {
for (int i = 0;
i < list.size();
i++) {
if (list.get(i).getIndex().equals(Operation.EQL.getIndex())
|| list.get(i).getIndex().equals(Operation.NEQL.getIndex())
|| list.get(i).getIndex().equals(Operation.NULL.getIndex())
|| list.get(i).getIndex().equals(Operation.NOTNULL.getIndex())){
operationList.add(list.get(i));
}
}//数组类型(包含,不包含,不为空,为空)
} else if (DataType.STRS.getValue().toString().equals(typeId) || DataType.DOUBLES.getValue().toString().equals(typeId)
|| DataType.INTS.getValue().toString().equals(typeId)) {
for (int i = 0;
i < list.size();
i++) {
if (list.get(i).getIndex().equals(Operation.CONTAINS.getIndex())
|| list.get(i).getIndex().equals(Operation.EXCLUDES.getIndex())
|| list.get(i).getIndex().equals(Operation.NULL.getIndex())
|| list.get(i).getIndex().equals(Operation.NOTNULL.getIndex())){
operationList.add(list.get(i));
}
}//其他类型为所有操作符
} else {
operationList = list;
}
return RuleAssembler.toDrlOperationDtos(operationList);
}
一堆if else看着就头疼,那么改成状态模式怎么做呢?
代码如下:
1.Context类
public class DrlOperatorContext {private DrlOperatorState state;
private List operationList = new ArrayList<>();
public List getOperationList(){
return operationList;
}public List addOperateList(String typeId) {List list = Operation.list;
//字符串类型(等于,不等于,被包含于,不被包含于,不为空,为空,匹配,不匹配)
if (DataType.STR.getValue().toString().equals(typeId)) {
state = new DrlStrOperator();
//数值类型(等于,大于,大于等于,小于,小于等于,不等于,被包含于,不被包含于,不为空,为空)
} else if (DataType.INT.getValue().toString().equals(typeId) || DataType.FLOAT.getValue().toString().equals(typeId)
|| DataType.DOUBLE.getValue().toString().equals(typeId)) {
state = new DrlNumberOperator();
//布尔类型(等于,不等于,不为空,为空)
} else if (DataType.BOOLEAN.getValue().toString().equals(typeId)) {state = new DrlBooleanOperator();
//数组类型(包含,不包含,不为空,为空)
} else if (DataType.STRS.getValue().toString().equals(typeId) || DataType.DOUBLES.getValue().toString().equals(typeId)
|| DataType.INTS.getValue().toString().equals(typeId)) {
state = new DrlArrayOperator();
//其他类型为所有操作符
} else {operationList = list;
}if (state != null) {
operationList = state.addOperateList(list, this);
}
return operationList;
}
}
2.State接口
public interface DrlOperatorState {List addOperateList(List list, DrlOperatorContext context);
}
3.具体状态
public class DrlArrayOperator implements DrlOperatorState {@Override
public List addOperateList(List list, DrlOperatorContext context) {
ListoperationList = context.getOperationList();
for (int i = 0;
i < list.size();
i++) {
if (list.get(i).getIndex().equals(Operation.CONTAINS.getIndex())
|| list.get(i).getIndex().equals(Operation.EXCLUDES.getIndex())
|| list.get(i).getIndex().equals(Operation.NULL.getIndex())
|| list.get(i).getIndex().equals(Operation.NOTNULL.getIndex())){
operationList.add(list.get(i));
}
}
return operationList;
}
}public class DrlBooleanOperator implements DrlOperatorState{@Override
public List addOperateList(List list, DrlOperatorContext context) {List operationList = context.getOperationList();
for (int i = 0;
i < list.size();
i++) {
if (list.get(i).getIndex().equals(Operation.EQL.getIndex())
|| list.get(i).getIndex().equals(Operation.NEQL.getIndex())
|| list.get(i).getIndex().equals(Operation.NULL.getIndex())
|| list.get(i).getIndex().equals(Operation.NOTNULL.getIndex())){
operationList.add(list.get(i));
}
}
return operationList;
}
}public class DrlNumberOperator implements DrlOperatorState {@Override
public List addOperateList(List list, DrlOperatorContext context) {List operationList = context.getOperationList();
for (int i = 0;
i < list.size();
i++) {
if (!list.get(i).getIndex().equals(Operation.MATCHES.getIndex())
&& !list.get(i).getIndex().equals(Operation.NMATCHES.getIndex())
&& !list.get(i).getIndex().equals(Operation.BET.getIndex())
&& !list.get(i).getIndex().equals(Operation.CONTAINS.getIndex())
&& !list.get(i).getIndex().equals(Operation.EXCLUDES.getIndex())){
operationList.add(list.get(i));
}
}return operationList;
}
}public class DrlStrOperator implements DrlOperatorState {@Override
public List addOperateList(List list, DrlOperatorContext context) {List operationList = context.getOperationList();
for (int i = 0;
i < list.size();
i++) {
if (!list.get(i).getIndex().equals(Operation.GRE.getIndex())
&& !list.get(i).getIndex().equals(Operation.GREEQL.getIndex())
&& !list.get(i).getIndex().equals(Operation.LESS.getIndex())
&& !list.get(i).getIndex().equals(Operation.LESSEQL.getIndex())
&& !list.get(i).getIndex().equals(Operation.BET.getIndex())
&& !list.get(i).getIndex().equals(Operation.CONTAINS.getIndex())
&& !list.get(i).getIndex().equals(Operation.EXCLUDES.getIndex())) {
operationList.add(list.get(i));
}
}
return operationList;
}
}
4.客户端调用
@Override
public List getDrlOperationDTO(String typeId) {
DrlOperatorContext context = new DrlOperatorContext();
List operationList = context.addOperateList(typeId);
return RuleAssembler.toDrlOperationDtos(operationList);
}
【工作中用到的状态模式】这样大大简化了,客户端的调用方式,提高了代码的也读性,同时需要增加新的类型只需要实现State接口即可。
推荐阅读
- 热闹中的孤独
- JAVA(抽象类与接口的区别&重载与重写&内存泄漏)
- 放屁有这三个特征的,请注意啦!这说明你的身体毒素太多
- 一个人的旅行,三亚
- 布丽吉特,人生绝对的赢家
- 慢慢的美丽
- 尽力
- 一个小故事,我的思考。
- 家乡的那条小河
- 《真与假的困惑》???|《真与假的困惑》??? ——致良知是一种伟大的力量