I implemented the State pattern at work, so I will leave it in Qiita. The language used was Java 8, but most languages should be able to implement it in a similar way.
When I looked back for the first time in a year, I realized that the distinction between State and Strategy was not properly made.
After learning about state machines, I became able to understand why they are named State patterns. In the following article, I realized that the name of the sample that I used to think lightly at that time was not quite appropriate. If you call yourself the State pattern, each State object should return the State object after the state transition.
** The content of the main subject of the following article was created by converting all the States of the previous article to Strategy. I will leave the previous one for the time being **
When using the Strategy pattern, you need a Strategy object that represents each process and an object that determines which Strategy to generate. The process of deciding what to generate was placed in Factory.
//Strategy interface
public interface Strategy{
void doSomething();
}
//Strategy implementation 1
public class StrategyImpl1 implements implements Strategy {
public void doSomething(){
System.out.println("Full of Strategy1 specific processing");
}
}
//Strategy implementation 2
public class StrategyImpl2 implements implements Strategy {
public void doSomething(){
System.out.println("Full of Strategy2 specific processing");
}
}
Just having a Strategy doesn't make much sense.
//What is the benefit of writing this code?
Strategy strategy1 = new StrategyImpl1();
Strategy strategy2 = new StrategyImpl2();
Actually, you also need a class that performs conditional branch processing that manages each process.
public class Factory{
//I think it's static
public Strategy create(SomeCondition sc){
if (sc.something1) {
//Actually, it takes about two steps to create an object.
return new StateImpl1();
} else if(sc.something2) {
return new StateImpl2();
}
}
}
Therefore, the caller can write:
Factory factory = new Factory();
for(SomeCondition sc: List<SomeCondition> scs) {
Strategy strategy = factory.create(sc);
strategy.doSomething();
}
In this example, the switch statement is enough, so it doesn't make much sense, it just makes it uselessly complicated. When the conditional branching is unpleasantly complicated and there are a lot of slightly different processes to be performed as a result of the judgment, the outlook becomes considerably better (now).
It's difficult to add a lot of class files, Humans can't think of too many things or complicated things at once, so we divide them into classes to reduce the amount that we have to understand at once.
When using the State pattern, you need a State object that represents each state and an object that determines which State to generate. The process of deciding what to generate was placed in Factory.
//State interface
public interface State{
void doSomething();
}
//State implementation 1
public class StateImpl1 implements implements State {
public void doSomething(){
System.out.println("Full of State 1 specific processing");
}
}
//State implementation 2
public class StateImpl2 implements implements State {
public void doSomething(){
System.out.println("Full of State 2 specific processing");
}
}
Just preparing a State doesn't make much sense.
//What is the benefit of writing this code?
State state = new StateImpl1();
State state = new StateImpl2();
In fact, you also need a class that performs conditional branching to manage the state.
public class Factory{
//I think it's static
public State create(SomeCondition sc){
if (sc.something1) {
//Actually, it takes about two steps to create an object.
return new StateImpl1();
} else if(sc.something2) {
return new StateImpl2();
}
}
}
Therefore, the caller can write:
Factory factory = new Factory();
for(SomeCondition sc: List<SomeCondition> scs) {
State state = factory.create(sc);
state.doSomething();
}
Recommended Posts