最近学习到设计模式,现总结个人学习状态模式内容【重点在于根据它的状态改变而改变它的相关行为】。


文章目录

  • 定义
  • 优缺点
  • 优点
  • 缺点
  • 实现
  • 代码
  • 测试


定义

对有状态的对象,把复杂的“判断逻辑”提取到不同的状态对象中,允许状态对象在其内部状态发生改变时改变其行为。

优缺点

优点

  • 允许对象在内部状态发生改变时改变它的行为,对象看起来好像修改了它的类。
  • 状态模式将与特定状态相关的行为局部化到一个状态中,并且将不同状态的行为分割开来,满足“单一职责原则”。
  • 减少对象间的相互依赖。将不同的状态引入独立的对象中会使得状态转换变得更加明确,且减少对象间的相互依赖。

缺点

  • 增加系统类和对象的个数。
  • 状态模式的结构与实现都较为复杂,如果使用不当将导致程序结构和代码的混乱。
  • 状态模式对"开闭原则"的支持并不太好,对于可以切换状态的状态模式,增加新的状态类需要修改那些负责状态转换的源代码(context),否则无法切换到新增状态,而且修改某个状态类的行为也需修改对应类的源代码

实现

模拟线程:

java状态模式实例 java状态设计模式_设计模式

状态模式模拟线程流程

java状态模式实例 java状态设计模式_状态模式_02


类图:

java状态模式实例 java状态设计模式_状态模式模拟线程状态_03

环境类(context):里面维护了一个具体状态的实例(AntFarmContext)

抽象状态类(state):定义一个接口,封装一些特定的行为(AntFarmState)

具体状态类(concreteState):每个子类实现一个与context的一个状态相关的行为(New,Blocked, Runnable,Running,Dead)

状态模式的实现类的方法,一般返回值,或者是改变实例变量的值。也就是说,状态模式一般和对象的状态有关。

代码

代码中用到的静态变量类

class StaticVariables {
	public static final String NEW = "New";//新生
	public static final String RUNNABLE = "Runnable";//就绪
	public static final String RUNNING = "Running";//运行
	public static final String BLOCKED = "Blocked";//挂起
	public static final String DEAD = "Dead";//死亡
}

状态抽象类,以及具体实现

//抽象状态类:线程状态
abstract class ThreadState{
    String stateName; //状态名
}
//具体状态类:新建状态
class New extends ThreadState{
    public New(){       
        stateName=StaticVariables.NEW;
    }
    public void start(ThreadContext th){//调用开始方法进入就绪状态
        System.out.println("线程处于:"+stateName+", \t调用start()方法-->进入"+StaticVariables.RUNNABLE+"状态");
        if(StaticVariables.NEW.equals(stateName)) {
        	th.setState(new Runnable());
        } else {
            System.out.println("线程"+stateName+",不能调用start()方法.");
        }
    }   
}
//具体状态类:就绪状态
class Runnable extends ThreadState{
    public Runnable(){       
        stateName=StaticVariables.RUNNABLE;
    }
    public void getCPU(ThreadContext th){//获取cpu时间进入运行状态
        System.out.println("线程处于:"+stateName+",获得CPU时间-->进入"+StaticVariables.RUNNING+"状态");
        if(StaticVariables.RUNNABLE.equals(stateName)){
        	th.setState(new Running());
        } else {
            System.out.println("当前线程"+stateName+",不能获取CPU.");
        }
    }   
}
//具体状态类:运行状态
class Running extends ThreadState{
    public Running(){       
        stateName=StaticVariables.RUNNING;
    }
    public void waits(ThreadContext th){//进入挂起状态
        System.out.println("线程处于: "+stateName+",\t调用waits()方法-->进入"+StaticVariables.BLOCKED+"状态");
        if(StaticVariables.RUNNING.equals(stateName)){
        	th.setState(new Blocked());
        }else {
            System.out.println("线程"+stateName+",不能调用waits()方法.");
        }
    }
    public void dead(ThreadContext th){//进入死亡状态
        System.out.println("线程处于: "+stateName+",\t调用dead()方法-->进入"+StaticVariables.DEAD+"状态");
        if(StaticVariables.RUNNING.equals(stateName)){
        	th.setState(new Dead());
        }else{
            System.out.println("线程"+stateName+",不能调用dead()方法.");
        }
    }
}
//具体状态类:阻塞状态
class Blocked extends ThreadState{
    public Blocked(){       
        stateName=StaticVariables.BLOCKED;
    }
    public void ready(ThreadContext th){//进入就绪状态
        System.out.println("线程处于: "+stateName+",\t调用ready()方法-->进入"+StaticVariables.RUNNABLE+"状态");
        if(StaticVariables.BLOCKED.equals(stateName)){    
        	th.setState(new Runnable());
        }else{
            System.out.println("线程"+stateName+",不能调用ready()方法.");
        }
    }   
}
//具体状态类:死亡状态
class Dead extends ThreadState{
    public Dead(){
        stateName=StaticVariables.DEAD;
        System.out.println("线程处于: "+stateName);   
    }   
}

上下文对象

//环境类
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(){//开始->进入新生态
    	if(state instanceof New) {
    		((New) state).start(this);
    	} else{
    		System.out.println("当前状态已为"+state.stateName+",不可直接运行!");
    	}
    }//运行
    public void getCPU(){ //获取cpu时间片->准备进入运行态
    	if(state instanceof Runnable) {
    		((Runnable) state).getCPU(this);
    	}else {
    		System.out.println("当前状态已为"+state.stateName+", 直接可以继续运行!");
    	}
    }
    public void waits(){//进入等待状态->挂起线程
    	if(state instanceof Running) {
        	((Running) state).waits(this);
    	} else {
    		System.out.println("当前状态为"+state.stateName+",不能转入waits状态");
    	}
    }
    public void dead(){//死亡方法->线程运行结束
    	if(state instanceof Running) {
    		((Running) state).dead(this);
    	} else  {
    		System.out.println("当前状态为"+state.stateName+",不能直接死亡状态");

    	}
    }
    public void ready(){//挂起的线程->进入就绪状态
    	if(state instanceof Blocked) {
        	((Blocked) state).ready(this);
    	} else {
    		System.out.println("当前状态已为"+state.stateName+",直接继续运行即可!");
    	}
    }
}

测试

public class Test {
	public static void main(String[] args) {
		ThreadContext context=new ThreadContext();
        context.start();
        context.getCPU();
        context.waits();
        context.ready();
        context.getCPU();
        context.dead();
//        context.start();
	}
}

java状态模式实例 java状态设计模式_状态模式模拟线程状态_04


java状态模式实例 java状态设计模式_状态模式模拟线程状态_05


java状态模式实例 java状态设计模式_状态模式_06


状态模式与命令模式
命令模式的接口中只有一个方法。
状态模式的接口中可以有多个方法。而且,状态模式的实现类的方法,一般返回值,或者是改变实例变量的值。也就是说,**状态模式一般和对象的状态有关。**对象的行为依赖于它的状态(属性),并且可以根据它的状态改变而改变它的相关行为。

以上仅为个人学习,如果错误望指出,谢谢。