2017-02-23 18 views
0

時有額外的內容我有一個這樣的類:什麼是正確的方式改變狀態

public class Machine { 
    enum State { 
     STARTED, STOPPED 
    } 

    private State state; 
    private String whyIsItStopped; // only used in STOPPED state 

    ... 
} 

我不知道什麼是做到這一點的正確方法。我有一個更復雜的課程,如果我這樣做似乎是一團糟。

問題出在我的架構上,你能給我一些建議嗎?

UPDATE

使用狀態模式我像一個幾乎解決辦法:

public interface State { 

    public String whyIsItStopped(); 

    public class Started implements State { 
     @Override 
     public String whyIsItStopped() { 
      return null; 
     } 
    } 

    public class Stopped implements State { 
     private final String reason; 

     public Stopped(String reason) { 
      this.reason = reason; 
     } 

     @Override 
     public String whyIsItStopped() { 
      return reason; 
     } 
    } 
} 

public class Machine { 

    private State state = new State.Started(); 

    public String whyIsItStopped(){ 
     state.whyIsItStopped(); 
    } 

    // setState etc ... 
} 

State模式似乎不錯,來改變同一方法的行爲,但很奇怪的其它附加字段/數據。

問題是,它不是真正的對象和多態性不能真正有用。 我必須測試機器是否獲取其內容之前停止(作爲一個instanceof的方式)

if (machine.isStopped()){ 
    println(machine.whyIsItStopped()); 
} 

另一種方式可能是設置吸氣僅在停止狀態

public interface State { 

    public class Started implements State {} 

    public class Stopped implements State { 
     private final String reason; 

     public String whyIsItStopped() { 
      return reason; 
     } 
    } 
} 

而且以檢索消息:

if (machine.isStopped()){ 
    println(((State.Stopped)machine.getState()).whyIsItStopped()); 
} 
// Yeah that's not really beautiful 

要麼它在architrecture或在利用中很奇怪。

你有沒有其他解決方案,比實例更好?

+0

Andres的答案是現貨。你使用多態 - 一個(抽象)基礎來實現一個**狀態機**;和狀態特定的子類。你做**而不是**用這種方式手動「硬編碼」你的fsm。 – GhostCat

+0

使用模式中描述的句柄方法而不是每個類的特定方法 – Andres

回答

3

您的問題似乎是State Pattern的一個明顯情況。它將允許您實現一個解決方案,該解決方案可以在不修改已有代碼的情況下使用新的狀態進行擴展。

狀態模式是一種行爲軟件設計模式,它以面向對象的方式實現狀態機。在狀態 模式下,通過將每個狀態實現爲狀態模式接口的派生類 並通過調用由模式的超類定義的方法來實現狀態轉換來實現狀態機。

相關問題