【行为型模式】状态模式

一、状态模式概述

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

策略模式和状态模式是双胞胎,在出生时才分开。

  • 策略模式是围绕可以互换的算法来创建成功业务的。
  • 状态模式走的是更崇高的路,它通过改变对象内部的状态来帮助对象控制自己的行为。
  • 状态模式的优缺点
    • 优点
      • 1.可以将不同的状态隔离;
      • 2.每个状态都是一个单独的类;
      • 3.可以将各种状态的转换逻辑 , 分布到状态的子类中 ,减少相互依赖;
      • 4.增加新状态操作简单。
    • 缺点
      • 如果状态数量比较多,状态类的数量会增加,业务场景系统变得很复杂;
      • 如果业务中某个对象由几十上百个状态,就会很复杂,这时就需要对状态进行拆分处理。
  • 适用场景
    • 一个对象存在多个状态,状态可以相互转换;
    • 不同状态下,行为不同。

二、代码实现

        状态模式主要包含三个角色:

  • 环境(Context)角色:也称为上下文,它定义了客户感兴趣的接口,维护一个当前状态,并将与状态相关的操作委托给当前状态对象来处理;
  • 抽象状态(State)角色:定义一个接口,用以封装环境对象中的特定状态所对应的行为;
  • 具体状态(Concrete State)角色:实现抽象状态所对应的行为。
        2.1 环境角色(GumballMachine)
package state.CandySolder;
//环境角色
public class GumballMachine {
    private State noQuarterState;
    private State hasQuarterState;
    private State soldState;
    private State soldOutState;
    private State state = soldOutState; // 糖果机默认状态为售罄状态
    int count = 0; // 糖果库存量

    public GumballMachine(int numberGumballs) {
        noQuarterState = new NoQuarterState(this);
        hasQuarterState = new HasQuarterState(this);
        soldState = new SoldState(this);
        soldOutState = new SoldOutState(this);
        count = numberGumballs;
        if (numberGumballs > 0) {
            state = noQuarterState; // 如果采购了糖果球(numberGumballs>0),则糖果机的状态为未投币状态
        }
    }

    // 投入钱币
    public void insertQuarter() {
        state.insertQuarter();
    }

    // 退出钱币
    public void ejectQuarter() {
        state.ejectQuarter();
    }

    // 扭转曲柄
    public void turnCrank() {
        state.turnCrank();
        state.dispense();
    }

    // 减少库存
    public void releaseBall() {
        if (count > 0) {
            System.out.println("一个糖果球正在出库");
            --count;
        } else {
            System.out.println("库存不足,一个糖果球无法出库");
        }
    }

    // 设置状态
    void setState(State state) {
        this.state = state;
    }
    //get,set方法
	public State getNoQuarterState() {
		return noQuarterState;
	}

	public State getSoldOutState() {
		return soldOutState;
	}

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

	public int getCount() {
		return count;
	}

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

	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;
	}
    
}
        2.2 抽象状态(State)
package state.CandySolder;
//抽象角色
public interface State {
    void insertQuarter(); // 投入硬币操作   
    void ejectQuarter(); // 退出硬币操作
    void turnCrank(); // 扭转曲柄操作
    void dispense(); // 发放糖果操作
}
        2.3 具体状态(HasQuarterState、NoQuarterState、SoldOutState、SoldState)
package state.CandySolder;
//具体状态,已经投放钱币状态
public class HasQuarterState implements State {
	private GumballMachine gumballMachine;

    public HasQuarterState(GumballMachine gumballMachine) {
        this.gumballMachine = gumballMachine;
    }
	@Override
	public void insertQuarter() {
		// TODO Auto-generated method stub
		System.out.println("您已经投入钱币!无须再次投入钱币!");
	}

	@Override
	public void ejectQuarter() {
		// TODO Auto-generated method stub
		System.out.println("退款成功!");
        gumballMachine.setState(gumballMachine.getNoQuarterState()); // 状态流转
	}

	@Override
	public void turnCrank() {
		// TODO Auto-generated method stub
		System.out.println("正在出货中,请稍等");
        gumballMachine.setState(gumballMachine.getSoldState()); // 状态流转
	}

	@Override
	public void dispense() {
		// TODO Auto-generated method stub
		System.out.println("你还没有扭转曲柄,糖果不可以发放!");
	}

}
package state.CandySolder;
//具体状态,没有投放钱币状态
public class NoQuarterState implements State {
	private GumballMachine gumballMachine;

    public NoQuarterState(GumballMachine gumballMachine) {
        this.gumballMachine = gumballMachine;
    }
	@Override
	public void insertQuarter() {
		// TODO Auto-generated method stub
		System.out.println("投入钱币成功!");
        gumballMachine.setState(gumballMachine.getHasQuarterState()); // 状态流转
	}

	@Override
	public void ejectQuarter() {
		// TODO Auto-generated method stub
		System.out.println("你还没有投入钱币,不能退回钱币!");
	}

	@Override
	public void turnCrank() {
		// TODO Auto-generated method stub
		System.out.println("你还没有投入钱币,不能扭转曲柄!");
	}

	@Override
	public void dispense() {
		// TODO Auto-generated method stub
		System.out.println("你还没有投入钱币,糖果不可以发放!");
	}

}
package state.CandySolder;
//具体状态,糖果售空状态
public class SoldOutState implements State {
	private GumballMachine gumballMachine;

    public SoldOutState(GumballMachine gumballMachine) {
        this.gumballMachine = gumballMachine;
    }
	@Override
	public void insertQuarter() {
		// TODO Auto-generated method stub
		System.out.println("糖果已经售罄。不能投入钱币");
	}

	@Override
	public void ejectQuarter() {
		// TODO Auto-generated method stub
		System.out.println("退回钱币成功!");
	}

	@Override
	public void turnCrank() {
		// TODO Auto-generated method stub
		System.out.println("糖果已经售罄。不能扭转曲柄!");
	}

	@Override
	public void dispense() {
		// TODO Auto-generated method stub
		System.out.println("糖果已经售罄。糖果无法出售!");
	}

}
package state.CandySolder;
//具体状态,糖果售卖状态
public class SoldState implements State {
	private GumballMachine gumballMachine;

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

	@Override
	public void insertQuarter() {
		// TODO Auto-generated method stub
		System.out.println("糖果正在出货中,请稍等。无须再次投入钱币!");
	}

	@Override
	public void ejectQuarter() {
		// TODO Auto-generated method stub
		System.out.println("糖果正在出货中,请稍等。不能退回钱币!");
	}

	@Override
	public void turnCrank() {
		// TODO Auto-generated method stub
		System.out.println("糖果正在出货中,请稍等。不需要再次扭转曲柄!");
	}

	@Override
	public void dispense() {
		// TODO Auto-generated method stub
		if (gumballMachine.getCount() > 0) {
            System.out.println("糖果正在出货中,请稍等!");
            gumballMachine.releaseBall();
            gumballMachine.setState(gumballMachine.getNoQuarterState()); // 状态流转
        } else {
            System.out.println("糖果库存不足,无法出货!");
            gumballMachine.setState(gumballMachine.getSoldOutState()); // 状态流转
        }
	}

}
        2.4 main方法实现状态模式
package state.CandySolder;
//测试
public class Test {
	public static void main(String[] args) {
        System.out.println("-----向糖果机中放入1枚糖果-----");
        GumballMachine machine = new GumballMachine(1);

        System.out.println("-----第一次购买糖果-----");
        machine.insertQuarter();
        machine.ejectQuarter();
        machine.turnCrank();

        System.out.println("-----第二次购买糖果-----");
        machine.insertQuarter();
        machine.turnCrank();

        System.out.println("-----第三次购买糖果-----");
        machine.insertQuarter();
        machine.turnCrank();
        machine.ejectQuarter();
    }
}
        2.5 UML图

三、代码结构图

相关推荐

  1. 行为模式-状态模式

    2024-04-23 13:34:02       52 阅读
  2. 行为设计模式状态模式

    2024-04-23 13:34:02       61 阅读
  3. 笨蛋学设计模式行为模式-状态模式【20】

    2024-04-23 13:34:02       62 阅读
  4. 设计模式行为设计模式——状态模式

    2024-04-23 13:34:02       43 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-04-23 13:34:02       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-04-23 13:34:02       106 阅读
  3. 在Django里面运行非项目文件

    2024-04-23 13:34:02       87 阅读
  4. Python语言-面向对象

    2024-04-23 13:34:02       96 阅读

热门阅读

  1. 总结:IP地址、网络地址与子网掩码的理解

    2024-04-23 13:34:02       38 阅读
  2. UE5.1_Subsystem

    2024-04-23 13:34:02       29 阅读
  3. 【前端】node.js常用命令

    2024-04-23 13:34:02       37 阅读
  4. 使用 mysql 命令行访问 ClickHouse 服务器

    2024-04-23 13:34:02       36 阅读
  5. 替换正则表达式c#

    2024-04-23 13:34:02       31 阅读
  6. 前端正则表达式js和测试工具

    2024-04-23 13:34:02       32 阅读
  7. LabVIEW多通道数据采集系统

    2024-04-23 13:34:02       37 阅读
  8. 数据库查询--简单查询

    2024-04-23 13:34:02       34 阅读
  9. Reactjs常用组件

    2024-04-23 13:34:02       32 阅读