JAVA设计模式九之状态模式State

来源:互联网 发布:系统数据对接 编辑:程序博客网 时间:2024/06/09 23:07

                                         JAVA设计模式九之状态模式State

1基本概念:当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。

2作用:状态模式主要解决的是当控制一个对象状态转换的条件表达式过于复杂时的情况。把状态的判断逻辑转移到表示不同状态的一系列类当中,可以把复杂的判断逻辑简化。

当状态判断很简单时,没有必要用状态模式了。

3UML类图

4状态模式的好处

1将于特定状态相关的行为局部化,并且将不同状态的行为分割开来。就是将特定的状态相关的行为都放入一个对象中,由于所有与状态相关的代码都存在与某个ConcreteState【具体状态类中】,所以通过定义新的子类可以很容易地增加新的状态和转换。

2这样做的目的就是为了消除庞大的条件分支语句,状态模式通过把各种状态转移逻辑分布到State的子类之间,来减少相互间的依赖。

5使用场景

当一个对象的行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为时,就可以考虑使用状态模式。

解释:即当有很多判断时,想办法把这些分支变成一个又一个的类,,增加时不会影响其他类,然后状态的变化在各自的类中完成。【即一个状态子类里完成一个判断满足状态执行该状态的方法,,否则转到下一个类中】。这样利于维护,职责单一原则,不至于牵一发 而动全身。

6模拟使用场景加班敲代码      时间不同工作状态和效率也不同

State接口  

//定义状态接口        里边定义每个状态子类共有行为的抽象方法public interface State {    //写代码    //维护一个Context【就是管理每个状态的管理器】实例    public abstract void WriteCode(WorkManager workManager);    }

WorkManager工作管理类相当于Context

//工作管理类就是状态模式的Context  一直维持一个状态子类public class WorkManager {    //定义状态    传入状态子类给其赋值    private State mCurrentState;    //定义时间的标记   就是根据时间来划分状态的    private double currentHour;    //管理器的构造函数   可以从构造传入初始状态   也可以直接初始    public WorkManager() {        mCurrentState=new MorningState();   //初始化工作状态类为早上状态    }    public double getCurrentHour() {        return currentHour;    }    public void setCurrentHour(double currentHour) {        this.currentHour = currentHour;    }    public State getCurrentState() {        return mCurrentState;    }    public void setCurrentState(State currentState) {        mCurrentState = currentState;    }    //写代码的方法    public void WriteCode(){        //调用当前的状态写代码   看看是哪种状态下写的代码        mCurrentState.WriteCode(this);  //写代码传入工作管理器【传当前即可】    }}

状态子类 里边分别实现了该状态下的具体操作的方法

MorningState

//早上状态     写代码public class MorningState implements State{    //该状态下写代码    传入当前管理类  可以获取当前时间 分派状态  同时更改管理器的状态子类    @Override    public void WriteCode(WorkManager workManager) {         if(workManager.getCurrentHour()<12){  //小于12点就是早上             Log.d("TAG", "WriteCode: ---------上午工作精神百倍当前时间为"+workManager.getCurrentHour());         }else{    //当前状态调用写代码时发现不符合当前状态的标准【就是已经过中午了则在类内部改变状态重新调写代码的方法】             workManager.setCurrentState(new NoonState());             workManager.WriteCode();         }    }}

NoonState

//中午状态写代码public class NoonState implements State{    @Override    public void WriteCode(WorkManager workManager) {        if(workManager.getCurrentHour()<13){   //午睡状态            Log.d("TAG", "WriteCode:----------------午睡犯困 "+workManager.getCurrentHour());        }else{//发现与当前状态不符合  则改变状态子类            workManager.setCurrentState(new AfterNoonState());            workManager.WriteCode();        }    }} 

AfterNoonState

public class AfterNoonState implements State{    @Override    public void WriteCode(WorkManager workManager) {        if(workManager.getCurrentHour()<17){            Log.d("TAG", "WriteCode: ------------------下午工作了"+workManager.getCurrentHour());        }else{            workManager.setCurrentState(new EveningState());            workManager.WriteCode();        }    }}

EveningState

public class EveningState implements State {    @Override    public void WriteCode(WorkManager workManager) {        if(workManager.getCurrentHour()<21){            Log.d("TAG", "WriteCode: -------------------晚间工作状态"+workManager.getCurrentHour());        }else{            workManager.setCurrentState(new OverTimeState());            workManager.WriteCode();        }    }}

OverTimeState

public class OverTimeState implements  State {    @Override    public void WriteCode(WorkManager workManager) {        Log.d("TAG", "WriteCode: -------------------------加班累的不行了");    }}

客户端代码

public class MainActivity extends AppCompatActivity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        //创建工作管理类        WorkManager workManager=new WorkManager();  //里边已经初始化了初始工作状态        workManager.setCurrentHour(9);        workManager.WriteCode();        workManager.setCurrentHour(10);        workManager.WriteCode();        workManager.setCurrentHour(12);        workManager.WriteCode();        workManager.setCurrentHour(13);        workManager.WriteCode();        workManager.setCurrentHour(14);        workManager.WriteCode();        workManager.setCurrentHour(17);        workManager.WriteCode();    }}

效果:












原创粉丝点击