HeadFirst 状态模式 源码

前言:今天复习了状态模式,突然发现和我之前写的状态模式,不一样,笑

状态模式:允许对象再内部状态改变的时候改变其行为,对象看着好像改变了他的类。

理解:状态模式有什么好处?

1 好处就是增加状态的话,直接增加一个类,并且在当前状态类里增加一个对新状态的引用,扩展性较好。

2 在什么状态,做什么操作,都是类分割开的,写业务的同学经常很多if来判断不同的状态,进行不同的处理,状态模式很好的把不同状态的代码分开。

思考:

1 和策略的区别,其实都是策略,但是策略是外部控制使用哪个策略,而状态模式,每个状态就是一种策略,而策略的选择是根据状态的转换而选择,而状态的转换又是根据每个状态类,同一个方法,通过状态实现接口的方式多态,进行不同的状态转换,当状态不一样了,实现接口的状态类就不一样了。

2 什么时候用状态模式,我觉得当一个功能,主要围绕状态转换的时候,而不同的状态要给不同的反应和判断的时候就可以用状态模式,正常业务场景确实会有很多单据的状态,但是我觉得并不适用于状态模式,因为一个单据会有很多的状态,可以做简单的封装,一个状态字段封装一个枚举和对状态字段单独处理的一个类,如果滥用状态模式会让后面的人比较头疼。

在这里插入图片描述

 

代码:


/**
 * 糖果机
 */
public class GumballMachine {

    State noQuarterState;
    State hasQuarterState;
    State soldState;
    State soldOutState;
    State winnerState;

    private State state = soldOutState;
    private int candyCount = 0;

    public GumballMachine(int count) {

        noQuarterState = new NoQuarterState(this);
        hasQuarterState = new HasQuarterState(this);
        soldState = new SoldState(this);
        soldOutState = new SoldOutState(this);
        winnerState = new WinnerState(this);

        this.candyCount = count;
        if (count > 0) {
            //没有硬币状态
            state = noQuarterState;
        } else {
            //售禁状态
            state = soldOutState;
        }
    }


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


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


    public void turnCrank() {
        state.turnCrank();
        state.dispense();
    }


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


    public boolean releaseBall(int count) {
        if (candyCount >= count) {
            candyCount = candyCount - count;
            return true;
        } else {
            return false;
        }
    }

    public void refill(int count) {
        candyCount = candyCount + count;
        this.state = noQuarterState;
        System.out.println("补货成功");
    }

    public void setCandyCount(int candyCount) {
        this.candyCount = candyCount;
    }

    public int getCandyCount() {
        return candyCount;
    }

    public State getNoQuarterState() {
        return noQuarterState;
    }

    public void setNoQuarterState(State noQuarterState) {
        this.noQuarterState = noQuarterState;
    }

    public State getHasQuarterState() {
        return hasQuarterState;
    }

    public void setHasQuarterState(State hasQuarterState) {
        this.hasQuarterState = hasQuarterState;
    }

    public State getSoldState() {
        return soldState;
    }

    public void setSoldState(State soldState) {
        this.soldState = soldState;
    }

    public State getSoldOutState() {
        return soldOutState;
    }

    public void setSoldOutState(State soldOutState) {
        this.soldOutState = soldOutState;
    }

    public State getWinnerState() {
        return winnerState;
    }

    public void setWinnerState(State winnerState) {
        this.winnerState = winnerState;
    }
}

package 设计模式.状态模式;

import java.util.Random;

/**
 * 投硬币的状态
 */
public class HasQuarterState extends State{
    GumballMachine gumballMachine;

    Random randomWinner = new Random(System.currentTimeMillis());

    public HasQuarterState(GumballMachine gumballMachine) {
        this.gumballMachine = gumballMachine;
    }
    @Override
    public void insertQuarter() {
        System.out.println("请不要重复投币!");
        returnQuarter();
    }

    @Override
    public void ejectQuarter() {
        returnQuarter();
        gumballMachine.setState(gumballMachine.getNoQuarterState());
    }

    @Override
    public void turnCrank() {
        System.out.println("转动曲轴");
        int winner = randomWinner.nextInt(10);
        //十分之1的中奖概率
        if (winner == 1) {
            gumballMachine.setState(gumballMachine.getSoldState());
        }else{
            gumballMachine.setState(gumballMachine.getWinnerState());
        }

    }

    @Override
    public void dispense() {
        System.out.println("发不了糖要先转动");
    }

    @Override
    public void refill(int count) {
        System.out.println("投掷硬币状态不能补货");
    }

}


package 设计模式.状态模式;

/**
 * 没有硬币的状态
 */
public class NoQuarterState extends State{
    GumballMachine gumballMachine;

    public NoQuarterState(GumballMachine gumballMachine) {
        this.gumballMachine = gumballMachine;
    }
    @Override
    public void insertQuarter() {
        System.out.println("你投入了一个硬币");
        //转换为有硬币状态
        gumballMachine.setState(gumballMachine.hasQuarterState);
    }

    @Override
    public void ejectQuarter() {
        System.out.println("没有硬币,无法弹出");
    }

    @Override
    public void turnCrank() {
        System.out.println("请先投币");
    }

    @Override
    public void dispense() {
        System.out.println("没有投币,无法发放糖果");
    }

    @Override
    public void refill(int count) {
        gumballMachine.refill(count);
    }

}

package 设计模式.状态模式;

/**
 * 售尽的状态
 */
public class SoldOutState extends State {
    GumballMachine gumballMachine;

    public SoldOutState(GumballMachine gumballMachine) {
        this.gumballMachine = gumballMachine;
    }

    @Override
    public void insertQuarter() {
        System.out.println("糖果已经售尽");
        returnQuarter();
    }

    @Override
    public void ejectQuarter() {
        System.out.println("没有投币,无法退币");
    }

    @Override
    public void turnCrank() {
        System.out.println("糖果已经售尽");
    }

    @Override
    public void dispense() {
        System.out.println("糖果已经售尽");
    }

    @Override
    public void refill(int count) {
        gumballMachine.refill(count);
    }


}

package 设计模式.状态模式;

/**
 * 出售的状态
 */
public class SoldState extends State {
    GumballMachine gumballMachine;

    public SoldState(GumballMachine gumballMachine) {
        this.gumballMachine = gumballMachine;
    }

    @Override
    public void insertQuarter() {
        System.out.println("已投币,请等待糖果");
        returnQuarter();
    }

    @Override
    public void ejectQuarter() {
        System.out.println("无法退币,正在发放糖果,请等待");
    }

    @Override
    public void turnCrank() {
        System.out.println("已按过曲轴,请等待");
    }

    @Override
    public void dispense() {
        if (gumballMachine.releaseBall(1)) {
            System.out.println("普通发糖");
            gumballMachine.setState(gumballMachine.getNoQuarterState());
        } else {
            System.out.println("抱歉,糖果已售尽");
            System.out.println("硬币已退出");
            gumballMachine.setState(gumballMachine.getSoldOutState());
        }
    }

    @Override
    public void refill(int count) {
        System.out.println("出售状态不能补货");
    }

}



package 设计模式.状态模式;

public class WinnerState extends State {
    GumballMachine gumballMachine;

    public WinnerState(GumballMachine gumballMachine) {
        this.gumballMachine = gumballMachine;
    }

    @Override
    public void insertQuarter() {
        System.out.println("已投币,请等待糖果");
        returnQuarter();
    }

    @Override
    public void ejectQuarter() {
        System.out.println("无法退币,正在发放糖果,请等待");
    }

    @Override
    public void turnCrank() {
        System.out.println("已按过曲轴,请等待");
    }

    @Override
    public void dispense() {
        if (gumballMachine.releaseBall(2)) {
            System.out.println("大奖发糖");
            gumballMachine.setState(gumballMachine.getNoQuarterState());
        } else {
            System.out.println("抱歉,糖果已售尽或不够");
            System.out.println("硬币已退出");
            if (gumballMachine.getCandyCount() > 0) {
                gumballMachine.setState(gumballMachine.getNoQuarterState());
            }else{
                gumballMachine.setState(gumballMachine.getSoldOutState());
            }
        }
    }

    @Override
    public void refill(int count) {
        System.out.println("不能补货 售卖状态");
    }

}

package 设计模式.状态模式;

public abstract class State {
    /**
     * 投币
     */
    public abstract void insertQuarter();

    /**
     * 退币
     */
    public abstract void ejectQuarter();

    /**
     * 转动出糖曲轴
     */
    public abstract void turnCrank();

    /**
     * 发糖
     */
    public abstract void dispense();

    /**
     * 补货
     */
    public abstract void refill(int count);
    /**
     * 退还硬币
     */
    protected void returnQuarter() {
        System.out.println("退币……");
    }

}
package 设计模式.状态模式;

public class Contest {
    public static void main(String[] args) {
        //初始化糖果机 默认 没有硬币的状态  noQuarterState
        GumballMachine  gumballMachine = new GumballMachine(5);
        //投币
        gumballMachine.insertQuarter();
        //退币
        gumballMachine.ejectQuarter();
        //转动 转动出糖曲轴
        gumballMachine.turnCrank();
        //投币
        gumballMachine.insertQuarter();
        //转动 转动出糖曲轴
        gumballMachine.turnCrank();
        //投币
        gumballMachine.insertQuarter();
        //转动 转动出糖曲轴
        gumballMachine.turnCrank();
        //投币
        gumballMachine.insertQuarter();
        //转动 转动出糖曲轴
        gumballMachine.turnCrank();
        //投币
        gumballMachine.insertQuarter();
        //转动 转动出糖曲轴
        gumballMachine.turnCrank();
        //投币
        gumballMachine.insertQuarter();
        //转动 转动出糖曲轴
        gumballMachine.turnCrank();

    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值