繁体   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