状态模式

个人笔记,请勿被误导。

状态模式:允许对象在内部状态改变时改变它的行为,对象看起来好像修改了它的类。

这个模式把状态封装成独立的类,并将动作委托到代表当前状态的对象。

案例介绍:糖果机有五种状态:没有收到硬币、收到硬币、糖果售罄。几种状态之间转换的操作依次是:投币、摇杆、出糖果。出糖果后如果没有糖果就转到售罄状态,否则回到没有收到硬币的状态。这里面状态是易变的,所以要封装它。比如后来出一个新状态是中奖状态,中奖状态是收到硬币状态进行摇杆操作后有十分之一概率发生的。中奖会弹出两个糖果,相应转到售罄或没有收到硬币状态。所以把各个状态封装成类,它们继承自一个抽象类State,糖果机类(这里类名是Context)有State对象curState,标识当前状态。

要点:当状态转换是固定的时候,适合放在Context中,不固定时适合放在状态类中(这样有缺点:状态之间产生依赖)。状态类还可以被多个Context实例共享,要设置成静态。

与策略模式比较:两者比较像,都用了组合的方法。个人理解策略模式封装了算法族,客户可以改变算法对象从而改变行为;而状态模式里,客户有多种状态,不同状态对应不同行为,用户改变的状态,从而改变行为。

public abstract class State {
    Context context;

    public State(Context context){//抽象类有构造函数,子类就没有默认的构造函数了。
        this.context = context;
    }

    public abstract void insertQuarter();
    public abstract void ejectQuarter();
    public abstract void turnCrank();
    public abstract void dispense();
}

public class Context {
    public State noQuarterState;
    public State hasQuarterState;
    public State winnerState;
    public State soldOutState;

    State curState = soldOutState;
    public int count = 0;
    public Context(int count){
        this.count = count;
        noQuarterState = new NoQuarterState(this);
        hasQuarterState = new HasQuarterState(this);
        winnerState = new WinnerState(this);
        soldOutState = new SoldOutState(this);
    }

    public void insertQuarter() {
        curState.insertQuarter();
    }

    public void ejectQuarter() {
        curState.ejectQuarter();
    }

    public void turnCrank() {
        curState.turnCrank();
    }

    public void dispense() {
        curState.dispense();
    }

    public void setCurState(State state){
        curState = state;
    }

    public boolean releaseBall(){
        if (count > 0){
            count--;
            return true;
        }
         else curState = noQuarterState;
        return false;
    }
}

public class NoQuarterState extends State {
    public NoQuarterState(Context context) {
        super(context);
    }

    @Override
    public void insertQuarter() {
        context.setCurState(context.hasQuarterState);
    }

    @Override
    public void ejectQuarter() {

    }

    @Override
    public void turnCrank() {

    }

    @Override
    public void dispense() {

    }
}

public class HasQuarterState extends State {
    public HasQuarterState(Context context) {
        super(context);
    }

    @Override
    public void insertQuarter() {
        System.out.print("you has insert quarters");
    }

    @Override
    public void ejectQuarter() {

    }

    @Override
    public void turnCrank() {
        double a = Math.random() * 10;
        if ((int) a == 0)
            context.setCurState(context.winnerState);
        else context.releaseBall();
    }

    @Override
    public void dispense() {

    }
}

public class WinnerState extends State {
    public WinnerState(Context context) {
        super(context);
    }

    @Override
    public void insertQuarter() {

    }

    @Override
    public void ejectQuarter() {

    }

    @Override
    public void turnCrank() {

    }

    @Override
    public void dispense() {
        if (context.releaseBall())
            context.releaseBall();
    }
}

public class SoldOutState extends State {
    public SoldOutState(Context context) {
        super(context);
    }

    @Override
    public void insertQuarter() {

    }

    @Override
    public void ejectQuarter() {

    }

    @Override
    public void turnCrank() {

    }

    @Override
    public void dispense() {

    }
}

public void StatePattern(){
        Context context = new Context(25);
        context.insertQuarter();
        context.ejectQuarter();
        context.insertQuarter();
        context.turnCrank();
        context.dispense();
    }

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值