302 lines
6.9 KiB
Java
302 lines
6.9 KiB
Java
## 8. 状态(State)
|
||
|
||
### Intent
|
||
|
||
允许对象在内部状态改变时改变它的行为,对象看起来好像修改了它所属的类。
|
||
|
||
### Class Diagram
|
||
|
||
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/79df886f-fdc3-4020-a07f-c991bb58e0d8.png"/> </div><br>
|
||
|
||
### Implementation
|
||
|
||
糖果销售机有多种状态,每种状态下销售机有不同的行为,状态可以发生转移,使得销售机的行为也发生改变。
|
||
|
||
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/396be981-3f2c-4fd9-8101-dbf9c841504b.jpg" width="600"/> </div><br>
|
||
|
||
```java
|
||
public interface State {
|
||
/**
|
||
* 投入 25 分钱
|
||
*/
|
||
void insertQuarter();
|
||
|
||
/**
|
||
* 退回 25 分钱
|
||
*/
|
||
void ejectQuarter();
|
||
|
||
/**
|
||
* 转动曲柄
|
||
*/
|
||
void turnCrank();
|
||
|
||
/**
|
||
* 发放糖果
|
||
*/
|
||
void dispense();
|
||
}
|
||
```
|
||
|
||
```java
|
||
public class HasQuarterState implements State {
|
||
|
||
private GumballMachine gumballMachine;
|
||
|
||
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...");
|
||
gumballMachine.setState(gumballMachine.getSoldState());
|
||
}
|
||
|
||
@Override
|
||
public void dispense() {
|
||
System.out.println("No gumball dispensed");
|
||
}
|
||
}
|
||
```
|
||
|
||
```java
|
||
public class NoQuarterState implements State {
|
||
|
||
GumballMachine gumballMachine;
|
||
|
||
public NoQuarterState(GumballMachine gumballMachine) {
|
||
this.gumballMachine = gumballMachine;
|
||
}
|
||
|
||
@Override
|
||
public void insertQuarter() {
|
||
System.out.println("You insert a quarter");
|
||
gumballMachine.setState(gumballMachine.getHasQuarterState());
|
||
}
|
||
|
||
@Override
|
||
public void ejectQuarter() {
|
||
System.out.println("You haven't insert a quarter");
|
||
}
|
||
|
||
@Override
|
||
public void turnCrank() {
|
||
System.out.println("You turned, but there's no quarter");
|
||
}
|
||
|
||
@Override
|
||
public void dispense() {
|
||
System.out.println("You need to pay first");
|
||
}
|
||
}
|
||
```
|
||
|
||
```java
|
||
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");
|
||
}
|
||
}
|
||
```
|
||
|
||
```java
|
||
public class SoldState implements State {
|
||
|
||
GumballMachine gumballMachine;
|
||
|
||
public SoldState(GumballMachine gumballMachine) {
|
||
this.gumballMachine = gumballMachine;
|
||
}
|
||
|
||
@Override
|
||
public void insertQuarter() {
|
||
System.out.println("Please wait, we're 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());
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
```java
|
||
public class GumballMachine {
|
||
|
||
private State soldOutState;
|
||
private State noQuarterState;
|
||
private State hasQuarterState;
|
||
private State soldState;
|
||
|
||
private State state;
|
||
private int count = 0;
|
||
|
||
public GumballMachine(int numberGumballs) {
|
||
count = numberGumballs;
|
||
soldOutState = new SoldOutState(this);
|
||
noQuarterState = new NoQuarterState(this);
|
||
hasQuarterState = new HasQuarterState(this);
|
||
soldState = new SoldState(this);
|
||
|
||
if (numberGumballs > 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 void releaseBall() {
|
||
System.out.println("A gumball comes rolling out the slot...");
|
||
if (count != 0) {
|
||
count -= 1;
|
||
}
|
||
}
|
||
|
||
public State getSoldOutState() {
|
||
return soldOutState;
|
||
}
|
||
|
||
public State getNoQuarterState() {
|
||
return noQuarterState;
|
||
}
|
||
|
||
public State getHasQuarterState() {
|
||
return hasQuarterState;
|
||
}
|
||
|
||
public State getSoldState() {
|
||
return soldState;
|
||
}
|
||
|
||
public int getCount() {
|
||
return count;
|
||
}
|
||
}
|
||
```
|
||
|
||
```java
|
||
public class Client {
|
||
|
||
public static void main(String[] args) {
|
||
GumballMachine gumballMachine = new GumballMachine(5);
|
||
|
||
gumballMachine.insertQuarter();
|
||
gumballMachine.turnCrank();
|
||
|
||
gumballMachine.insertQuarter();
|
||
gumballMachine.ejectQuarter();
|
||
gumballMachine.turnCrank();
|
||
|
||
gumballMachine.insertQuarter();
|
||
gumballMachine.turnCrank();
|
||
gumballMachine.insertQuarter();
|
||
gumballMachine.turnCrank();
|
||
gumballMachine.ejectQuarter();
|
||
|
||
gumballMachine.insertQuarter();
|
||
gumballMachine.insertQuarter();
|
||
gumballMachine.turnCrank();
|
||
gumballMachine.insertQuarter();
|
||
gumballMachine.turnCrank();
|
||
gumballMachine.insertQuarter();
|
||
gumballMachine.turnCrank();
|
||
}
|
||
}
|
||
```
|
||
|
||
```html
|
||
You insert a quarter
|
||
You turned...
|
||
A gumball comes rolling out the slot...
|
||
You insert a quarter
|
||
Quarter returned
|
||
You turned, but there's no quarter
|
||
You need to pay first
|
||
You insert a quarter
|
||
You turned...
|
||
A gumball comes rolling out the slot...
|
||
You insert a quarter
|
||
You turned...
|
||
A gumball comes rolling out the slot...
|
||
You haven't insert a quarter
|
||
You insert a quarter
|
||
You can't insert another quarter
|
||
You turned...
|
||
A gumball comes rolling out the slot...
|
||
You insert a quarter
|
||
You turned...
|
||
A gumball comes rolling out the slot...
|
||
Oops, out of gumballs
|
||
You can't insert a quarter, the machine is sold out
|
||
You turned, but there are no gumballs
|
||
No gumball dispensed
|
||
```
|