设计模式之-----状态模式

今天继续学习状态模式,通俗来讲,就是每个不同的状态会有不同的行为,拿现实生活来说,一个普通的上班族,7点的状态是刚刚起床,9点的状态是刚上班,精力充沛,12点的状态是吃饭。。。等等。在每一个不同的状态中,会有对应的事情要取做,那么这个状态模式怎么写呢?首先我第一想到的就是if-else。那我们一天有24小时,我们岂不是要写24个if-else么?那实在太恐怖了,而且一旦有变动,代价可是十分大的,所以,我们引进了状态模式,虽然代码量没有减少,甚至增多了,但是却符合设计原则中的单一职责和开-闭原则。

我们还是看一看代码,深入的了解一下,为了直观一些,我们不用上边的例子,我们拿电风扇来说,电风扇在不同的档位有不同的转速,这也是状态模式的一种体现。我们就拿这个来做例子,代码部分有注释,我就不过多解释了。

老样子,先看包结构

先来写一个通用的状态接口,每一个状态都要完成的工作

package com.state.state.intf;

import com.state.context.Context;

/**
 * 状态接口,每一个状态都要实现的接口
 * @author ZHENGWEI
 * @date Jul 29, 2015
 */
public interface State {

	/**
	 * 当前状态的下一个状态
	 */
	public void nextState(Context con);
	
	/**
	 * 当前状态的上一个状态
	 */
	public void preState(Context con);
	
	/**
	 *  获取当前状态
	 */
	public void getCurState();
}

之后是Context类,也叫上下文类

package com.state.context;

import com.state.state.intf.State;

/**
 * 上下文类
 * @author ZHENGWEI
 * @date Jul 29, 2015
 */
public class Context {

	private State state;

	public State getState() {
		return state;
	}

	public void setState(State state) {
		this.state = state;
	}
	
	/**
	 * 当前状态的下一个状态
	 */
	public void next(){
		this.state.nextState(this);
		this.state.getCurState();
	}
	
	/**
	 * 当前状态的上一个状态
	 */
	public void pre(){
		this.state.preState(this);
		this.state.getCurState();
	}
}

我们在调整状态时,不去使用State接口里的方法,而是通过上下文类,让它自己决定去调用具体哪个实例的方法

之后就是每一个具体的状态的类,有3个,分别是1档,2档,关闭档

package com.state.state.impl;

import com.state.context.Context;
import com.state.state.intf.State;

public class OneState implements State {
	
	public void getCurState() {
		System.out.println("当前是1档");
	}

	public void nextState(Context con) {
		con.setState(new TwoState());
	}

	public void preState(Context con) {
		con.setState(new OffState());
	}

}

package com.state.state.impl;

import com.state.context.Context;
import com.state.state.intf.State;

public class TwoState implements State {

	public void getCurState() {
		System.out.println("当前是2档");
	}

	public void nextState(Context con) {
		con.setState(new OffState());
	}

	public void preState(Context con) {
		con.setState(new OneState());
	}

}

package com.state.state.impl;

import com.state.context.Context;
import com.state.state.intf.State;

public class OffState implements State {

	public void getCurState() {
		System.out.println("当前档位是关闭");
	}

	public void nextState(Context con) {
		con.setState(new OneState());
	}

	public void preState(Context con) {
		con.setState(new TwoState());
	}

}

在这里要注意,在实际应用中,这个具体的状态类应该是单例的,也就是说在一个JVM中,只存在这个类的一个实例对象,否则过多的状态转换会导致占用过多JVM资源。但是在这里我为了直观表达状态模式,就没有用单例,否则代码太乱的话会影响大家理解。

最后是测试类

package com.state.main;

import com.state.context.Context;
import com.state.state.impl.OneState;
import com.state.state.intf.State;

public class StateMain {

	public static void main(String[] args) {
		Context con = new Context();
		State oneSta = new OneState();
		con.setState(oneSta);
		for(int i = 0; i < 10; i++){
			con.next();
		}
	}

}

然后是结果


可以看到,如果我现在想加一个三档,只需要增加相关的类,别的地方只要微小的改动就可以了。





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值