最近发现项目中的判断太多,大量的if-else结构,想着重构下,于是接触到了状态模式。
这种设计模式就是java多态的体现,没有想象的那么神奇。
状态模式:当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。
即
1、有一个对象,它是有状态的。
2、这个对象在状态不同的时候,行为不一样。
3、这些状态是可以切换的,而非毫无关系。

图中包含三个角色。
Context:它就是那个含有状态的对象,它可以处理一些请求,这些请求最终产生的响应会与状态相关。
State:状态接口,它定义了每一个状态的行为集合,这些行为会在Context中得以使用。
ConcreteState:具体状态,实现相关行为的具体状态类。
其他解释
环境(Context)角色,也成上下文:定义客户端所感兴趣的接口,并且保留一个具体状态类的实例。这个具体状态类的实例给出此环境对象的现有状态。
抽象状态(State)角色:定义一个接口,用以封装环境(Context)对象的一个特定的状态所对应的行为。
具体状态(ConcreteState)角色:每一个具体状态类都实现了环境(Context)的一个状态所对应的行为。
个人还是喜欢把环境角色context带入接口的方法参数中,这样逻辑更清楚;
另外的方式是把context放入各个具体状态角色的构造方法中,当实例化context的时候,通过具体状态的构造方法加载此context实例到具体状态角色中
举例一
本例子模拟购物的整个过程,包括下单,付款,收货,评价,退款,结束等。
状态接口
public interface Event {
//下单
void order(Shopping shopping,Boolean isConfirm) ;
//付款
void pay(Shopping shopping,Boolean isConfirm);
//签收
void receive(Shopping shopping,Boolean isConfirm);
//评价
void evaluate(Shopping shopping,Boolean isConfirm);
//订单结束
void finish(Shopping shopping,Boolean isConfirm);
//退款
void refund(Shopping shopping,Boolean isConfirm);
}
抽象类主要处理异常的情况,即用户重复提交某个状态时出现
public class AbstractEvent implements Event {
@Override
public void order(Shopping shopping, Boolean isConfirm) {
System.out.println("亲亲,下单异常");
}
@Override
public void pay(Shopping shopping, Boolean isConfirm) {
System.out.println("亲亲,支付异常");
}
@Override
public void receive(Shopping shopping, Boolean isConfirm) {
System.out.println("亲亲,接收异常");
}
@Override
public void evaluate(Shopping shopping, Boolean isConfirm) {
System.out.println("亲亲,评价异常");
}
@Override
public void finish(Shopping shopping, Boolean isConfirm) {
System.out.println("亲亲,结束操作流程错误");
}
@Override
public void refund(Shopping shopping, Boolean isConfirm) {
System.out.println("您的订单已经退款,请不要重复提交");
}
}
具体状态角色 - 下单
public class Order extends AbstractEvent {
@Override
public void order(Shopping shopping, Boolean isConfirm) {
if(isConfirm){
System.out.println("恭喜您,下单成功");
shopping.setEvent(Shopping.PAY_STATE);//确定下单,进入支付页面
}else {
System.out.println("订单页面取消成功,回到主页面");
shopping.setEvent(Shopping.REFUND);
}
}
}
具体状态角色 - 支付
public class Pay extends AbstractEvent {
@Override
public void pay(Shopping shopping, Boolean isConfirm) {
if(isConfirm){
System.out.println("恭喜您,支付成功");
shopping.setEvent(Shopping.RECEIVE_STATE);//进入收货阶段
}else {
System.out.println("支付页面,取消订单成功");
shopping.setEvent(Shopping.REFUND);
}
}
}
具体状态角色 - 接收
public class Receive extends AbstractEvent {
@Override
public void receive(Shopping shopping, Boolean isConfirm) {
if(isConfirm){
System.out.println("亲,签收物品成功,期待下次与您再次相见");
shopping.setEvent(Shopping.EVALUATE_STATE);
}else {
System.out.println("亲,签收阶段退款成功");
shopping.setEvent(Shopping.REFUND);
}
}
}
具体状态角色 - 评价
public class Evaluate extends AbstractEvent {
@Override
public void evaluate(Shopping shopping, Boolean isConfirm) {
if(isConfirm){
System.out.println("评价商品成功");
shopping.setEvent(Shopping.FINISH_STATE);
}else {
System.out.println("评价阶段,退款成功");
shopping.setEvent(Shopping.REFUND);
}
}
}
具体状态角色 - 完成
public class Finish extends AbstractEvent {
@Override
public void finish(Shopping shopping, Boolean isConfirm) {
if(isConfirm){
System.out.println("订单结束,感谢您的光临");
}else {
System.out.println("亲爱的客人,请您分享使用心得");
}
}
}
具体状态角色 - 退款
public class Refund extends AbstractEvent {
@Override
public void refund(Shopping shopping, Boolean isConfirm) {
if(isConfirm){
System.out.println("抱歉客官,给您带来不好的购物体验了,已为您退款,请见谅");
shopping.setEvent(Shopping.FINISH_STATE);
}
}
}
环境角色,有状态的对象 - 购物对象
public class Shopping {
public static final Event ORDER_STATE = new Order();
public static final Event PAY_STATE = new Pay();
public static final Event RECEIVE_STATE = new Receive();
public static final Event EVALUATE_STATE = new Evaluate();
public static final Event FINISH_STATE = new Finish();
public static final Event REFUND = new Refund();
//状态记录,默认进入下单状态
private Event event = ORDER_STATE;
public Event getEvent() {
return event;
}
public void setEvent(Event event) {
this.event = event;
}
public void startOrder(Boolean isConfirm){
event.order(this,isConfirm);
}
public void startPay(Boolean isConfirm){
event.pay(this,isConfirm);
}
public void startReceive(Boolean isConfirm){
event.receive(this,isConfirm);
}
public void startEvaluate(Boolean isConfirm){
event.evaluate(this,isConfirm);
}
public void startFinish(Boolean isConfirm){
event.finish(this,isConfirm);
}
public void startRefund(Boolean isConfirm){
event.refund(this,isConfirm);
}
}
客户启动段
public class Client {
public static void main(String[] args) {
Shopping shopping = new Shopping();
//下单成功
shopping.startOrder(true);
shopping.startOrder(true);
shopping.startOrder(true);
shopping.startOrder(true);
shopping.startOrder(true);
shopping.startPay(true);
shopping.startReceive(false);
shopping.startRefund(true);
shopping.startEvaluate(true);
shopping.startFinish(true);
}
}
运行结果:

状态模式适用于某一个对象的行为取决于该对象的状态,并且该对象的状态会在运行时转换,又或者有很多的if else判断,而这些判断只是因为状态不同而不断的切换行为。
来源:https://www.cnblogs.com/InternetJava/p/12540133.html