美文网首页
状态模式

状态模式

作者: 阳光的技术小栈 | 来源:发表于2018-01-22 15:13 被阅读13次

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

示例—糖果机的实现

糖果机的主要流程是:开始没有硬币投入的状态,用户在投入硬币后,糖果机转为已投入硬币状态。这时,用户可以选择旋转把手或者退钱。选择旋转把手后,状态变更为已售出。糖果掉落后,如果还有糖果,状态变更为没有硬币;如果没有糖果了,状态变更为售光。选择退钱后,硬币退回,状态变更为没有硬币。还有一个抽奖机制,把手旋转的时候有10%的纪律掉落2个糖果。

UML图表示

状态模式-糖果机

代码演示

状态接口

package State;

public interface State {
    void insertQuarter();
    void ejectQuarter();
    void turnCrank();
    void dispense();
}

无硬币状态类

package State;

public class NoQuarterState implements State {

    GumballMachine gumballMachine;

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

    @Override
    public void insertQuarter() {
        System.out.println("You inserted a quarter");
        gumballMachine.setState(gumballMachine.getHasQuarterState());
    }

    @Override
    public void ejectQuarter() {
        System.out.println("You haven't inserted a quarter");
    }

    @Override
    public void turnCrank() {
        System.out.println("You need to pay first");
    }

    @Override
    public void dispense() {
        System.out.println("You need to pay first");
    }

    @Override
    public String toString() {
        return this.getClass().getName();
    }
}

有硬币状态类

package State;

import java.util.Random;

public class HasQuarterState implements State {

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

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

    @Override
    public void insertQuarter() {
        System.out.println("You can't insert another quarter");
    }

    @Override
    public void ejectQuarter() {
        System.out.println("Quarter returned");
        gumballMachine.setState(gumballMachine.getNoQuarterState());
    }

    @Override
    public void turnCrank() {
        System.out.println("You turned...");
        int winner = randomWinner.nextInt(10);
        if ((winner == 0) && (gumballMachine.getCount() > 1)){
            gumballMachine.setState(gumballMachine.getWinnerState());
        }
        else{
            gumballMachine.setState(gumballMachine.getSoldState());
        }
    }

    @Override
    public void dispense() {
        System.out.println("No gumball dispensed");
    }

    @Override
    public String toString() {
        return this.getClass().getName();
    }
}

售出状态类

package State;

public class SoldState implements State {

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

    @Override
    public void insertQuarter() {
        System.out.println("Please wait,we've already giving you a gumball");
    }

    @Override
    public void ejectQuarter() {
        System.out.println("Sorry, you already turned the crank");
    }

    @Override
    public void turnCrank() {
        System.out.println("Turning twice doesn't get you another gumball!");
    }

    @Override
    public void dispense() {
        gumballMachine.releaseBall();
        if (gumballMachine.getCount() > 0){
            gumballMachine.setState(gumballMachine.getNoQuarterState());
        }
        else{
            System.out.println("Oops, out of gumballs");
            gumballMachine.setState(gumballMachine.getSoldOutState());
        }

    }

    @Override
    public String toString() {
        return this.getClass().getName();
    }
}

售罄状态类

package State;

public class SoldOutState implements State {

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

    @Override
    public void insertQuarter() {
        System.out.println("You can't insert a quarter,the machine is sold out");
    }

    @Override
    public void ejectQuarter() {
        System.out.println("You can't eject,you haven't inserted a quarter yet");
    }

    @Override
    public void turnCrank() {
        System.out.println("You turned, but there are no gumballs");
    }

    @Override
    public void dispense() {
        System.out.println("No gumball dispensed");
    }
    @Override
    public String toString() {
        return this.getClass().getName();
    }
}

获奖状态类

package State;

public class WinnerState implements State {

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

    @Override
    public void insertQuarter() {
        System.out.println("You can't insert a quarter");
    }

    @Override
    public void ejectQuarter() {
        System.out.println("You can't eject");
    }

    @Override
    public void turnCrank() {
        System.out.println("Turning twice doesn't get you third gumball!");
    }

    @Override
    public void dispense() {
        System.out.println("YOU'RE A WINNER! You get two gumballs for your quarter");
        gumballMachine.releaseBall();
        if (gumballMachine.getCount() == 0){
            gumballMachine.setState(gumballMachine.getSoldOutState());
        }else{
            gumballMachine.releaseBall();
            if (gumballMachine.getCount() > 0){
                gumballMachine.setState(gumballMachine.getNoQuarterState());
            }else{
                System.out.println("Oops, out of gumballs");
                gumballMachine.setState(gumballMachine.getSoldOutState());
            }
        }
    }

    @Override
    public String toString() {
        return this.getClass().getName();
    }
}

糖果机类

package State;

public class GumballMachine {

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

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

    public GumballMachine(int numberGumballs){
        soldOutState = new SoldOutState(this);
        noQuarterState = new NoQuarterState(this);
        hasQuarterState = new HasQuarterState(this);
        soldState = new SoldState(this);
        winnerState = new WinnerState(this);
        this.count = numberGumballs;

        if (numberGumballs > 0){
            state = noQuarterState;
        }
    }

    @Override
    public String toString() {
        return "GumballMachine has " + count + " gumballs now, current state is " + state.toString();
    }

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

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

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


    public State getState() {
        return state;
    }

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

    public State getHasQuarterState(){
        return hasQuarterState;
    }

    public State getNoQuarterState(){
        return noQuarterState;
    }

    public State getSoldState(){
        return soldState;
    }

    public State getSoldOutState(){
        return soldOutState;
    }

    public State getWinnerState() {
        return winnerState;
    }

    void releaseBall(){
        System.out.println("A gumball comes rolling out the slot...");
        if (count != 0){
            count = count - 1;
        }
    }

    public int getCount() {
        return count;
    }

    public void setCount(int count) {
        this.count = count;
    }
}

测试代码

package State;

public class GumballMachineTestDrive {
    public static void main(String[] args) {
        GumballMachine gumballMachine = new GumballMachine(5);
        System.out.println(gumballMachine);

        gumballMachine.insertQuarter();
        gumballMachine.turnCrank();

        System.out.println(gumballMachine);

        gumballMachine.insertQuarter();
        gumballMachine.turnCrank();
        gumballMachine.insertQuarter();
        gumballMachine.turnCrank();

        System.out.println(gumballMachine);

    }
}

测试结果

GumballMachine has 5 gumballs now, current state is State.NoQuarterState
You inserted a quarter
You turned...
YOU'RE A WINNER! You get two gumballs for your quarter
A gumball comes rolling out the slot...
A gumball comes rolling out the slot...
GumballMachine has 3 gumballs now, current state is State.NoQuarterState
You inserted a quarter
You turned...
A gumball comes rolling out the slot...
You inserted a quarter
You turned...
A gumball comes rolling out the slot...
GumballMachine has 1 gumballs now, current state is State.NoQuarterState

相关文章

  • State模式

    状态模式(State模式) 定义 状态模式,又称状态对象模式(Pattern of Objects for S...

  • 设计模式-状态模式

    设计模式-状态模式 设计模式 状态模式的关键是区分事物内部的状态

  • 状态模式(状态机模式)

    状态模式学习笔记 前言:文章从三方面简单阐述状态模式:是什么、为什么、如何做。这是我在工作之余自己的一些理解、思考...

  • C++设计模式(3)

    本文预览: 状态模式 组合模式 迭代器 职责链 命令 状态模式 定义:状态模式(State Pattern),允许...

  • 设计模式——状态模式

    定义 状态模式,又称状态对象模式(Pattern of Objects for States),状态模式是对象的行...

  • 第5章 -行为型模式-状态模式

    一、状态模式的简介 二、状态模式的优缺点 三、状态模式的实例

  • 状态模式

    Android进阶之设计模式 状态模式 定义: 当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了...

  • 状态模式

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

  • 状态模式

    《大话设计模式》阅读笔记和总结。原书是C#编写的,本人用Java实现了一遍,包括每种设计模式的UML图实现和示例代...

  • 状态模式

    状态模式 一个对象有状态变化 每次状态变化都会触发一个逻辑 不能总是用 if...else 来控制 示例 交通灯信...

网友评论

      本文标题:状态模式

      本文链接:https://www.haomeiwen.com/subject/dhrsnxtx.html