Lying design pattern notes (xiii) の state mode

For chestnuts

Problem Description

Work day, morning, good condition, noon to sleep, gradual recovery in the afternoon, overtime bitter suffering. Depending on different working conditions reflect the time.

Simple implementation

Work

/**
 * 工作类
 * Created by callmeDevil on 2019/8/3.
 */
public class Work {

    private int hour;
    private boolean finish = false;

    public void writeProgram() {
        if (hour < 12) {
            System.out.println(String.format("当前时间:%s点,上午工作,精神百倍", hour));
        } else if (hour < 13) {
            System.out.println(String.format("当前时间:%s点,饿了,午饭;犯困,午休", hour));
        } else if (hour < 17) {
            System.out.println(String.format("当前时间:%s点,下午状态还不错,继续努力", hour));
        } else {
            if (finish) {
                System.out.println(String.format("当前时间:%s点,下班回家了", hour));
            } else {
                if (hour < 21) {
                    System.out.println(String.format("当前时间:%s点,加班哦,疲累至极", hour));
                } else {
                    System.out.println(String.format("当前时间:%s点,不行了,睡着了", hour));
                }
            }
        }
    }

    // 省略 get set 方法

}

test

public class Test {
    public static void main(String[] args) {
        // 紧急项目
        Work emergencyProjects = new Work();
        emergencyProjects.setHour(9);
        emergencyProjects.writeProgram();
        emergencyProjects.setHour(10);
        emergencyProjects.writeProgram();
        emergencyProjects.setHour(11);
        emergencyProjects.writeProgram();
        emergencyProjects.setHour(12);
        emergencyProjects.writeProgram();
        emergencyProjects.setHour(13);
        emergencyProjects.writeProgram();
        emergencyProjects.setHour(14);
        emergencyProjects.writeProgram();
        emergencyProjects.setHour(17);
        emergencyProjects.writeProgram();
        emergencyProjects.setHour(19);
        emergencyProjects.writeProgram();
        emergencyProjects.setHour(22);
        emergencyProjects.writeProgram();
        System.out.println("--------------------------");
        emergencyProjects.setFinish(true);
        emergencyProjects.setHour(19);
        emergencyProjects.writeProgram();
        emergencyProjects.setHour(22);
        emergencyProjects.writeProgram();
    }
}

Test Results

当前时间:9点,上午工作,精神百倍
当前时间:10点,上午工作,精神百倍
当前时间:11点,上午工作,精神百倍
当前时间:12点,饿了,午饭;犯困,午休
当前时间:13点,下午状态还不错,继续努力
当前时间:14点,下午状态还不错,继续努力
当前时间:17点,加班哦,疲累至极
当前时间:19点,加班哦,疲累至极
当前时间:22点,不行了,睡着了
--------------------------
当前时间:19点,下班回家了
当前时间:22点,下班回家了

There is a problem

Object-oriented design is actually a code decomposition do want the responsibility. This class against the " single responsibility principle ." If the company for safety of employees and require employees to leave the company before 20:00 (think like, the reality is often impossible ..), it will change the current approach, maintaining a great risk of error, and this is contrary to the " open - closed principle ."

State mode

definition

When allowed to change the internal state of an object to change its behavior, the object appears to change its class.

The main solution is to state mode when the conditional expression control of an object state transition is too complex situations. Determining the logic state of the different states is transferred to a series of classes which can simplify the complex decision logic . Of course, if the state judgment is very simple, that there is no need to use state models a.

UML diagrams

Code

State

/**
 * 抽象状态
 * Created by callmeDevil on 2019/8/3.
 */
public abstract class State {
    public abstract void writeProgram(Work work);
}

ForenoonState

/**
 * 上午工作状态
 * Created by callmeDevil on 2019/8/3.
 */
public class ForenoonState extends State{
    @Override
    public void writeProgram(Work work) {
        if (work.getHour() < 12) {
            System.out.println(String.format("当前时间:%s点,上午工作,精神百倍", work.getHour()));
        } else {
            // 超过12点,转入中午工作状态
            work.setState(new NoonState());
            work.writeProgram();
        }
    }
}

NoonState

/**
 * 中午工作状态
 * Created by callmeDevil on 2019/8/3.
 */
public class NoonState extends State{
    @Override
    public void writeProgram(Work work) {
        if (work.getHour() < 13) {
            System.out.println(String.format("当前时间:%s点,饿了,午饭;犯困,午休", work.getHour()));
        } else {
            // 超过13点,转入下午工作状态
            work.setState(new AfternoonState());
            work.writeProgram();
        }
    }
}

AfternoonState

/**
 * 下午工作状态
 * Created by callmeDevil on 2019/8/3.
 */
public class AfternoonState extends State{
    @Override
    public void writeProgram(Work work) {
        if (work.getHour() < 17) {
            System.out.println(String.format("当前时间:%s点,下午状态还不错,继续努力", work.getHour()));
        } else {
            // 超过17点,转入傍晚工作状态
            work.setState(new EveningState());
            work.writeProgram();
        }
    }
}

EveningState

/**
 * 傍晚工作状态
 * Created by callmeDevil on 2019/8/3.
 */
public class EveningState extends State {
    @Override
    public void writeProgram(Work work) {
        if (work.isTaskFinished()) {
            // 如果完成任务,转入下班状态
            work.setState(new RestState());
        } else {
            if (work.getHour() < 21) {
                System.out.println(String.format("当前时间:%s点,加班哦,疲累至极", work.getHour()));
            } else {
                // 超过21点,转入睡眠工作状态
                work.setState(new SleepingState());
                work.writeProgram();
            }
        }
    }
}

SleepingState

/**
 * 睡眠工作状态
 * Created by callmeDevil on 2019/8/3.
 */
public class SleepingState extends State{
    @Override
    public void writeProgram(Work work) {
        System.out.println(String.format("当前时间:%s点,不行了,睡着了", work.getHour()));
    }
}

rest State

/**
 * 下班工作状态
 * Created by callmeDevil on 2019/8/3.
 */
public class RestState extends State{
    @Override
    public void writeProgram(Work work) {
        System.out.println(String.format("当前时间:%s点,下班回家了", work.getHour()));
    }
}

Work

/**
 * 工作类,此时没有了过长的分支判断语句
 * Created by callmeDevil on 2019/8/3.
 */
public class Work {

    private State current;
    private int hour; // 时间,状态转换的依据
    private boolean taskFinished; // 任务完成,是否能下班的依据

    public Work(){
        // 工作初始化为上午工作状态,即上午9点开始上班
        current = new ForenoonState();
    }

    public void writeProgram(){
        current.writeProgram(this);
    }

    // 省略 get set 方法

}

Test code and test results above.

to sum up

  • The benefit is associated with a particular state of localized behavior, and the behavior of different states separated.
  • The specific state related behavior into an object, because all state related code are present in a ConcreteState in, so the new sub-class definition can easily add new states and transitions.
  • State mode distribution of the various state transition logic between the subclass of State to reduce mutual dependence.
  • When the behavior of an object depends on its state, and must change its behavior depending on the state at runtime, you can consider the use state mode.

Guess you like

Origin www.cnblogs.com/call-me-devil/p/11295085.html