狀態(tài)模式涉及到的類有:
1.上下文陕靠,擁有一個(gè)或多個(gè)狀態(tài)類實(shí)例,對(duì)客戶端暴露接口鞠评;
2.狀態(tài)接口茂蚓,封裝具體狀態(tài)類所對(duì)應(yīng)的行為;
3.具體狀態(tài)類剃幌,真正實(shí)現(xiàn)狀態(tài)行為聋涨。
類圖如下:
微信截圖_20181121143455.png
代碼示例:
先看一下之前同事寫的代碼:
@Override
public List<DrlTypeDTO> getDrlOperationDTO(String typeId) {
List<Operation> list = Operation.list;
List<Operation> 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));
}
}
//數(shù)值類型(等于,大于,大于等于,小于,小于等于,不等于,被包含于,不被包含于,不為空,為空)
} 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));
}
}
//數(shù)組類型(包含,不包含,不為空,為空)
} 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看著就頭疼,那么改成狀態(tài)模式怎么做呢负乡?
代碼如下:
1.Context類
public class DrlOperatorContext {
private DrlOperatorState state;
private List<Operation> operationList = new ArrayList<>();
public List<Operation> getOperationList(){
return operationList;
}
public List<Operation> addOperateList(String typeId) {
List<Operation> list = Operation.list;
//字符串類型(等于,不等于,被包含于,不被包含于,不為空,為空,匹配,不匹配)
if (DataType.STR.getValue().toString().equals(typeId)) {
state = new DrlStrOperator();
//數(shù)值類型(等于,大于,大于等于,小于,小于等于,不等于,被包含于,不被包含于,不為空,為空)
} 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();
//數(shù)組類型(包含,不包含,不為空,為空)
} 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<Operation> addOperateList(List<Operation> list, DrlOperatorContext context);
}
3.具體狀態(tài)
public class DrlArrayOperator implements DrlOperatorState {
@Override
public List<Operation> addOperateList(List<Operation> list, DrlOperatorContext context) {
List<Operation> operationList = 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<Operation> addOperateList(List<Operation> list, DrlOperatorContext context) {
List<Operation> 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<Operation> addOperateList(List<Operation> list, DrlOperatorContext context) {
List<Operation> 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<Operation> addOperateList(List<Operation> list, DrlOperatorContext context) {
List<Operation> 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.客戶端調(diào)用
@Override
public List<DrlTypeDTO> getDrlOperationDTO(String typeId) {
DrlOperatorContext context = new DrlOperatorContext();
List<Operation> operationList = context.addOperateList(typeId);
return RuleAssembler.toDrlOperationDtos(operationList);
}
這樣大大簡化了牍白,客戶端的調(diào)用方式,提高了代碼的也讀性抖棘,同時(shí)需要增加新的類型只需要實(shí)現(xiàn)State接口即可茂腥。