狀態模式:允許對象在內部狀態改變時改變他的行爲,對象看起來好像修改了它的類,屬於對象的行爲模式。
狀態模式如何選擇:
1.如果代碼中存在大量的if-else情況語句。
2.對象的行爲跟隨狀態而改變。
這個模式將狀態封裝成獨立的類,並將動作委託到當前狀態的對象,我們知道行爲會隨着內部狀態的改變而改變。從客戶的角度來看:如果你使用的對象能夠完全改變他的行爲,呢麼你會覺得,這個對象是從別的類實例化而來的。然而,實際上,你知道我們是在使用組合通過簡單引用不同的狀態對象來造成類改變的假象。
類圖如下:
public class GumballMachine {
State soldOutState;
State noQuarterState;
State hasQuarterState;
State soldState;
State state = soldOutState;
int count = 0 ; //記錄有多少糖果
public GumballMachine(int numberGumballs) { //初始化,取得糖果數量
soldOutState = new SoldOutState(this);
noQuarterState = new NoQuarterState(this);
hasQuarterState = new HasQuarterState(this);
soldState = new SoldOutState(this);
this.count = numberGumballs;
if (numberGumballs > 0) {
state = noQuarterState;
}
}
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 static void main(String[] args) {
GumballMachine gumballMachine = new GumballMachine(5);
gumballMachine.setState(gumballMachine.noQuarterState);
gumballMachine.insertQuarter();
gumballMachine.turnCrank();
}
}
public class HasQuarterState implements State{
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.noQuarterState);
}
@Override
public void turnCrank() {
System.out.println("You rurned...");
gumballMachine.setState(gumballMachine.soldState);
}
@Override
public void dispense() {
System.out.println("No gumball dispensed");
}
}
public class NoQuarterState implements State{
GumballMachine gumballMachine;
public NoQuarterState(GumballMachine gumballMachine) {
this.gumballMachine = gumballMachine;
}
@Override
public void insertQuarter() {
System.out.println("You inserted a quarter");
gumballMachine.state = gumballMachine.hasQuarterState;
}
@Override
public void ejectQuarter() {
System.out.println("You haven't inserted a quarter");
}
@Override
public void turnCrank() {
System.out.println("You need to pay first");
}
@Override
public void dispense() {
// TODO Auto-generated method stub
}
}
public class SoldOutState implements State{
GumballMachine gumballMachine;
public SoldOutState(GumballMachine gumballMachine) {
this.gumballMachine = gumballMachine;
}
@Override
public void insertQuarter() {
System.out.println("You insert a quarter");
gumballMachine.setState(gumballMachine.hasQuarterState);
}
@Override
public void ejectQuarter() {
System.out.println("Quarter returned");
gumballMachine.setState(gumballMachine.noQuarterState);
}
@Override
public void turnCrank() {
System.out.println("Sorry,there is no quarter.");
}
@Override
public void dispense() {
System.out.println("No gumball dispensed");
}
}
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 truned 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.count > 0) {
gumballMachine.state = gumballMachine.noQuarterState;
}else {
System.out.println("Oops, out of gumballs!");
gumballMachine.state = gumballMachine.soldOutState;
}
}
}
public interface State {
public void insertQuarter();//這裏加入投幣代碼
public void ejectQuarter();//這裏加入退幣代碼
public void turnCrank();//這裏加入轉動曲柄代碼
public void dispense();//這裏加入發放糖果代碼
}