在我的工作中,我们进行了调查,一项调查涉及多个步骤.我从事自动化工作,所以我围绕为这些调查创建的页面对象设计测试.我们将此特定调查称为“流量”调查,因为它有多个步骤.因此,您可以跳过步骤1(调查A),然后完成或跳过步骤2(调查B),然后完成或跳过步骤3(调查C).天真地,我们可以编写一个测试,其中只有以下方法:
public void completeSurveyA() { //... } public void skipSurveyB() { //... } public void completeSurveyB() { //... } public void skipSurveyC() { //... } public void completeSurveyC() { //... }
你会像这样使用它
completeSurveyA(); skipSurveyB(); completeSurveyC();
但是,这可能是一个问题,因为我们可能在调用completeSurveyA()之前调用completeSurveyB(),调用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:
Probably the most important thing to notice about this style is that the intent is to do something along the lines of an internal DomainSpecificLanguage. (…) The API is primarily designed to be readable and to flow.
它不是构建器模式,因为您没有构建任何东西(即,您没有最终的build()方法,其中前面步骤中收集的数据用于创建实例).
它也不是状态模式,因为操作(在这种情况下为skip()和complete())不依赖于对象的状态(实际上步骤没有状态).
如果整个调查被建模为一个对象,其实现取决于不同的状态(在这种情况下,状态将是步骤加上采取的行动,即调查已完成,调查已确定,调查已完成,调查BSkipped),这将是状态模式等等,而方法就像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()); } }
对于你的例子:
>完成调查A.
>跳过调查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是最后一步,那么它可以忽略布尔参数,不应该设置更多步骤.