ConcreteState-具体状态角色(本状态的行为管理和趋势状态处理)
Context-环境角色(定义客户端接口,并且负责具体状态的切换)
环境角色有两个不成文的约束
public class Client {
public static void main(String[] args) {
Context context=new Context();
context.setCurrentState(new ConcreteState1());
context.handle1();
context.handle2();
}
}
public class Context {
public static final State STATE1 = new ConcreteState1();
public static final State STATE2 = new ConcreteState2();
private State currentState;
public void setCurrentState(State state1) {
currentState = state1;
currentState.setContext(this);
}
//行为委托
public void handle1() {
this.currentState.handle1();
}
public void handle2() {
this.currentState.handle2();
}
}
public abstract class State {
//定义一个环境角色 提供子类访问
protected Context context;
public Context getContext() {
return context;
}
public State setContext(Context context) {
this.context = context;
return this;
}
//行为1
protected abstract void handle1();
//行为2
protected abstract void handle2();
}
public class ConcreteState1 extends State {
@Override
protected void handle1() {
//本状态下要处理的逻辑
}
@Override
protected void handle2() {
//设置当前状态state2
super.context.setCurrentState(Context.STATE2);
//过渡到状态2
super.context.handle2();
}
}
public class ConcreteState2 extends State {
@Override
protected void handle1() {
//设置当前状态state1
super.context.setCurrentState(Context.STATE1);
//过渡到状态1
super.context.handle1();
}
@Override
protected void handle2() {
//本状态下要处理的逻辑
}
}
以上是基本的通用逻辑和流程,接下来我们来看看处理订单常有的功能
处理视图–建造者模式(Builder模式) 示例代码如下
public static class Builder {
private StateVisibility stateVisibility;
private boolean evaluateVisible;
private boolean askAgainVisible;
private boolean reConsultVisible;
private boolean deleteOrderVisible;
private boolean modifyMsgVisible;
private boolean reminderVisible;
public Builder() {
stateVisibility = new StateVisibility();
}
public Builder setEvaluateVisible(boolean evaluateVisible) {
this.evaluateVisible = evaluateVisible;
return this;
}
public Builder setAskAgainVisible(boolean askAgainVisible) {
this.askAgainVisible = askAgainVisible;
return this;
}
public Builder setReConsultVisible(boolean reConsultVisible) {
this.reConsultVisible = reConsultVisible;
return this;
}
public Builder setDeleteOrderVisible(boolean deleteOrderVisible) {
this.deleteOrderVisible=deleteOrderVisible;
return this;
}
public Builder setModifyMsgVisible(boolean modifyMsgVisible) {
this.modifyMsgVisible=modifyMsgVisible;
return this;
}
public Builder setReminderVisible(boolean reminderVisible) {
this.reminderVisible=reminderVisible;
return this;
}
private void build() {
stateVisibility.reminderVisible = reminderVisible;
stateVisibility.modifyMsgVisible = modifyMsgVisible;
stateVisibility.deleteOrderVisible = deleteOrderVisible;
stateVisibility.evaluateVisible = evaluateVisible;
stateVisibility.askAgainVisible = askAgainVisible;
stateVisibility.reConsultVisible = reConsultVisible;
}
private class StateVisibility {
boolean evaluateVisible;
boolean askAgainVisible;
boolean reConsultVisible;
boolean deleteOrderVisible;
boolean modifyMsgVisible;
boolean reminderVisible;
}
}
动作类的流程适合状态模式,比如点击了确认收货,会根据当前的订单状态允许或者不允许一些操作,比如,没有物流状态的包裹不允许确认收货,只允许查看物流,以及点击确认收货设置下一步的状态为已收货或者退货中之类的。需要修改下一步状态的才比较适合状态模式
OrderContext orderContext = new OrderContext();
orderContext.setCurrentState(context, itemModel, mQuestionTypeEnum);
State.Builder builder = orderContext.getBuilder();
holder.vRemindAnswer.setVisibility(builder.isReminderVisible());
holder.vConsult.setVisibility(builder.isReConsultVisible());
holder.vComment.setVisibility(builder.isEvaluateVisible());
holder.vGoAskAgain.setVisibility(builder.isAskAgainVisible());
holder.vOrderGuoqi.setVisibility(builder.isYiguoqiTipVisible());
holder.vAnswerLayout.setVisibility(builder.isHasAnswer());
holder.vTvModify.setVisibility(builder.isModifyMsgVisible());
holder.vOrderMore.setVisibility(builder.isHasAnswer());
public class OrderContext {
//我这里就没声明是静态常量了
public State waitAnswerState = new WaitAnswerState();
public State answeredState = new AnsweredState();
public State overTimeState = new OverTimeState();
public State rejectedState = new RejectedState();
private State currentState;
private QuestionListModel.ListModel model;
private Context context;
private QuestionTypeEnum questionTypeEnum;
public Context getContext() {
return context;
}
public QuestionListModel.ListModel getModel() {
return model;
}
public QuestionTypeEnum getQuestionTypeEnum() {
return questionTypeEnum;
}
public void setCurrentState(Context context, QuestionListModel.ListModel model, QuestionTypeEnum questionTypeEnum) {
this.model = model;
this.context = context;
this.questionTypeEnum = questionTypeEnum;
State state = null;
//0已提问,1已回答,2已过期 3已拒单
switch (model.getStatus()) {
case 0:
state = waitAnswerState;
break;
case 1:
state = answeredState;
break;
case 2:
state = overTimeState;
break;
case 3:
state = rejectedState;
break;
}
setCurrentState(state);
}
private void setCurrentState(State state) {
currentState = state;
currentState.setmOrderContext(this);
}
public State.Builder getBuilder() {
return this.currentState.getBuilder();
}
}
public abstract class State {
//定义一个环境角色 提供子类访问
protected OrderContext mOrderContext;
public State setmOrderContext(OrderContext mOrderContext) {
this.mOrderContext = mOrderContext;
return this;
}
@NonNull
public abstract Builder getBuilder();
}
public class AnsweredState extends State {
@Override
public Builder getBuilder() {
QuestionListModel.ListModel itemModel = mOrderContext.getModel();
CharSequence answerState = getAnswerState(itemModel);
return new State.Builder()
.setHasAnswer(true)
.setAnswerState(answerState)
.setAskAgainVisible(showAskAgain(itemModel))
.setEvaluateVisible(!itemModel.getIsEvaluate())
.setReConsultVisible(itemModel.getIsEvaluate())
.build();
}
private CharSequence getAnswerState(QuestionListModel.ListModel itemModel) {
//一些判断获取显示字段
...
}
}
public class WaitAnswerState extends State {
@Override
public Builder getBuilder() {
return new State.Builder()
.setReminderVisible(true)
.setModifyMsgVisible(true)
.setAnswerState(mOrderContext.getContext().getResources().getString(R.string.answer_ask_question_status_wait_answer))
.build();
}
}
当然你也可以直接用静态方法直接根据类型返回Builder,如果没有太多逻辑的话