最近学习到设计模式,现总结个人学习状态模式内容【重点在于根据它的状态改变而改变它的相关行为】。
文章目录
- 定义
- 优缺点
- 优点
- 缺点
- 实现
- 代码
- 测试
定义
对有状态的对象,把复杂的“判断逻辑”提取到不同的状态对象中,允许状态对象在其内部状态发生改变时改变其行为。
优缺点
优点
- 允许对象在内部状态发生改变时改变它的行为,对象看起来好像修改了它的类。
- 状态模式将与特定状态相关的行为局部化到一个状态中,并且将不同状态的行为分割开来,满足“单一职责原则”。
- 减少对象间的相互依赖。将不同的状态引入独立的对象中会使得状态转换变得更加明确,且减少对象间的相互依赖。
缺点
- 增加系统类和对象的个数。
- 状态模式的结构与实现都较为复杂,如果使用不当将导致程序结构和代码的混乱。
- 状态模式对"开闭原则"的支持并不太好,对于可以切换状态的状态模式,增加新的状态类需要修改那些负责状态转换的源代码(context),否则无法切换到新增状态,而且修改某个状态类的行为也需修改对应类的源代码
实现
模拟线程:
状态模式模拟线程流程
类图:
环境类(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();
}
}
状态模式与命令模式
命令模式的接口中只有一个方法。
状态模式的接口中可以有多个方法。而且,状态模式的实现类的方法,一般返回值,或者是改变实例变量的值。也就是说,**状态模式一般和对象的状态有关。**对象的行为依赖于它的状态(属性),并且可以根据它的状态改变而改变它的相关行为。
以上仅为个人学习,如果错误望指出,谢谢。