状态模式

定义

当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类

使用场景

  • 一个对象的行为取决于它的状态,并且它必须在运行时根据状态改变它的行为
  • 代码中包含大量与对象状态有关的语句条件

理解

其实很好理解,就是对象可以改变自身的状态,状态改变后,行为也会跟着改变

实现方法

一般是根据对象行为提取出接口,不同的状态有不同的实现类,然后对象中有改变状态的方法,对象的行为依赖实现类去实现,状态改变后把相应的实现类替换掉,从而改变对象的行为;感觉上和策略模式有些相像,但是解决的问题不同

举个栗子

很多软件都有用户系统,都需要实名认证绑定手机号,比如有一篇文章,我点击收藏、点赞、分享的时候可能就有三种情况:未登录、登录未绑定手机、已登录;

第一个版本

package state;

public class Essay {
    //未登录
    private static final int NEED_REGISTER = 1;
    //没有绑定手机号
    private static final int NEED_PHONE = 2;
    //正常登录
    private static final int REGISTERED = 3;
    /**
     * 当前状态
     */
    private int mState = 1;

    /**
     * 点赞,登录就可以了
     */
    public void like() {
        if (mState == NEED_REGISTER) {
            System.out.println("请先登录");
        } else if (mState == NEED_PHONE || mState == REGISTERED) {
            System.out.println("点赞成功");
        }
    }

    /**
     * 分享,可以随意分享
     */
    public void share() {
        System.out.println("分享到朋友圈成功");
    }

    /**
     * 收藏,必须绑定手机号
     */
    public void collect() {
        if (mState == NEED_REGISTER) {
            System.out.println("请先登录");
        } else if (mState == NEED_PHONE) {
            System.out.println("请先绑定手机号");
        } else if (mState == REGISTERED) {
            System.out.println("收藏成功");
        }
    }
}

无论在哪里判断状态,这些条件语句是少不了的,看起来比较麻烦,不利于维护,要是在多添加几个状态可能就更糟糕了,使用状态模式试试

先抽象出行为

public interface OperateState {
    /**
     * 分享
     */
    void share();

    /**
     * 点赞
     */
    void like();

    /**
     * 收藏
     */
    void collect();
}

实现未登录状态的行为

public class NeedRegisterState implements OperateState {

    @Override
    public void share() {
        System.out.println("分享到朋友圈成功");
    }

    @Override
    public void like() {
        System.out.println("请先登录");
    }

    @Override
    public void collect() {
        System.out.println("请先登录");
    }
}

实现未绑定手机的行为

package state;

public class NeedPhoneState implements OperateState {
    @Override
    public void share() {
        System.out.println("分享到朋友圈成功");
    }

    @Override
    public void like() {
        System.out.println("点赞成功");
    }

    @Override
    public void collect() {
        System.out.println("请先绑定手机号");
    }
}

实现正常登录的行为

public class Registed implements OperateState {
    @Override
    public void share() {
        System.out.println("分享到朋友圈成功");
    }

    @Override
    public void like() {
        System.out.println("点赞成功");
    }

    @Override
    public void collect() {
        System.out.println("收藏成功");
    }
}

最后对象的实现

public class Essay {

    private OperateState operateState;

    /**
     * 改变状态
     *
     * @param operateState
     */
    public void changeState(OperateState operateState) {
        this.operateState = operateState;
    }

    public void like() {
        operateState.like();
    }

    public void share() {
        operateState.share();
    }
    
    public void collect() {
        operateState.collect();
    }
}

总结

类虽然变多了,但是思路清晰了,也更易于维护了;既然使用设计模式就是要降低耦合,抽象接口,分离代码,类变多也是正常的吧

推荐阅读更多精彩内容