Design Patterns seven: state mode (State)

In the software development process, the application of some objects may make different behavior depending on the circumstances, we call this object called stateful objects, and the properties of one influence the behavior of an object or multiple dynamic called state. When the state of an object to interact with external events, it will change its internal state, so that their behavior will change accordingly. Such as human emotions have a happy time and a sad time, different emotions have different behavior, of course, the outside world will also affect their mood changes.

This object has a state of programming, the traditional solution is: all these situations into consideration are all possible, and if-else statements do use state determination, then the processing of different situations. But many state of the object, the procedure will become very complicated. And to add new status To add a new if-else statement, which is contrary to the "principle of opening and closing" is not conducive to the expansion of the program.

If the above problems, "state mode" can be a good resolved. Thought the state model is solved: When the conditional expression control of an object state transition is too complex, the relevant "Analyzing logic" extracted, into a series of classes among the state, so that the original complex logic can be simplified determination.

State pattern definition and characteristics

Defined state (State) mode: the state of a subject, the complex "decision logic" extracted objects to a different state, which allows the state of the object changes behavior when its internal state changes.

State model is an object behavioral pattern, its main advantages are as follows.

  1. State model associated with the specific state to a localized state behavior, and the behavior of the different states separated, meet "single responsibility principle."
  2. Reduce interdependencies between objects. The target different states will make the introduction of a separate state transition become clearer, and reduce interdependencies between objects.
  3. In favor of the extension. Through new subclass definition easily add new states and transitions.


The main disadvantage of the state of mode are as follows.

  1. The number of classes and objects using the system inevitably increases state pattern.
  2. Structure and implementation of the state model are more complex, if used improperly can lead to confusion and structure of the program code.

Architecture and Implementation of state pattern

The state of the object model to change behavior by environmental packaging in a different state object, the intention is to make an object change its internal state when their behavior has changed. Now we have to analyze the basic structure and implementation.

1. Structure Model

State model consists of the following major role.

  1. Environment (Context) Role: Also called context, which defines the interface of interest to clients, maintaining a current status and commissioned state related to the current operating state of the object to handle.
  2. Abstract state (State) Roles: defining an interface for a particular package environment state object corresponding to behavior.
  3. Specific state (Concrete State) Role: The abstract states corresponding behavior.


The structure shown in Figure 1.

                   FIG state pattern structure
 

2. Mode of realization

State pattern codes are as follows:

package state;
public class StatePatternClient
{
    public static void main(String[] args)
    {       
        Context context=new Context();    //创建环境       
        context.Handle();    //处理请求
        context.Handle();
        context.Handle();
        context.Handle();
    }
}
//环境类
class Context
{
    private State state;
    //定义环境类的初始状态
    public Context()
    {
        this.state=new ConcreteStateA();
    }
    //设置新状态
    public void setState(State state)
    {
        this.state=state;
    }
    //读取状态
    public State getState()
    {
        return(state);
    }
    //对请求做处理
    public void Handle()
    {
        state.Handle(this);
    }
}
//抽象状态类
abstract class State
{
    public abstract void Handle(Context context);
}
//具体状态A类
class ConcreteStateA extends State
{
    public void Handle(Context context)
    {
        System.out.println("当前状态是 A.");
        context.setState(new ConcreteStateB());
    }
}
//具体状态B类
class ConcreteStateB extends State
{
    public void Handle(Context context)
    {
        System.out.println("当前状态是 B.");
        context.setState(new ConcreteStateA());
    }
}

Program results are as follows: 

当前状态是 A.
当前状态是 B.
当前状态是 A.
当前状态是 B.

Examples of the application state pattern

[Example 1] with a "model state" Design a state transition program student achievement.

Analysis: This example includes the "fail", "medium" and "excellent" three states, when the student's score is less than 60 time-sharing "fail" state, when the score is greater than or equal to 60 and less than 90 minutes for the time-sharing "Medium "state, when the score is greater than or equal to 90 time-sharing as" excellent "condition, we use the state model to achieve this program.

First, the definition of an abstract state class (AbstractState), which contains the environmental attributes, attribute name and current score status attributes and sub-subtraction method addScore (intx) and checking the current state of the abstract method checkState (); then, the definition of "no passing "state class LowState," intermediate "state class MiddleState and" excellent "state class HighState, they are specific state category, achieving checkState () method, is responsible for checking their own state, and according to conversion; and finally, the definition of environmental ( ScoreContext), which contains the current state of the object and the method of subtraction points add (int score), to change the performance state of the customer class by this method. Figure 2 is a structural view.
 

                    State transition diagram the structure of the program of student achievement

Code is as follows:

package state;
public class ScoreStateTest
{
    public static void main(String[] args)
    {
        ScoreContext account=new ScoreContext();
        System.out.println("学生成绩状态测试:");
        account.add(30);
        account.add(40);
        account.add(25);
        account.add(-15);
        account.add(-25);
    }
}
//环境类
class ScoreContext
{
    private AbstractState state;
    ScoreContext()
    {
        state=new LowState(this);
    }
    public void setState(AbstractState state)
    {
        this.state=state;
    }
    public AbstractState getState()
    {
        return state;
    }   
    public void add(int score)
    {
        state.addScore(score);
    }
}
//抽象状态类
abstract class AbstractState
{
    protected ScoreContext hj;  //环境
    protected String stateName; //状态名
    protected int score; //分数
    public abstract void checkState(); //检查当前状态
    public void addScore(int x)
    {
        score+=x;       
        System.out.print("加上:"+x+"分,\t当前分数:"+score );
        checkState();
        System.out.println("分,\t当前状态:"+hj.getState().stateName);
    }   
}
//具体状态类:不及格
class LowState extends AbstractState
{
    public LowState(ScoreContext h)
    {
        hj=h;
        stateName="不及格";
        score=0;
    }
    public LowState(AbstractState state)
    {
        hj=state.hj;
        stateName="不及格";
        score=state.score;
    }
    public void checkState()
    {
        if(score>=90)
        {
            hj.setState(new HighState(this));
        }
        else if(score>=60)
        {
            hj.setState(new MiddleState(this));
        }
    }   
}
//具体状态类:中等
class MiddleState extends AbstractState
{
    public MiddleState(AbstractState state)
    {
        hj=state.hj;
        stateName="中等";
        score=state.score;
    }
    public void checkState()
    {
        if(score<60)
        {
            hj.setState(new LowState(this));
        }
        else if(score>=90)
        {
            hj.setState(new HighState(this));
        }
    }
}
//具体状态类:优秀
class HighState extends AbstractState
{
    public HighState(AbstractState state)
    {
        hj=state.hj;
        stateName="优秀";
        score=state.score;
    }           
    public void checkState()
    {
        if(score<60)
        {
            hj.setState(new LowState(this));
        }
        else if(score<90)
        {
            hj.setState(new MiddleState(this));
        }
    }
}

Program results are as follows: 

学生成绩状态测试:
加上:30分,    当前分数:30分,    当前状态:不及格
加上:40分,    当前分数:70分,    当前状态:中等
加上:25分,    当前分数:95分,    当前状态:优秀
加上:-15分,    当前分数:80分,    当前状态:中等
加上:-25分,    当前分数:55分,    当前状态:不及格

[Example 2] with "status pattern" design condition conversion program a multi-threaded.

Analysis: Multithreading There are five states, namely for the new state, ready state, running state, blocking state and death state, each state will encounter when converting to other states where relevant method invocation or event-triggered, as shown in its state transition rule 3 shown in FIG.
 

                      Thread state transition diagram
Thread 3 state transition diagram of FIG.


Now define the state of an abstract class (TheadState), then the design of a particular state for each state type shown in Figure 3, which is the new state (New), the ready state (the Runnable), the operating state (Running), blocked state ( Blocked) and death state (dead), each state has a state transition triggering method thereof, environmental (ThreadContext) into an initial state in Mr (New), and provide a trigger method, the thread is a state transition diagram shown in FIG. 4 the program structure of FIG.
 

                          Structure of FIG conversion program thread state
Structure of FIG. 4 FIG conversion program thread state


Code is as follows:

package state;
public class ThreadStateTest
{
    public static void main(String[] args)
    {
        ThreadContext context=new ThreadContext();
        context.start();
        context.getCPU();
        context.suspend();
        context.resume();
        context.getCPU();
        context.stop();
    }
}
//环境类
class ThreadContext
{
    private ThreadState state;
    ThreadContext()
    {
        state=new New();
    }
    public void setState(ThreadState state)
    {
        this.state=state;
    }
    public ThreadState getState()
    {
        return state;
    }   
    public void start()
    {
        ((New) state).start(this);
    }
    public void getCPU()
    {
        ((Runnable) state).getCPU(this);
    }
    public void suspend()
    {
        ((Running) state).suspend(this);
    }
    public void stop()
    {
        ((Running) state).stop(this);
    }
    public void resume()
    {
        ((Blocked) state).resume(this);
    }
}
//抽象状态类:线程状态
abstract class ThreadState
{
    protected String stateName; //状态名
}
//具体状态类:新建状态
class New extends ThreadState
{
    public New()
    {       
        stateName="新建状态";
        System.out.println("当前线程处于:新建状态.");   
    }
    public void start(ThreadContext hj)
    {
        System.out.print("调用start()方法-->");
        if(stateName.equals("新建状态"))
        {
            hj.setState(new Runnable());
        }
        else
        {
            System.out.println("当前线程不是新建状态,不能调用start()方法.");
        }
    }   
}
//具体状态类:就绪状态
class Runnable extends ThreadState
{
    public Runnable()
    {       
        stateName="就绪状态";
        System.out.println("当前线程处于:就绪状态.");   
    }
    public void getCPU(ThreadContext hj)
    {
        System.out.print("获得CPU时间-->");
        if(stateName.equals("就绪状态"))
        {
            hj.setState(new Running());
        }
        else
        {
            System.out.println("当前线程不是就绪状态,不能获取CPU.");
        }
    }   
}
//具体状态类:运行状态
class Running extends ThreadState
{
    public Running()
    {       
        stateName="运行状态";
        System.out.println("当前线程处于:运行状态.");   
    }
    public void suspend(ThreadContext hj)
    {
        System.out.print("调用suspend()方法-->");
        if(stateName.equals("运行状态"))
        {
            hj.setState(new Blocked());
        }
        else
        {
            System.out.println("当前线程不是运行状态,不能调用suspend()方法.");
        }
    }
    public void stop(ThreadContext hj)
    {
        System.out.print("调用stop()方法-->");
        if(stateName.equals("运行状态"))
        {
            hj.setState(new Dead());
        }
        else
        {
            System.out.println("当前线程不是运行状态,不能调用stop()方法.");
        }
    }
}
//具体状态类:阻塞状态
class Blocked extends ThreadState
{
    public Blocked()
    {       
        stateName="阻塞状态";
        System.out.println("当前线程处于:阻塞状态.");   
    }
    public void resume(ThreadContext hj)
    {
        System.out.print("调用resume()方法-->");
        if(stateName.equals("阻塞状态"))
        {
            hj.setState(new Runnable());
        }
        else
        {
            System.out.println("当前线程不是阻塞状态,不能调用resume()方法.");
        }
    }   
}
//具体状态类:死亡状态
class Dead extends ThreadState
{
    public Dead()
    {
        stateName="死亡状态";
        System.out.println("当前线程处于:死亡状态.");   
    }   
}

Program results are as follows: 

当前线程处于:新建状态.
调用start()方法-->当前线程处于:就绪状态.
获得CPU时间-->当前线程处于:运行状态.
调用suspend()方法-->当前线程处于:阻塞状态.
调用resume()方法-->当前线程处于:就绪状态.
获得CPU时间-->当前线程处于:运行状态.
调用stop()方法-->当前线程处于:死亡状态.

 

State mode of application scenarios

Generally used state model may be considered in the following cases.

  • When the behavior of an object depends on its state, and it must change its behavior depending on the state at runtime, you can consider the use state mode.
  • When operating a large branch structure contained in, and determines the state of the branches of the object.

Extended status mode

In some cases, there may be multiple objects need to share a set of environmental state, then the need to introduce Flyweight, particularly those in the set state of the object for program sharing, the structure shown in Figure 5.
 

              FIG shared state configuration mode
 


Analysis: Shared state except model is increased in the environment of a class associated HashMap to save state may be acquired from a certain state when necessary, which code is as follows:

package state;
import java.util.HashMap;
public class FlyweightStatePattern
{
    public static void main(String[] args)
    {
        ShareContext context=new ShareContext(); //创建环境       
        context.Handle(); //处理请求
        context.Handle();
        context.Handle();
        context.Handle();
    }
}
//环境类
class ShareContext
{
    private ShareState state;
    private HashMap<String, ShareState> stateSet=new HashMap<String, ShareState>();
    public ShareContext()
    {
        state=new ConcreteState1();
        stateSet.put("1", state);
        state=new ConcreteState2();
        stateSet.put("2", state);
        state=getState("1");
    }
    //设置新状态
    public void setState(ShareState state)
    {
        this.state=state;
    }
    //读取状态
    public ShareState getState(String key)
    {
        ShareState s=(ShareState)stateSet.get(key);
        return s;
    }
    //对请求做处理
    public void Handle()
    {
        state.Handle(this);
    }
}
//抽象状态类
abstract class ShareState
{
    public abstract void Handle(ShareContext context);
}
//具体状态1类
class ConcreteState1 extends ShareState
{
    public void Handle(ShareContext context)
    {
        System.out.println("当前状态是: 状态1");
        context.setState(context.getState("2"));
    }
}
//具体状态2类
class ConcreteState2 extends ShareState
{
    public void Handle(ShareContext context)
    {
        System.out.println("当前状态是: 状态2");
        context.setState(context.getState("1"));
    }
}

 Program results are as follows:

当前状态是: 状态1
当前状态是: 状态2
当前状态是: 状态1
当前状态是: 状态2

 

Published 136 original articles · won praise 6 · views 1544

Guess you like

Origin blog.csdn.net/weixin_42073629/article/details/104437847