状态模式

1. 概念

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

看不懂没关系,看个例子就明白了

2. 一个例子

进程有就绪,运行,停止三个状态(简单起见只说这三个),其状态可以不断从一种转换到另一种,模拟这种情况

2.1 不用设计模式

对于上面的问题,最容易想到的就是在进程类中维护一个状态变量,通过改变这个变量改变状态,并通过对状态变量的判断,执行相对应状态下的操作

class Process{
	public static final int READY = 1;
	public static final int RUNNING = 2;
	public static final int STOP = 3;
	private int state;//状态
	
	public void start(){
		if(state == READY ){
			state = RUNNING;
			System.out.println("RUNNING")
		}else{
			//invalid
		}
	}
	public void stop(){
		if(state == RUNNING){
			state = STOP;
			System.out.println("STOP")
		}else{
			//invalid
		}
	}
	public void newProcess(){
		if(state == STOP){
			state = READY ;
			System.out.println("READY ")
		}else{
			//invalid
		}
	}
}

可以看到这样的实现方法,每个操作都有庞大的分支判断结构,这些分支决定于对象的状态

2.2 使用状态模式改进

如果把进程的状态和当前状态下对应的操作封装到一个类中,再让进程持有这样的状态类,那么就能避免大量的判断,因为每个状态类只操作当前状态下的操作
在这里插入图片描述
就像上面所说的,我们在State的抽象类中把所有的操作都设置为默认非法的,然后再具体的状态去重新当前状态下的操作
状态

abstract class State{
	public void newProcess(Process process){
		//invalid
	}
	public void start(Process process){
		//invalid
	}
	public void stop(Process process){
		//invalid
	}
}

class Stop extends State{
	public void newProcess(Process process){
		//newProcess
		process.setState(new Ready())
	}
}

class Ready extends State{
	public void start(Process process){
		//Ready
		process.setState(new Start())
	}
}

class Runnable extends State{
	public void stop(Process process){
		//Stop
		process.setState(new Stop())
	}
}

Process

class Process{
	private State state;
	public void setState(State state){
		this.state = state;
	}
	public void stop(Process process){
		state.stop(this);
	}
	public void start(Process process){
		state.start(this);
	}
	public void newProcess(Process process){
		state.newProcess(this);
	}
}

2.3 引入享元模式

实际上上面的代码有点问题,那就是每次都要创建新的状态对象,这时需要引入享元模式,将这些具体状态对象放在集合中供程序共享
Process

class Process{ 
	Map<Integer, State> map = new HashMap();
	private State state;
	public Process(){
		State ready= new Ready();
		map.put(1,ready);
		State Runnable= new Runnable();
		map.put(2,runnable);
		State Stop= new Stop();
		map.put(3,stop)
		
	}
	public void setState(State state){
		this.state = state;
	}
	public void getState(int key){
		state = map.get(key);
	}
	public void stop(Process process){
		state.stop(this);
	}
	public void start(Process process){
		state.start(this);
	}
	public void newProcess(Process process){
		state.newProcess(this);
	}
}

状态

abstract class State{
	public void newProcess(Process process){
		//invalid
	}
	public void start(Process process){
		//invalid
	}
	public void stop(Process process){
		//invalid
	}
}

class Stop extends State{
	public void newProcess(Process process){
		//newProcess
		process.setState(process.getState(1))
	}
}

class Ready extends State{
	public void start(Process process){
		//Ready
		process.setState(process.getState(2))
	}
}

class Runnable extends State{
	public void stop(Process process){
		//Stop
		process.setState(process.getState(3))
	}
}

3. 再看概念

状态模式把受环境改变的对象行为包装在不同的状态对象里,其意图是让一个对象在其内部状态改变的时候,其行为也随之改变
在这里插入图片描述

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

状态模式是一种对象行为型模式,其主要优点如下:

  • 状态模式将与特定状态相关的行为局部化到一个状态中,并且将不同状态的行为分割开来,满足“单一职责原则”
  • 减少对象间的相互依赖。将不同的状态引入独立的对象中会使得状态转换变得更加明确,且减少对象间的相互依赖
  • 有利于程序的扩展。通过定义新的子类很容易地增加新的状态和转换

状态模式的主要缺点如下:

  • 状态模式的使用必然会增加系统的类与对象的个数
  • 状态模式的结构与实现都较为复杂,如果使用不当会导致程序结构和代码的混乱
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值