在我的工作中,我们进行了调查,一项调查涉及多个步骤。我从事自动化工作,所以我围绕为这些调查创建的页面对象设计测试。我们将此特定调查称为“流动”和“#34;调查因为它有多个步骤。因此,您可以跳过步骤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();
这种模式让我想起了状态机,因为在不同的状态下只有某些方法可用,但我想知道这种模式是否有更具体的名称。
答案 0 :(得分:1)
这在某种程度上是状态模式,但并不完全遵循GoF描述的状态模式,因为你没有改变单个对象的状态,而是创建并返回一个不同类的新对象,你之后使用。
实际上,这类似于Builder模式,其中completeSurveyC()
充当build
或getResult
方法,用于从之前指定的多个组成部分构建Surway
。
答案 1 :(得分:1)
根据您示例的类,它是FluentInterface:
关于这种风格,最重要的事情可能是意图是按照内部DomainSpecificLanguage的方式做一些事情。 (...)API主要设计为可读和流动。
它不是构建器模式,因为您没有构建任何东西(即,您没有最终build()
方法,其中使用先前步骤中收集的数据来创建实例)。
它也不是状态模式,因为操作(在这种情况下skip()
和complete()
)不依赖于对象的状态(实际上步骤不具备一个州)。
如果整个调查已被建模为一个对象,并且其实现取决于不同的状态(在这种情况下,状态将是步骤加上行动,那么将状态模式采取,即surveyACompleted
,surveyASkipped
,surveyBCompleted
,surveyBSkipped
等,而方法类似于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());
}
}
对于你的例子:
你可以这样做:
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
参数,并且不应该设置进一步的步骤。