1. 程式人生 > >Java設計模式(十二):狀態設計模式

Java設計模式(十二):狀態設計模式

1.應用場景

在軟體開發過程中,應用程式可能會根據不同的情況作出不同的處理。最直接的解決方案是將這些所有可能發生的情況全都考慮到。然後使用if… ellse語句來做狀態判斷來進行不同情況的處理。但是對複雜狀態的判斷就顯得“力不從心了”。隨著增加新的狀態或者修改一個狀體(if else(或switch case)語句的增多或者修改)可能會引起很大的修改,而程式的可讀性,擴充套件性也會變得很弱。維護也會很麻煩。那麼我就考慮只修改自身狀態的模式。

例子1:按鈕來控制一個電梯的狀態,一個電梯開們,關門,停,執行。每一種狀態改變,都有可能要根據其他狀態來更新處理。例如,開門狀體,你不能在執行的時候開門,而是在電梯定下後才能開門。

例子2:我們給一部手機打電話,就可能出現這幾種情況:使用者開機,使用者關機,使用者欠費停機,使用者消戶等。 所以當我們撥打這個號碼的時候:系統就要判斷,該使用者是否在開機且不忙狀態,又或者是關機,欠費等狀態。但不管是那種狀態我們都應給出對應的處理操作。

2. 概念

允許物件在內部狀態改變時改變它的行為,物件看起來好像修改了它所屬的類。

這個模式將狀態封裝成了獨立的類,並且將動作委託到代表當前狀態的物件上,我們知道行為會隨著內部狀態的改變而改變。

3.Class Diagram

在這裡插入圖片描述

Context(上下文)是一個類,它可以擁有一些內部狀態。

State介面定義了一個所有具體狀態的共同介面,任何狀態都實現這個相同的介面,這樣一來,狀態之間可以互相替換。

4. Implementation

糖果銷售機有多種狀態,每種狀態下銷售機有不同的行為,狀態可以發生轉移,使得銷售機的行為也發生改變。

在這裡插入圖片描述

public interface State {
    public void insertQuarter();
    public void ejectQuarter();
    public void turnCrank();
    public void dispense();

    public void refill();
}

public class SoldState implements State {
 
    GumballMachine gumballMachine;
public SoldState(GumballMachine gumballMachine) { this.gumballMachine = gumballMachine; } public void insertQuarter() { System.out.println("Please wait, we're already giving you a gumball"); } public void ejectQuarter() { System.out.println("Sorry, you already turned the crank"); } public void turnCrank() { System.out.println("Turning twice doesn't get you another gumball!"); } 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 void refill() { } public String toString() { return "dispensing a gumball"; } } public class SoldOutState implements State { GumballMachine gumballMachine; public SoldOutState(GumballMachine gumballMachine) { this.gumballMachine = gumballMachine; } public void insertQuarter() { System.out.println("You can't insert a quarter, the machine is sold out"); } public void ejectQuarter() { System.out.println("You can't eject, you haven't inserted a quarter yet"); } public void turnCrank() { System.out.println("You turned, but there are no gumballs"); } public void dispense() { System.out.println("No gumball dispensed"); } public void refill() { gumballMachine.setState(gumballMachine.getNoQuarterState()); } public String toString() { return "sold out"; } } public class NoQuarterStete implements State { private GumballMachine gumballMachine; public NoQuarterStete(GumballMachine gumballMachine) { this.gumballMachine = gumballMachine; } @Override public void insertQuarter() { System.out.println("You inserted a quarter"); gumballMachine.setState(gumballMachine.hasQuarterState); } @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"); } @Override public void refill() { } } public class NoQuarterState implements State { GumballMachine gumballMachine; public NoQuarterState(GumballMachine gumballMachine) { this.gumballMachine = gumballMachine; } public void insertQuarter() { System.out.println("You inserted a quarter"); gumballMachine.setState(gumballMachine.getHasQuarterState()); } public void ejectQuarter() { System.out.println("You haven't inserted a quarter"); } public void turnCrank() { System.out.println("You turned, but there's no quarter"); } public void dispense() { System.out.println("You need to pay first"); } public void refill() { } public String toString() { return "waiting for quarter"; } } public class HasQuarterState implements State { GumballMachine gumballMachine; public HasQuarterState(GumballMachine gumballMachine) { this.gumballMachine = gumballMachine; } public void insertQuarter() { System.out.println("You can't insert another quarter"); } public void ejectQuarter() { System.out.println("Quarter returned"); gumballMachine.setState(gumballMachine.getNoQuarterState()); } public void turnCrank() { System.out.println("You turned..."); gumballMachine.setState(gumballMachine.getSoldState()); } public void dispense() { System.out.println("No gumball dispensed"); } public void refill() { } public String toString() { return "waiting for turn of crank"; } } public class GumballMachine { State soldOutState; State noQuarterState; State hasQuarterState; State soldState; State state; int count = 0; public GumballMachine(int numberGumballs) { soldOutState = new SoldOutState(this); noQuarterState = new NoQuarterState(this); hasQuarterState = new HasQuarterState(this); soldState = new SoldState(this); this.count = numberGumballs; 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(); } void releaseBall() { System.out.println("A gumball comes rolling out the slot..."); if (count != 0) { count = count - 1; } } int getCount() { return count; } void refill(int count) { this.count += count; System.out.println("The gumball machine was just refilled; it's new count is: " + this.count); state.refill(); } void setState(State state) { this.state = state; } public State getState() { return state; } public State getSoldOutState() { return soldOutState; } public State getNoQuarterState() { return noQuarterState; } public State getHasQuarterState() { return hasQuarterState; } public State getSoldState() { return soldState; } public String toString() { StringBuffer result = new StringBuffer(); result.append("\nMighty Gumball, Inc."); result.append("\nJava-enabled Standing Gumball Model #2004"); result.append("\nInventory: " + count + " gumball"); if (count != 1) { result.append("s"); } result.append("\n"); result.append("Machine is " + state + "\n"); return result.toString(); } } public class GumballMachineTestDrive { public static void main(String[] args) { GumballMachine gumballMachine = new GumballMachine(2); System.out.println(gumballMachine); gumballMachine.insertQuarter(); gumballMachine.turnCrank(); System.out.println(gumballMachine); gumballMachine.insertQuarter(); gumballMachine.turnCrank(); gumballMachine.insertQuarter(); gumballMachine.turnCrank(); gumballMachine.refill(5); gumballMachine.insertQuarter(); gumballMachine.turnCrank(); System.out.println(gumballMachine); } }