设计模式 | 飞机票 |
---|---|
三大工厂模式 | 登机入口 |
策略模式 | 登机入口 |
委派模式 | 登机入口 |
模板方法模式 | 登机入口 |
观察者模式 | 登机入口 |
单例模式 | 登机入口 |
原型模式 | 登机入口 |
代理模式 | 登机入口 |
装饰者模式 | 登机入口 |
适配器模式 | 登机入口 |
建造者模式 | 登机入口 |
责任链模式 | 登机入口 |
享元模式 | 登机入口 |
组合模式 | 登机入口 |
门面模式 | 登机入口 |
桥接模式 | 登机入口 |
中介者模式 | 登机入口 |
迭代器模式 | 登机入口 |
状态模式 | 登机入口 |
解释器模式 | 登机入口 |
备忘录模式 | 登机入口 |
命令模式 | 登机入口 |
访问者模式 | 登机入口 |
软件设计7大原则和设计模式总结 | 登机入口 |
状态对于我们开发者而言是相当熟悉的,平常开发中总是离不开对象的状态,比如我们审核流程,就是一个状态不断流转的过程,订单流程也是一个状态不断流转的过程,而状态模式就是为了更好地解决我们状态流转过程中的业务处理逻辑。
状态模式(State Pattern)也称为状态机模式(State Machine Pattern),是允许对象在内部状态发生改变的同时改变对象的行为,使得看起来像是修改了类一样。
状态模式中的类的行为是由状态决定的,不同的状态有不同的行为。状态模式的意图是让一个对象在其内部改变时行为也随之一起改变。
状态模式的核心就是给每一种状态绑定一种行为。
好了,装逼时刻又到了:Talk is cheap,Show you the code,先看一个非常简单的例子。
下面我们就以订单状态的流转来写一个简单的示例,我们假设订单只有三个状态:待支付,待收货,已收货(完成)。
1、首先建立一个抽象的状态类,这个类需要定义所有状态的所有行为:
package com.zwx.design.pattern.state;
public abstract class AbstractOrderState {
protected OrderContext orderContext;
public AbstractOrderState(OrderContext orderContext) {
this.orderContext = orderContext;
}
public abstract void payOrder();
public abstract void deliver();
public abstract void receiveGoods();
}
注意这里面集成了一个OrderContext对象,这个对象是用来负责状态的切换的。
2、因为有三个状态,所以我们新建三个具体的状态类来实现抽象状态类:
package com.zwx.design.pattern.state;
public class WaitPaidOrderState extends AbstractOrderState {
public WaitPaidOrderState(OrderContext orderContext) {
super(orderContext);
}
@Override
public void payOrder() {
//相当于待支付的状态绑定了支付行为
System.out.println("支付成功");
this.orderContext.setState(this.orderContext.waitDeliver);//切换状态
}
@Override
public void deliver() {
System.out.println("对不起,请先付钱");
}
@Override
public void receiveGoods() {
System.out.println("对不起,请先付钱");
}
}
package com.zwx.design.pattern.state;
public class WaitDeliverOrderState extends AbstractOrderState {
public WaitDeliverOrderState(OrderContext orderContext) {
super(orderContext);
}
@Override
public void payOrder() {
System.out.println("你已经付过钱了");
}
@Override
public void deliver() {
System.out.println("商品已发货并送达目的地");
this.orderContext.setState(this.orderContext.receiveGoods);//切换状态
}
@Override
public void receiveGoods() {
System.out.println("请稍等,商品即将发货");
}
}
package com.zwx.design.pattern.state;
public class ReceiveGoodsOrderState extends AbstractOrderState{
public ReceiveGoodsOrderState(OrderContext orderContext) {
super(orderContext);
}
@Override
public void payOrder() {
System.out.println("您已经付过钱啦,不要重复付钱哦");
}
@Override
public void deliver() {
System.out.println("商品已发货并送达,请不要重复发货");
}
@Override
public void receiveGoods() {
System.out.println("用户已收到商品,此次交易结束");
}
}
我们可以看到,每个状态都绑定了一个行为(也可以支持绑定多个),并且在对应的行为处理完毕之后会流转到下一个状态,对于不属于当前状态的行为则做出相应的回应。
3、再建立一个状态上下文环境类,用来负责具体状态的切换:
package com.zwx.design.pattern.state;
/**
* @author zwx
* @version 1.0
* @date 2020/10/5
* @since jdk1.8
*/
public class OrderContext {
AbstractOrderState waitPaid;
AbstractOrderState waitDeliver;
AbstractOrderState receiveGoods;
AbstractOrderState currState;//当前状态
public OrderContext() {
this.waitPaid = new WaitPaidOrderState(this);
this.waitDeliver = new WaitDeliverOrderState(this);
this.receiveGoods = new ReceiveGoodsOrderState(this);
currState = waitPaid;
}
void setState(AbstractOrderState state){
this.currState = state;
}
public void payOrder(){
currState.payOrder();
}
public void deliver(){
currState.deliver();
}
public void receiveGoods(){
currState.receiveGoods();
}
}
可以看到,这个类里面也有点委派模式的影子,不同的行为委派给对应的对象进行处理而自己不做处理,只负责状态的切换。
4、最后再新建一个测试类进行测试:
package com.zwx.design.pattern.state;
public class TestState {
public static void main(String[] args) {
OrderContext orderContext = new OrderContext();
orderContext.payOrder();
orderContext.deliver();
orderContext.receiveGoods();
}
}
输出结果为:
支付成功
商品已发货并送达目的地
用户已收到商品,此次交易结束
从上面示例中,我们可以得出状态模式主要有3个角色:
看这个状态模式的实现是有点和责任链模式相似,都是一条链去处理,可以这么说在某种场景下这两种模式可以互相替换,但是这两种模式也是有本质区别的。
状态模式和策略模式都能用来消除大量的if/else场景,但是也有本质区别。策略模式中各个策略之间是独立的,相互可以替换的,任意选择其中一个策略就能满足需求,而且是由客户端自己做出选择。而状态模式客户端只能选择初始节点,后续就会自动流转,各个状态是一个整体,不存在可以互相替换的状态。
当控制一个对象状态的条件表达式过于复杂的时候,就可以考虑使用状态模式,通过把状态的判断逻辑转移到表示不同状态的一系列类中,这样就可以把复杂的逻辑简单化,使得对象的行为依赖于它的状态,并且会随着状态的改变而同时改变行为。
状态模式主要应用于以下场景:
优点:
缺点
本文主要介绍了状态模式的定义,并通过一个简单的示例来实现了一个简单的状态模式,最后将状态模式和责任链模式进行了对比分析,明确了其和策略模式,责任链模式的区别。
请关注我,和孤狼一起学习进步。