【設計模式】狀態模式
阿新 • • 發佈:2018-12-25
模式定義
狀態模式允許物件在內部狀態改變時改變它的行為,物件看起來好像修改了它的類。
下圖是該模式的類圖:
一個生動的例子
就是一個自動售賣機,投硬幣—>搖桿—>出東西。
一共有這麼幾個狀態:無硬幣狀態、有硬幣狀態、無貨狀態和出貨狀態。
下面是程式碼:
狀態介面:
public interface State {
// 投硬幣
void insertQuarter();
// 退硬幣
void ejectQuarter();
// 搖桿
void turnCrank();
// 取東西
void dispense();
}
無硬幣的狀態:
public class NoQuarterState implements State {
private 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 turned but there's no quarter.");
}
@Override
public void dispense() {
System.out.println ("You need to pay first.");
}
}
有硬幣的狀態:
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());
gumballMachine.dispense();
}
@Override
public void dispense() {
System.out.println("No gumballs dispensed.");
}
}
出貨狀態:
public class SoldState implements State {
private 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());
}
}
}
無貨狀態:
public class SoldOutState implements State {
@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's no gumballs.");
}
@Override
public void dispense() {
System.out.println("No gumballs dispensed.");
}
}
售賣機:
public class GumballMachine {
private State soldOutState;
private State noQuarterState;
private State hasQuarterState;
private State soldState;
private State state = soldOutState;
private int count = 0;
public GumballMachine(int numberGumballs) {
soldOutState = new SoldOutState();
noQuarterState = new NoQuarterState(this);
hasQuarterState = new HasQuarterState(this);
soldState = new SoldState(this);
this.count = numberGumballs;
if (numberGumballs > 0) {
state = noQuarterState;
}
}
public void insertQuarter() {
state.insertQuarter();
}
public void ejectQuarter() {
state.ejectQuarter();
}
public void turnCrank() {
state.turnCrank();
}
public void dispense() {
state.dispense();
}
public void releaseBall() {
System.out.println("A gumball comes rolling out the slot...");
if (count != 0) {
count = count - 1;
}
}
public State getSoldOutState() {
return soldOutState;
}
public void setSoldOutState(State soldOutState) {
this.soldOutState = soldOutState;
}
public State getNoQuarterState() {
return noQuarterState;
}
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;
}
public State getState() {
return state;
}
public void setState(State state) {
this.state = state;
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
@Override
public String toString() {
return "GumballMachine [state=" + state.getClass().getSimpleName() + ", count=" + count + "]";
}
}
參考
- Head First 設計模式[書籍]