Lab3漫谈(1)-状态模式

前言

Lab3中需要使用状态模式来控制一个计划项的运行状态,并且在五个应用中总共有两类状态转换图(状态机)。因为有一些状态是重叠的,因此可以将他们共享,二选一,我采用布尔变量控制,但是状态模式的基本“套路”还是没有变的。

模式结构

状态模式包含以下主要角色。

  • 环境(Context)角色:也称为上下文,它定义了客户感兴趣的接口,维护一个当前状态,并将与状态相关的操作委托给当前状态对象来处理。
  • 抽象状态(State)角色:定义一个接口,用以封装环境对象中的特定状态所对应的行为。
  • 具体状态(Concrete State)角色:实现抽象状态所对应的行为。

可以结合具体代码对照,State实际上被定义为一个抽象类,这个抽象类中应该包括状态机中各种状态的一些共有属性,比如“状态名”。
Concrete State 对应位State的一些具体实现类,来定义状态机中所需要的状态类。
而环境Context,不如说是状态机,前两者提供了这个“机器”的一些零件,但实际的运转却需要将这些零件组合起来。
你也可以看到,具体类的创建(或者说状态转换的一个操作)是直接new 一个对应的状态类的,这个有点像工厂模式。
代码中的状态转换图:
两类状态转化图

package Resource;
//状态机
public class StateMachine
{
    private State state;
    private boolean type;//true代表第二种
    //构造函数,初始为wait
    public StateMachine(boolean type)
    {
        state=new WAITING();
//        System.out.println(state.stateName);
        this.type=type;
    }
    public void setState(State state)
    {
        this.state=state;
    }
    public State getState()
    {
        return state;
    }
    public String getStateName(){
        return state.stateName;
    }
    public boolean allocate()
    {
        if(state.stateName.equals("未分配状态")){
            ((WAITING) state).allocate(this);
//            System.out.println(state.stateName);
            return true;
        }else
            return false;

    }
    public boolean run()
    {
        if(state.stateName.equals("已分配状态")){
            ((ALLOCATED) state).run(this);
//            System.out.println(state.stateName);
            return true;
        }else
            return false;
    }
    public boolean block()
    {
        if(this.type)
            return false;
        if(state.stateName.equals("运行状态")){
            ((Running) state).suspend(this);
//            System.out.println(state.stateName);
            return true;
        }else
            return false;

    }
    public boolean end()
    {
        if(state.stateName.equals("运行状态")){
            ((Running) state).stop(this);
//            System.out.println(state.stateName);
            return true;
        }else
            return false;

    }
    public boolean resume()
    {
        if(this.type)
            return false;
        if(state.stateName.equals("挂起状态")){
            ((Blocked) state).resume(this);
//            System.out.println(state.stateName);
            return true;
        }else
            return false;

    }
    public boolean cancel()
    {
        switch (state.stateName) {
            case "未分配状态":
                ((WAITING) state).cancel(this);
//                System.out.println(state.stateName);
                return true;
            case "已分配状态":
                ((ALLOCATED) state).cancel(this);
//                System.out.println(state.stateName);
                return true;
            case "挂起状态":
                ((Blocked) state).cancel(this);
//                System.out.println(state.stateName);
                return true;
            default:
//                System.out.println(state.stateName);
//                System.out.println("当前状态不可调用cancel()");
                return false;
        }
    }
}
//抽象状态类:状态
abstract class State
{
    protected String stateName; //状态名
}
//具体状态类:未分配状态
class WAITING extends State
{
    public WAITING()
    {
        stateName="未分配状态";
    }
    //申请资源分配
    public void allocate(StateMachine hj)
    {

        if(stateName.equals("未分配状态"))
        {
            hj.setState(new ALLOCATED());
        }
        else
        {
            System.out.println("当前线程不是未分配状态,不能调用allocate()方法.");
        }
    }
    //取消
    public void cancel(StateMachine hj)
    {

        if(stateName.equals("未分配状态"))
        {
            hj.setState(new CANCELLED());
        }
        else
        {
            System.out.println("当前线程不是未分配状态,不能调用cancel()方法.");
        }
    }
}
//具体状态类:已分配状态
class ALLOCATED extends State
{
    public ALLOCATED()
    {
        stateName="已分配状态";
    }
    public void run(StateMachine hj)
    {

        if(stateName.equals("已分配状态"))
        {
            hj.setState(new Running());
        }
        else
        {
            System.out.println("当前线程不是已分配状态,不能调用run().");
        }
    }
    public void cancel(StateMachine hj)
    {
        if(stateName.equals("已分配状态"))
        {
            hj.setState(new CANCELLED());
        }
        else
        {
            System.out.println("当前线程不是已分配状态,不能调用cancel()方法.");
        }
    }
}
//具体状态类:运行状态
class Running extends State
{
    public Running()
    {
        stateName="运行状态";
    }
    public void suspend(StateMachine hj)//阻塞
    {

        if(stateName.equals("运行状态"))
        {
            hj.setState(new Blocked());
        }
        else
        {
            System.out.println("当前线程不是运行状态,不能调用suspend()方法.");
        }
    }
    public void stop(StateMachine hj)//结束
    {
        if(stateName.equals("运行状态"))
        {
            hj.setState(new ENDED());
        }
        else
        {
            System.out.println("当前线程不是运行状态,不能调用stop()方法.");
        }
    }
}
//具体状态类:挂起状态
class Blocked extends State
{
    public Blocked()
    {
        stateName="挂起状态";
    }
    public void resume(StateMachine hj)//恢复运行
    {
        if(stateName.equals("挂起状态"))
        {
            hj.setState(new Running());
        }
        else
        {
            System.out.println("当前线程不是挂起状态,不能调用resume()方法.");
        }
    }
    public void cancel(StateMachine hj)
    {
        if(stateName.equals("挂起状态"))
        {
            hj.setState(new CANCELLED());
        }
        else
        {
            System.out.println("当前线程不是挂起状态,不能调用cancel()方法.");
        }
    }
}
//具体状态类:已完成状态
class ENDED extends State
{
    public ENDED()
    {
        stateName="已完成状态";
    }
}
//具体状态类:已取消状态
class CANCELLED extends State
{
    public CANCELLED()
    {
        stateName="已取消状态";
    }
}

之后再讨论提到的工厂设计模式,其实从这章要讲的程序的可维护性和复用性来看,讲到的设计模式其实都要符合LSP原则,还是比较容易理解的,但是对于这次实验的具体内容来说,有些地方用设计模式反而变复杂了(虽然有些设计模式本身继承树就很深),而且也存在一些矛盾的地方,之后想到哪再说说吧。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值