设计模式学习笔记:状态模式(State)

学而不思则罔,思而不学则殆。 ——孔子

一、状态模式简介

状态模式是设计模式中行为型模式的一种。一个对象在它的状态改变时,它的行为也随之改变,看起来好像改变了其类。

二、举例说明

假如电话有三种状态:通话中、待机中、已关机。四种行为:打电话、挂电话、开机、关机。那么在不同的状态下这四种行为的表现方式肯定不同。例如关机状态下不能打电话,而待机状态下就可以打电话。

三、代码实现

1、不使用状态模式的实现方法

/**
 * 不使用状态模式的实现方式
 *
 * @author ZhengNC
 * @date 2020/9/22 16:48
 */
public class NotUsedStatePattern {

    enum State{
        /** 通话中 */
        Calling,
        /** 待机中 */
        Standby,
        /** 已关机 */
        Shutdown
    }

    private State state = State.Shutdown;

    /**
     * 打电话
     */
    public void call() {
        switch (state){
            case Calling:
                System.out.println("正在通话中,不能发起新的通话。。。");
                break;
            case Standby:
                state = State.Calling;
                break;
            case Shutdown:
                System.out.println("手机已关机,无法通话!");
                break;
            default:
                break;
        }
    }

    /**
     * 挂电话
     */
    public void bye() {
        switch (state){
            case Calling:
                state = State.Standby;
                break;
            case Standby:
                System.out.println("不在通话状态,无需挂断!");
                break;
            case Shutdown:
                System.out.println("手机已关机,不需挂断!");
                break;
            default:
                break;
        }
    }

    /**
     * 关机
     */
    public void shutdown() {
        switch (state){
            case Calling:
                System.out.println("通话中,正在强制关机。。。");
                state = State.Shutdown;
                break;
            case Standby:
                state = State.Shutdown;
                break;
            case Shutdown:
                System.out.println("手机已关机,不需重复关机!");
                break;
            default:
                break;
        }
    }

    /**
     * 开机
     */
    public void bootUp() {
        switch (state){
            case Calling:
                System.out.println("手机已经开机了,无需重复开机。");
                break;
            case Standby:
                System.out.println("手机已经开机了,无需重复开机。");
                break;
            case Shutdown:
                state = State.Standby;
                break;
            default:
                break;
        }
    }
}

从以上代码中可以发现,类中的逻辑过于复杂,而且如果要增加一种状态的话将需要修改每个行为对应的方法。

2、使用状态模式的实现方法

PhoneAction(电话动作):

/**
 * 电话动作
 *
 * @author ZhengNC
 * @date 2020/9/22 15:36
 */
public interface PhoneAction {

    /**
     * 通话
     */
    void call();

    /**
     * 挂掉电话
     */
    void bye();

    /**
     * 关机
     */
    void shutdown();

    /**
     * 开机
     */
    void bootUp();
}

PhoneState(手机状态):

/**
 * 手机状态
 *
 * @author ZhengNC
 * @date 2020/9/22 15:20
 */
public abstract class PhoneState implements PhoneAction {

    protected Phone phone;

    protected String stateName;

    public PhoneState(Phone phone){
        this.phone = phone;
    }

    @Override
    public String toString() {
        return "状态:"+stateName;
    }
}

Calling(状态:通话中):

/**
 * 状态:通话中
 *
 * @author ZhengNC
 * @date 2020/9/22 15:54
 */
public class Calling extends PhoneState {

    public Calling(Phone phone) {
        super(phone);
        stateName = "通话中";
    }

    @Override
    public void call() {
        System.out.println("正在通话中,不能发起新的通话。。。");
    }

    @Override
    public void bye() {
        phone.setState(phone.getStandby());
    }

    @Override
    public void shutdown() {
        System.out.println("通话中,正在强制关机。。。");
        phone.setState(phone.getShutdown());
    }

    @Override
    public void bootUp() {
        System.out.println("手机已经开机了,无需重复开机。");
    }
}

Shutdown(状态:已关机):

/**
 * 状态:已关机
 *
 * @author ZhengNC
 * @date 2020/9/22 16:13
 */
public class Shutdown extends PhoneState {

    public Shutdown(Phone phone) {
        super(phone);
        stateName = "已关机";
    }

    @Override
    public void call() {
        System.out.println("手机已关机,无法通话!");
    }

    @Override
    public void bye() {
        System.out.println("手机已关机,不需挂断!");
    }

    @Override
    public void shutdown() {
        System.out.println("手机已关机,不需重复关机!");
    }

    @Override
    public void bootUp() {
        phone.setState(phone.getStandby());
    }
}

Standby(状态:待机中):

/**
 * 状态:待机中
 *
 * @author ZhengNC
 * @date 2020/9/22 16:00
 */
public class Standby extends PhoneState {

    public Standby(Phone phone) {
        super(phone);
        stateName = "待机中";
    }

    @Override
    public void call() {
        phone.setState(phone.getCalling());
    }

    @Override
    public void bye() {
        System.out.println("不在通话状态,无需挂断!");
    }

    @Override
    public void shutdown() {
        phone.setState(phone.getShutdown());
    }

    @Override
    public void bootUp() {
        System.out.println("手机已经开机了,无需重复开机。");
    }
}

Phone(电话):

/**
 * 电话
 *
 * @author ZhengNC
 * @date 2020/9/22 15:24
 */
public class Phone implements PhoneAction {

    /**
     * 状态:通话中
     */
    private final PhoneState Calling = new Calling(this);
    /**
     * 状态:待机中
     */
    private final PhoneState standby = new Standby(this);
    /**
     * 状态:已关机
     */
    private final PhoneState shutdown = new Shutdown(this);

    /**
     * 当前状态
     */
    private PhoneState state = shutdown;

    public PhoneState getCalling() {
        return Calling;
    }

    public PhoneState getStandby() {
        return standby;
    }

    public PhoneState getShutdown() {
        return shutdown;
    }

    public PhoneState getState() {
        return state;
    }

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

    @Override
    public void call() {
        state.call();
    }

    @Override
    public void bye() {
        state.bye();
    }

    @Override
    public void shutdown() {
        state.shutdown();
    }

    @Override
    public void bootUp() {
        state.bootUp();
    }
}

3、测试状态模式

/**
 * 测试状态模式
 *
 * @author ZhengNC
 * @date 2020/9/22 16:31
 */
public class TestState {

    public static void main(String[] args) {
        Phone phone = new Phone();
        System.out.println(phone.getState());
        phone.call();
        System.out.println(phone.getState());
        phone.bye();
        System.out.println(phone.getState());
        phone.bootUp();
        System.out.println(phone.getState());
        phone.call();
        System.out.println(phone.getState());
        phone.bye();
        System.out.println(phone.getState());
        phone.shutdown();
        System.out.println(phone.getState());
    }
}

输出结果:

状态:已关机
手机已关机,无法通话!
状态:已关机
手机已关机,不需挂断!
状态:已关机
状态:待机中
状态:通话中
状态:待机中
状态:已关机

四、与策略模式的区别

刚接触状态模式的时候肯定觉得和策略模式很像,但它们最大的区别就是策略模式的策略是手动选择的,而状态模式的状态却是对象自动变化的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值