Java设计模式(二十)---状态模式

x33g5p2x  于2021-03-13 发布在 Java  
字(4.9k)|赞(0)|评价(0)|浏览(165)

定义:当一个对象内在状态改变时允许其改变行为,这个对象看起来像改变了其类。

一般模式

state:抽象状态角色
---|接口或抽象类,负责对象状态定义,并且封装环境角色以实现状态切换。
ConcreteState:具体状态角色
---|每一个具体状态必须完成两个职责,本状态的行为管理以及去想状态处理,通俗的说,就是本状态下要做的事情,
以及本状态如何过渡到其他状态。
Context环境角色
---|定义客户端需要的接口,并且负责具体状态的切换。

状态类是通过context(环境角色)来实现装之间的转换的。

public class StateTest {
	public static void main(String[] args) {
		//提供一个环境角色
		Context context = new Context();
		//想让执行状态1的handle1方法
		context.setCurrentState(new ConcreteState1());
		//执行handle2方法
		context.handle2();
	}
}
/**
 * 抽象状态角色:
 * 封装环境角色,实现状态的切换
 * @author Administrator
 */
abstract class State{
	//提供一个环境角色,共子类访问
	protected Context context;

	public void setContext(Context context) {
		this.context = context;
	}
	//抽像的行为1角色
	public abstract void handle1();
	//抽像的行为2角色
	public abstract void handle2();
}
/**
 * 负责具体状态的切换
 * @author Administrator
 *
 */
class Context{
	//里面封装了所有的状态方法
	protected final static ConcreteState1 state1 = new ConcreteState1();
	protected final static ConcreteState2 state2 = new ConcreteState2();
	//设置当前状态
	private State currentState;
	
	public State getCurrentState() {
		return currentState;
	}
	public void setCurrentState(State currentState) {
		this.currentState = currentState;
		//设置环境角色
		this.currentState.setContext(this);
	}
	//提供handle1方法
	public void handle1(){
		this.currentState.handle1();
	}
	//提供handle2方法
	public void handle2(){
		this.currentState.handle2();
	}
}
/**
 * 具体状态类的实现类,
 * 主要抽象方法的具体实现方式。
 * @author Administrator
 */
class ConcreteState1 extends State{

	@Override
	public void handle1() {
		System.out.println("我是实现类1,的具体实现方法1...");
	}
	@Override
	public void handle2() {
		System.out.println("我是实现类1,的具体实现方法2...");
		//切换到ConcreteState2类的handle2方法,这里就相当于是状态的切换
		super.context.setCurrentState(Context.state2);
		super.context.handle2();
	}
}
/**
 * 具体状态类的实现类,
 * 主要抽象方法的具体实现方式。
 * @author Administrator
 */
class ConcreteState2 extends State{

	@Override
	public void handle1() {
		System.out.println("我是实现类2,的具体实现方法1...");
		super.context.setCurrentState(Context.state1);
		super.context.handle1();
	}
	@Override
	public void handle2() {
		System.out.println("我是实现类2,的具体实现方法2...");
	}
}

一个例子:

 一个电梯他有4中状态,打开,运行,停止,关闭。他们之间存在着紧密的状态切换关系。例如:
 人乘坐电梯,打开-->关闭--->运行--->停止。关闭电梯时,可能存在运行和停止。我们通过程序
 来模拟这里的状态之间的转换。

public class StateT {
	public static void main(String[] args) {
		//提供一个环境角色
		LiftContext context = new LiftContext();
		//设置环境角色,为打开状态
		context.setCurrentLift(new Closeing());
		context.close();
		context.run();
		context.stop();
	}
}
/**
 * 抽象的装填类角色
 * 定义抽像的方法,封装角色。
 * @author Administrator
 */
abstract class ILift{
	//定义一个环境角色,共子类调用
	protected LiftContext context;
	
	public LiftContext getContext(){
		return this.context;
	}
	public void setContext(LiftContext context) {
		this.context = context;
	}
	//电梯的打开状态
	public abstract void open();
	//电梯的打开关闭
	public abstract void close();
	//电梯的打开运行
	public abstract void run();
	//电梯的打开停止
	public abstract void stop();
}
/**
 * 抽象状态类的实现类
 * @author Administrator
 */
class Openning extends ILift{

	@Override
	public void open() {
		System.out.println("---电梯打开,请上去...或下去");
	}

	@Override
	public void close() {
		//状态转换
		super.context.setCurrentLift(LiftContext.CLOSE);
		//委托给关闭状态的类来执行
		super.context.close();
	}

	@Override
	public void run() {
		System.out.println("打开状态--不能运行..");
	}

	@Override
	public void stop() {
		System.out.println("打开状态--已经停止");
	}
}
/**
 * 抽象状态类的实现类
 * @author Administrator
 */
class Closeing extends ILift{

	@Override
	public void open() {
		//切换为打开状态
		super.context.setCurrentLift(LiftContext.OPEN);
		super.getContext().open();
	}

	@Override
	public void close() {
		System.out.println("电梯门关闭..");
	}

	@Override
	public void run() {
		super.context.setCurrentLift(LiftContext.RUN);
		super.getContext().run();
	}

	@Override
	public void stop() {
	}
}

/**
 * 抽象状态类的实现类
 * @author Administrator
 */
class Running extends ILift{

	@Override
	public void open() {
		System.out.println("运行中--电梯不能打开..");
	}

	@Override
	public void close() {
		System.out.println("运行中--电梯已关闭..");
	}

	@Override
	public void run() {
		System.out.println("---电梯正在运行...");
	}

	@Override
	public void stop() {
		//运行状态--->停止状态
		super.context.setCurrentLift(LiftContext.STOP);
		super.getContext().stop();
	}
}

/**
 * 抽象状态类的实现类
 * @author Administrator
 */
class Stoping extends ILift{

	@Override
	public void open() {
		//停止之后-->打开电梯门
		super.context.setCurrentLift(LiftContext.OPEN);
		super.getContext().open();
	}

	@Override
	public void close() {
		System.out.println("停止状态--电梯还是关闭的..");
	}

	@Override
	public void run() {
		System.out.println("停止状态--电梯没有运行..");
	}

	@Override
	public void stop() {
		System.out.println("--电梯停止了..");
	}
}

/**
 * 环境角色,
 * 用于转换他们之间的状态
 * @author Administrator
 */
class LiftContext{
	//封装四种状态类
	protected static final Openning OPEN = new Openning();
	protected static final Closeing CLOSE = new Closeing();
	protected static final Running RUN = new Running();
	protected static final Stoping STOP = new Stoping();
	//提供一个状态类
	private ILift currentLift;
	
	public ILift getCurrentLift() {
		return currentLift;
	}
	public void setCurrentLift(ILift currentLift) {
		this.currentLift = currentLift;
		//设置环境角色
		this.currentLift.setContext(this);
	}
	//提供四种状态类的方法
	public void open() {
		this.currentLift.open();
	}
	//提供四种状态类的方法
	public void close() {
		this.currentLift.close();
	}
	//提供四种状态类的方法
	public void run() {
		this.currentLift.run();
	}
	//提供四种状态类的方法
	public void stop() {
		this.currentLift.stop();
	}
}

状态模式的优点:
---|结构清晰
---|遵循设计原则
---|封装性非常好
状态模式的缺点:
---|环境角色中封装的角色子类太多。 不好管理。
状态模式的使用场景
---|行为随状态改变而改变的场景
---|条件、分支判断语句的替代者。

相关文章