簡體   English   中英

這個基於Java狀態的設計模式的名稱是什么?

[英]What is this the name of this Java state-based design pattern?

在我的工作中,我們進行了調查,一項調查涉及多個步驟。 我從事自動化工作,所以我圍繞為這些調查創建的頁面對象設計測試。 我們將此特定調查稱為“流量”調查,因為它有多個步驟。 因此,您可以跳過步驟1(調查A),然后完成或跳過步驟2(調查B),然后完成或跳過步驟3(調查C)。 天真地,我們可以編寫一個測試,其中只有以下方法:

public void completeSurveyA() {
    //...
}
public void skipSurveyB() {
    //...
}
public void completeSurveyB() {
    //...
}
public void skipSurveyC() { 
    //...
}
public void completeSurveyC() {
    //...
}

你會像這樣使用它

completeSurveyA();
skipSurveyB();
completeSurveyC();

但是,這可能是一個問題,因為我們可能在調用completeSurveyB()之前調用completeSurveyA() ,調用completeSurveyA兩次等等,測試會中斷。 為了避免這種情況,我介紹了一種不同的方法,在surveyA上調用方法將返回一個surveyB對象,該對象將返回一個surveyC對象。

public class SurveyFlow() {
    public SurveyB completeSurveyA() {
        //...
        return new SurveyB();
    }
    private class SurveyB() {
        public SurveyC skipSurveyB() {
            //...
            return new SurveyC();
        }
        public SurveyC completeSurveyB() {
            //...
            return new SurveyC();
        }
        private class SurveyC() {
            public void skipSurveyC() {
                //...
            }
            public void completeSurveyC() {
                //...
            }
        }
    }
}

你會像這樣使用它

new SurveyFlow().completeSurveyA().skipSurveryB().completeSurveyC();

這種模式讓我想起了狀態機,因為在不同的狀態下只有某些方法可用,但我想知道這種模式是否有更具體的名稱。

這在某種程度上是狀態模式,但並不完全遵循GoF描述的狀態模式,因為您不是更改單個對象的狀態,而是創建並返回您之后使用的不同類的新對象。

實際上,這類似於Builder模式,其中completeSurveyC()充當buildgetResult方法,用於從之前指定的多個組成部分構建Surway

根據您的示例的類,它是一個FluentInterface

關於這種風格可能最重要的一點是,意圖是按照內部DomainSpecificLanguage的方式做一些事情。 (...)API主要設計為可讀和流動。

它不是構建器模式,因為您沒有構建任何東西(即,您沒有最終的build()方法,其中前面步驟中收集的數據用於創建實例)。

它也不是狀態模式,因為操作(在這種情況下為skip()complete() )不依賴於對象的狀態(實際上步驟沒有狀態)。

本來是狀態模式如果整個調查已經建模為一個對象的一個方法,它的實現依賴於不同的狀態(在這種情況下,美國將成為步驟加采取的行動,即surveyACompletedsurveyASkippedsurveyBCompletedsurveyBSkipped等等,而方法就像nextStep() ):

public class SurveyFlow {

    private SurveyState state; // this represents the current step

    public SurveyFlow(boolean skipFirst) {
        this.state = skipFirst ? new SurveyASkipped() : new SurveyACompleted();
    }

    void setState(SurveyState state) {
        this.state = state;
    }

    public void takeStep(boolean skipNext) { // takeStep operation delegated 
                                             // to the state (current step)
        this.state.takeStep(skipNext, this); // "this" passed to the step so 
                                             // that it can switch to the 
                                             // next step if needed
    }
}

狀態將由SurveyFlow每個步驟多態表示:

abstract class SurveyState {

    protected abstract void takeStep(boolean skipNext, SurveyFlow survey);
}

調查A州將如下:

class SurveyACompleted extends SurveyState {

    protected void takeStep(boolean skipNext, SurveyFlow survey) {
        // ...

        survey.setState(skipNext ? new SurveyBSkipped() : new SurveyBCompleted());
    }
}

class SurveyASkipped extends SurveyState {

    protected void takeStep(boolean skipNext, SurveyFlow survey) {
        // ...

        survey.setState(skipNext ? new SurveyBSkipped() : new SurveyBCompleted());
    }
}

調查B的狀態如下:

class SurveyBCompleted extends SurveyState {

    protected void takeStep(boolean skipNext, SurveyFlow survey) {
        // ...

        survey.setState(skipNext ? new SurveyCSkipped() : new SurveyCCompleted());
    }
}

class SurveyBSkipped extends SurveyState {

    protected void takeStep(boolean skipNext, SurveyFlow survey) {
        // ...

        survey.setState(skipNext ? new SurveyCSkipped() : new SurveyCCompleted());
    }
}

對於你的例子:

  1. 完成調查A.
  2. 跳過調查B.
  3. 完成調查C.

你可以這樣做:

SurveyFlow survey = new SurveyFlow(false); // will complete survey A
survey.takeStep(true);                     // completed survey A and will skip survey B
survey.takeStep(false);                    // skipped survey A and will complete survey C
survey.takeStep(true);                     // completed survey C

如果調查C是最后一步,那么它可以忽略boolean參數,不應該設置更多步驟。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM