"围观"设计模式(21)--行为型之状态模式(State Pattern)

状态模式--允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类。----百度百科


个人理解


状态模式应该说可以理解为某种状态下,程序的执行流程可能会发生变化,类似于交通灯,红灯的时候停下,绿灯行走,黄灯时等一等,这就是三种状态下我们人对其作出的相应的变化。再比如,公交车应该都坐过的,公交车停车的时候,可以上车和下车;公交车行驶的时候,不允许下车和上车,那么,这里公交车停车和行驶是两种状态,这两种状态对于后续人上车下车的行为产生了一定的影响。通俗点就是说,某种状态作为先决条件时,后面的行为受到了前面的这种状态的影响,这种情况比较适合运用状态模式。


案例解析

通用的模板

下面来看一个比较通用的模板


public class Context {

	// 定义状态
	public final static State STATE1 = new ConcreteState1();
	public final static State STATE2 = new ConcreteState2();
	
	// 当前状态
	private State currentState;

	public State getCurrentState() {
		return currentState;
	}

	// 设置当前状态
	public void setCurrentState(State currentState) {
		this.currentState = currentState;
		currentState.setContext(this);
	}
	
	// 行为委托
	public void behave1(){
		this.currentState.behave1();
	}
	
	public void behave2(){
		this.currentState.behave2();
	}
}
Context类:环境角色,定义客户端需要的接口,并且负责具体的状态的切换。


State类为抽象状态角色,定义对象的状态,并且封装环境角色以实现状态的切换。

public abstract class State {

	// 定义一个环境角色,提供子类访问
	protected Context context;
	// 设置环境角色
	public void setContext(Context context){
		this.context = context;
	}
	
	// 行为1
	public abstract void behave1();
	
	// 行为2
	public abstract void behave2();
}

抽象类的具体实现类,需要完成本状态的行为以及要切换到的状态的行为管理,也就是,本状态要做的事做完,然后跳转其要切换的状态。

public class ConcreteState1 extends State {

	@Override
	public void behave1() {
		System.out.println("状态1");
	}

	@Override
	public void behave2() {
		super.context.setCurrentState(Context.STATE2);
		super.context.behave2();
	}

	
}

红绿灯案例与状态模式


在具体的实现时与之前的部分有所不同,或许是案例的原因,基本的功能和原理是相符的。

State--抽象状态角色,定义好三个不同的交通灯的情况下,对应的动作。

public abstract class State {

	// 设置环境角色
	protected Context context;

	public void setContext(Context context) {
		this.context = context;
	}
	
	public abstract void pass();
	
	public abstract void stop();
	
	public abstract void waiting();
	
}

Context环境角色,定义调用者需要的接口,负责具体的状态的切换。

public class Context {

	public final static State REDLIGHT = new RedLight();
	public final static State GREENLIGHT = new GreenLight();
	public final static State YELLOWLIGHT = new YellowLight();
	
	// 当前状态
	private State currentState;

	public State getCurrentState() {
		return currentState;
	}

	public void setCurrentState(State currentState) {
		this.currentState = currentState;
		this.currentState.setContext(this);
	}
	
	public void pass() {
		this.currentState.pass();
	}
	
	public void stop() {
		this.currentState.stop();
	}
	
	public void waiting() {
		this.currentState.waiting();
	}
	
	
}

状态的具体实现类,完成本状态应有的行为,并且切换到相应的状态去。

public class RedLight extends State {

	@Override
	public void pass() {
		// 不允许通过
	}

	@Override
	public void stop() {
		System.out.println("红灯停止");
		try {
			waiting();
			new Thread().sleep(1000);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		super.context.setCurrentState(Context.GREENLIGHT);
		super.context.pass();
	}

	@Override
	public void waiting() {
		System.out.println("等待1s钟");
	}
	
	
}

测试类

public class WY {

	public static void main(String[] args) {
		Context context = new Context();
		// 红灯
		context.setCurrentState(new RedLight());
		context.stop();
		System.out.println("==================");
		
		// 绿灯
		context.setCurrentState(new GreenLight());
		context.pass();
		
		System.out.println("==================");
		// 黄灯
		context.setCurrentState(new YellowLight());
		context.waiting();
	}
}


状态模式优点


1. 结构清晰(和if..else以及switch相比)。

2. 遵循了开闭原则和单一职责原则。

3. 封装性好,状态的变化放在类的内部,外部不需要知道类内部如何实现状态和行为的变化。


状态模式的缺点


子类太多的话导致类膨胀,不便于管理和维护,在设计时需要考虑到这一点。


状态模式适用场景


1. 存在多种状态,行为受到状态的影响。

2. 条件、判断替代者


代码下载

设计模式实例源代码下载


推荐阅读

"围观"设计模式(16)--结构型之组合模式(Composite Pattern)

"围观"设计模式(17)--结构型之享元模式(Flyweight Pattern)

"围观"设计模式(18)--行为型之模板方法模式(TemplateMethod Pattern)

"围观"设计模式(19)--行为型之观察者模式(Observer Pattern)

"围观"设计模式(20)--行为型之策略模式(Strategy Pattern)


你可能感兴趣的:(设计模式,"围观"设计模式,设计模式,行为型设计模式,架构设计,状态模式,StatePattern)