What is the name of this Java state based design pattern?

In my work, we conducted a survey. A survey involves multiple steps I work in automation, so I design tests around the page objects created for these surveys We call this particular survey a "traffic" survey because it has multiple steps Therefore, you can skip step 1 (survey a), then complete or skip step 2 (survey b), and then complete or skip step 3 (survey C) Naively, we can write a test in which there are only the following methods:

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

You'll use it like this

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

However, this may be a problem, because we may call completeSurveyB () before calling completeSurveyA (), call completeSurveyA two times, and so on, the test will be interrupted. To avoid this, I introduced a different method. Calling the method on surveya will return a surveyb object, which will return a surveyc object

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() {
                //...
            }
        }
    }
}

You'll use it like this

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

This pattern reminds me of the state machine, because only some methods are available in different states, but I wonder if this pattern has a more specific name

Solution

According to the class of your example, it is a fluent interface:

It's not a builder pattern because you don't build anything (that is, you don't have the final build () method, where the data collected in the previous steps is used to create an instance)

It is also not a state mode, because the operation (skip () and complete () in this case) does not depend on the state of the object (in fact, the step has no state)

If the whole survey is modeled as an object, its implementation depends on different states (in this case, the state will be steps plus actions taken, that is, the survey has been completed, the survey has been determined, the survey has been completed, the survey bskipped), this will be the state mode, and the method is like 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
    }
}

The status will be represented by each step of surveyflow:

abstract class SurveyState {

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

State a will be surveyed as follows:

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());
    }
}

The status of survey B is as follows:

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());
    }
}

For your example:

>Complete survey A. > skip survey B. > complete survey C

You can do this:

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

If survey C is the last step, it can ignore Boolean parameters and should not set more steps

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>