状态模式

发布时间 2023-12-18 13:56:08作者: 求简君

状态模式,它允许对象在内部状态发生改变时改变它的行为,简单地讲就是,一个拥有状态的context对象,在不同状态下,其行为会发生改变。

状态模式有两个角色,一个是主类,即上下文类(context),一个是状态类。主类里有状态类对象,把不同的状态下的不同行为,由不同的状态类对象来执行,主类来进行切换状态即可。

代码示例

/**
* @author Created by njy on 2023/7/3
* 1.抽象状态(Abstract State):状态接口
* 定义:定义该状态下的行为,可以一个或多个。
*/
public interface State {
//投币
void insertCoin();
//选择商品
void selectProduct();
//发放商品
void dispense();
}

/**
* @author Created by njy on 2023/7/3
* 2.具体状态(Concrete State):未投币状态
* 定义:实现了抽象状态类定义的接口,并根据当前状态决定上下文对象的行为。
*/
public class NoCoinState implements State{
private Machine machine;

public NoCoinState(Machine machine) {
this.machine = machine;
}

@Override
public void insertCoin() {
System.out.println("已投币");
// 切换到已投币状态
machine.setState(machine.getHasCoinState());
}

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

@Override
public void dispense() {
System.out.println("请先投币选择商品");
}
}

 

/**
* @author Created by njy on 2023/7/3
* 2.具体状态(Concrete State):已投币状态
* 定义:实现了抽象状态类定义的接口,并根据当前状态决定上下文对象的行为。
*/
public class HasCoinState implements State{

private Machine machine;

public HasCoinState(Machine machine) {
this.machine = machine;
}

@Override
public void insertCoin() {
System.out.println("已投币,请勿重复投币");
}

@Override
public void selectProduct() {
System.out.println("商品已选择");
// 切换到出售状态
machine.setState(machine.getSoldState());
}

@Override
public void dispense() {
System.out.println("请先选择商品");
}
}

 

/**
* @author Created by njy on 2023/7/3
* 2.具体状态(Concrete State):出售状态
* 定义:实现了抽象状态类定义的接口,并根据当前状态决定上下文对象的行为。
*/
public class SoldState implements State{
private Machine machine;

public SoldState(Machine machine) {
this.machine = machine;
}

@Override
public void insertCoin() {
System.out.println("正在出售商品,请稍等");
}

@Override
public void selectProduct() {
System.out.println("正在出售商品,请稍等");
}

@Override
public void dispense() {
System.out.println("商品已发放");
//切换到未投币状态
machine.setState(machine.getNoCoinState());
}
}

 

/**
* @author Created by njy on 2023/7/3
* 3.上下文(Context):自动售卖机
* 定义:定义客户端需要的接口,并且负责具体状态的切换。
*/
public class Machine {
//未投币状态
private State noCoinState;
//已投币状态
private State hasCoinState;
//出售状态
private State soldState;
//当前状态
private State currentState;

public Machine() {
noCoinState = new NoCoinState(this);
hasCoinState = new HasCoinState(this);
soldState = new SoldState(this);
currentState = noCoinState; // 初始状态为未投币状态
}

public void setState(State state) {
currentState = state;
}

public State getNoCoinState() {
return noCoinState;
}

public State getHasCoinState() {
return hasCoinState;
}

public State getSoldState() {
return soldState;
}

public void insertCoin() {
currentState.insertCoin();
}

public void selectProduct() {
currentState.selectProduct();
}

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

 

/**
* @author Created by njy on 2023/7/3
* 状态模式测试类
*/
@SpringBootTest
public class TestState {

@Test
void testState(){
//创建上下文对象(自动售卖机)
Machine machine = new Machine();

System.out.println("=======直接选择商品=======");
machine.selectProduct();

System.out.println("======投币--->选择商品--->发放商品=======");
machine.insertCoin();
machine.selectProduct();
machine.dispense();

System.out.println("=======投币--->发放商品=======");
machine.insertCoin();
machine.dispense();
}
}