在我的工作中,我们进行了调查,而一项调查涉及多个步骤。我从事自动化工作,因此我围绕为这些调查创建的页面对象设计测试。我们将此特定调查称为“流量”调查,因为它包含多个步骤。因此,您可以跳过第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();

该模式让我想起了状态机,因为在某些状态下只有某些方法可供您使用,但是我想知道该模式是否有更具体的名称。

最佳答案

根据您的示例的类,它是FluentInterface:



这不是构建器模式,因为您没有构建任何东西(即,您没有最终的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());
    }
}

例如:
  • 完成调查
  • 跳过调查B
  • 完成调查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参数,并且不应设置其他步骤。

    09-30 15:24
    查看更多