设计模式——状态模式

状态在我们的生活中是很常见的,比如我们交通使用的红绿信号灯,有红、黄、绿三种状态。其实我们的衣食住行都是状态,比如火车的启动,运行,暂停,状态几乎是无处不在。下面我们来看一个大家再熟悉不过的状态图
这里写图片描述
想必大家也都知道这几种状态的意义了。其实在我们程序里面状态也是很常见的,比如我们经常使用的switch语句就是最好的说明,case后面的值就是我们所说的状态值,线程的五种状态:新建状态、就绪状态、运行状态、阻塞状态、死亡状态。
言归正传!!!状态模式就是允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类。
状态模式的使用性:
1.一个对象的行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为。
2.代码中包含大量与对象状态有关的条件语句:一个操作中含有庞大的多分支的条件(if else(或switch case)语句,且这些分支依赖于该对象的状态。这个状态通常用一个或多个枚举常量表示。通常 , 有多个操作包含这一相同的条件结构。 状态模式将每一个条件分支放入一个独立的类中。这使得你可以根据对象自身的情况将对象的状态作为一个对象,这一对象可以不依赖于其他对象而独立变化。
状态模式的参与者:
环境类 : 定义一个接口。维护一个具体状态子类的实例,这个实例定义当前状态。
抽象状态类: 定义一个接口以封装与环境类的一个特定状态相关的行为。
具体状态类: 每一子类实现一个与环境类的一个状态相关的行为。
以购物里面的搜索商品,下订单、正在配送中、确认收货、订单评价这五个状态为例
抽象状态类ShoppingState.class

/**
 * 抽象状态类
 */
public interface ShoppingState {
    void handleState(Shopping shopping);
    String getState();
}

环境类Shopping.class

/**
 * 环境类
 */
public class Shopping {
    ShoppingState state;

    public void setState(ShoppingState state) {
        this.state = state;
    }

    public void handle(){
        state.handleState(this);
    }
}

具体状态类SearchGoods.class

/**
 * 搜索商品的状态
 */
public class SearchGoods implements ShoppingState{
    @Override
    public void handleState(Shopping shopping) {
        System.out.println(this.getState());
        ShoppingState state = new PlaceOrder();
        shopping.setState(state);
        state.handleState(shopping);
    }
    @Override
    public String getState() {
        return "搜索商品已经完成!!!";
    }

}

具体状态类PlaceOrder.class

/**
 * 下订单的状态
 */
public class PlaceOrder implements ShoppingState{
    @Override
    public void handleState(Shopping shopping) {
        System.out.println(this.getState());
        ShoppingState state = new Distribution();
        shopping.setState(state);
        state.handleState(shopping);
    }
    @Override
    public String getState() {
        return "下订单已经完成!!!";
    }

}

具体状态类Distribution.class

/**
 * 商品配送的状态
 */
public class Distribution implements ShoppingState{
    @Override
    public void handleState(Shopping shopping) {
        System.out.println(this.getState());
        ShoppingState state = new Receipt();
        shopping.setState(state);
        state.handleState(shopping);
    }
    @Override
    public String getState() {
        return "商品配送已经完成!!!";
    }
}

具体状态类Receipt.class

/**
 * 商品接收的状态
 */
public class Receipt implements ShoppingState{
    @Override
    public void handleState(Shopping shopping) {
        System.out.println(this.getState());
        ShoppingState state = new Evaluate();
        shopping.setState(state);
        state.handleState(shopping);
    }
    @Override
    public String getState() {
        return "商品接收已经完成!!!";
    }
}

具体状态类Evaluate.class

/**
 * 评价的状态
 */
public class Evaluate implements ShoppingState{
    @Override
    public void handleState(Shopping shopping) {
        System.out.println(this.getState());
        System.out.println("~~~~~~~~到此已经走完整个流程了~~~~~~~~");
    }
    @Override
    public String getState() {
        return "评价已经完成!!!";
    }
}

测试代码

Shopping shopping = new Shopping();
shopping.setState(new SearchGoods());
shopping.handle();

运行效果图
这里写图片描述
通过上面的代码我们可以很明显的看出状态模式的优缺点
优点:
封装了转换规则。
将所有与某个状态有关的行为放到一个类中,并且可以方便地增加新的状态,只需要改变对象状态即可改变对象的行为。
允许状态转换逻辑与状态对象合成一体,而不是某一个巨大的条件语句块。
可以让多个环境对象共享一个状态对象,从而减少系统中对象的个数。
缺点:
状态模式的使用必然会增加系统类和对象的个数。
状态模式的结构与实现都较为复杂,如果使用不当将导致程序结构和代码的混乱。
状态模式对“开闭原则”的支持并不太好,对于可以切换状态的状态模式,增加新的状态类需要修改那些负责状态转换的源代码,否则无法切换到新增状态;而且修改某个状态类的行为也需修改对应类的源代码。
状态模式的介绍就到此为止了,如有疑问欢迎留言。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值