State定义
- 当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变其类。
- 状态模式主要解决的是当控制一个对象状态转换的条件表达式过于复杂的情况,把状态的判断逻辑转移到表示不同状态
的一系列类当中,把复杂的判断逻辑简单化。 - 将与特定状态的相关行为局部化,并且将不同状态的行为分割开来。什么情况考虑状态模式了,
当一个对象的行为取决于它的状态
,并且它必须在运行的时刻根据状态改变它的行为时,就可以考虑使用状态模式。
例子现在有个自动售货机的代码需要我们来写
- 在购买东西过程中包含4个状态,已投币,未投币,售出商品,商品售罄,
- 在如下的三个动作(投币,退币,转动手柄)
- 当用户调用不同的动作,方法时候。需要判断当前状态得出不同的信息。
- 不采用state模式解耦,会有大量代码重复。
例子1
public interface State {
/**
* 放钱
*/
public void insertMoney();
/**
* 退钱
*/
public void backMoney();
/**
* 转动
*/
public void turnCrank();
/**
* 出商品
*/
public void dispense();
}
/**
* 对象
*/
public class VendingMachine {
private State noMoneyState;
private State hasMoneyState;
private State soldState;
private State soldOutState;
private State winnerState;
private int count = 0;
/**
* 当前状态
*/
private State currentState = noMoneyState;
public VendingMachine(int count) {
this.noMoneyState = new NoMoneyState(this);
this.hasMoneyState = new HasMoneyState(this);
this.soldState = new SoldState(this);
this.soldOutState = new SoldOutState(this);
this.count = count;
if (count > 0) {
this.count = count;
currentState = noMoneyState;
}
}
/**
* 放钱
*/
public void insertMoney() {
currentState.insertMoney();
}
/**
* 退钱
*/
public void backMoney() {
currentState.backMoney();
}
/**
* 转动
*/
public void turnCrank() {
currentState.turnCrank();
}
/**
* 出商品
*/
public void dispense() {
}
public void setState(State state) {
this.currentState = state;
}
public State getNoMoneyState() {
return noMoneyState;
}
public State getHasMoneyState() {
return hasMoneyState;
}
public State getSoldState() {
return soldState;
}
public State getSoldOutState() {
return soldOutState;
}
public State getWinnerState() {
return winnerState;
}
public int getCount() {
return count;
}
public State getCurrentState() {
return currentState;
}
}
public class AbstractState implements State {
@Override
public void insertMoney() {
System.out.println("请投币");
}
@Override
public void backMoney() {
System.out.println("你未投币");
}
@Override
public void turnCrank() {
System.out.println("未投币,就想拿东西");
}
@Override
public void dispense() {
System.out.println("非法状态");
}
}
import java.util.Random;
public class HasMoneyState extends AbstractState {
private VendingMachine machine;
Random random = new Random();
public HasMoneyState(VendingMachine machine) {
this.machine = machine;
}
@Override
public void backMoney() {
System.out.println("退币成功");
machine.setState(machine.getNoMoneyState());
}
@Override
public void turnCrank() {
// System.out.println("未投币,就想拿东西");
System.out.println("你转动了手柄");
int winner = random.nextInt(10);
if (winner == 0 && machine.getCount() > 1) {
machine.setState(machine.getWinnerState());
} else {
machine.setState(machine.getSoldState());
}
}
}
/**
* 没钱状态
*/
public class NoMoneyState extends AbstractState {
private VendingMachine machine;
public NoMoneyState(VendingMachine machine) {
this.machine = machine;
}
@Override
public void insertMoney() {
System.out.println("系统投币");
/**
* 发生投钱动作后,状态发生转换
*/
machine.setState(machine.getHasMoneyState());
}
}
/**
* 售罄状态
*/
public class SoldOutState extends AbstractState {
private VendingMachine machine;
public SoldOutState(VendingMachine machine) {
this.machine = machine;
}
@Override
public void insertMoney() {
}
@Override
public void backMoney() {
}
@Override
public void turnCrank() {
System.out.println("商品售罄,转动手柄也木有用");
}
@Override
public void dispense() {
}
}
/**
* 准备出商品的状态,该状态下,不会任何用户的操作
*/
public class SoldState extends AbstractState {
private VendingMachine machine;
public SoldState(VendingMachine machine) {
this.machine = machine;
}
@Override
public void insertMoney() {
}
@Override
public void backMoney() {
}
@Override
public void turnCrank() {
}
@Override
public void dispense() {
machine.dispense();
if (machine.getCount() > 0) {
machine.setState(machine.getNoMoneyState());
} else {
System.out.println("商品已经售罄");
machine.setState(machine.getSoldOutState());
}
}
}
public class ClientTest {
public static void main(String[] args) {
VendingMachine machine=new VendingMachine(10);
machine.insertMoney();
machine.backMoney();
System.out.println("----我要中奖----");
machine.insertMoney();
machine.turnCrank();
machine.insertMoney();
machine.turnCrank();
machine.insertMoney();
machine.turnCrank();
machine.insertMoney();
machine.turnCrank();
machine.insertMoney();
machine.turnCrank();
machine.insertMoney();
machine.turnCrank();
machine.insertMoney();
machine.turnCrank();
System.out.println("-------压力测试------");
machine.insertMoney();
machine.backMoney();
machine.backMoney();
machine.turnCrank();// 无效操作
machine.turnCrank();// 无效操作
machine.backMoney();
}
}
总结
- 减少每次调用不同方法动作时候,大量状态判断,而根据当前状态下不同行为直接输出结果。
参考文档
https://blog.csdn.net/lmj623565791/article/details/26350617