第十五篇:状态模式

什么是状态呢?这个非常好理解,就比如我们经常听到的一句广告词 “不在状态怎么办?脉动回来!!!”  , 那么这就是状态的体现啦,这里的状态指的是你的精神,你的精神非常好,可能会赶紧看书工作,稍微差点,可能得眯眼休息下,差到完全处于懵逼状态,那你可能得选择好好休息睡个觉什么的了; 

所以你的精神状态决定了你接下来的行为,用代码来表示的话,状态就是一个变量,而变量的变化,直接影响程序的走向...

今天我们就来举一个关于状态的例子, 举个通俗易懂的吧, 拿天气来举例 !

/**准备做某事的类,什么样的天气决定你将要去做某事*/
class PrepareDoSth{
	//天气情况
	private String weather;
	public PrepareDoSth( String weather) {
		this.weather = weather;
	}
	
	public String getWeather() {return weather;}
	public void setWeather(String weather) {this.weather = weather;}
	
	//做某事
	public void doSth(){
		if( "晴朗".equals(weather) || "多云".equals(weather) ){
			System.out.println("与心爱的女神野外约起!");
		}else if("小雨".equals(weather)){
			System.out.println("蒙蒙细雨,独自外出雨中漫步思考人生...");
		}else if("倾盆大雨".equals(weather) || "雷阵雨".equals(weather)){
			System.out.println("躲在家中追美剧");
		}else if("大太阳".equals(weather)){
			System.out.println("躲在家中空调WIFI西瓜");
		}else if("大冰雹".equals(weather)){
			System.out.println("站在阳台看美丽的冰雹");
		}else if("下雪".equals(weather)){
			System.out.println("出去堆堆雪人");
		}else if("暴风雪".equals(weather)){
			System.out.println("躲在家中烤火...");
		}
	}
}
public class Test {
	public static void main(String[] args) {
		PrepareDoSth pds = new PrepareDoSth("小雨");
		pds.doSth();
	}
}

上面的代码很简单,没什么好说的,但我们观察doSth方法,它根据天气这个状态进行大量的if...else...if...判断来决定程序的走向 ,如果说哪天程序需要添加新的功能,再加上阴天,大风天...等等乱七八糟的天气,或者哪天程序需求变了,你分手了,哪怕是晴朗的天气也无法去约女神只能一个人守着电脑看苍老师了...这些时候你又得对既有代码进行改动,我们的设计原则有一条就是开放闭合原则,对扩展开放对修改关闭,  如果你想要消除这种大量的判断语句,想要在不影响其它功能的情况下,修改某一个功能或者增加新的行为, 就可以使用状态模式了  (当然,如果只是简单的判断,完全没必要使用状态模式!)

接下来我们采用状态模式修改上面的代码,状态模式就是用一个个的状态类来代表某个状态变量的不同值!

/**准备做某事的类,什么样的天气决定你将要去做某事*/
class PrepareDoSth{
	//天气情况
	private String weather;
	//增加天气状态类,有一个默认类
	private WeatherState ws = new DefaultState();
	public PrepareDoSth( String weather) {
		this.weather = weather;
	}
	
	public String getWeather() {return weather;}
	public void setWeather(String weather) {this.weather = weather;}
	
	//做某事,交给状态对象去做!
	public void doSth(){
		ws.doSth(weather);
	}
}

//状态抽象类
abstract class WeatherState{
	protected abstract void doSth( String weather );
	//取得下一个状态
	protected abstract WeatherState nextState();
	 
}

class DefaultState extends WeatherState{
	@Override
	protected void doSth(String weather) {
		//什么也不做,直接交给下一个状态对象去做
		if( this.nextState()!=null){
			nextState().doSth(weather);
		}
	}
	//返回该状态后的下一个状态
	@Override
	protected WeatherState nextState() {
		return new QingLangState();
	}
	
}
class QingLangState extends WeatherState{
	@Override
	public void doSth( String weather ){
		//如果不是我想要的状态,我直接交给下一个状态对象去做
		if( "晴朗".equals(weather) ){
			System.out.println("与心爱的女神野外约起!");
		}else{
			if( this.nextState()!=null){
				nextState().doSth(weather);
			}
		}
	}
	@Override
	protected WeatherState nextState() {
		return new XiaoYuState();
	}
}
class XiaoYuState extends WeatherState{
	@Override
	public void doSth( String weather ){
		if( "小雨".equals(weather) ){
			System.out.println("蒙蒙细雨,独自外出雨中漫步思考人生...");
		}else{
			if( this.nextState()!=null){
				nextState().doSth(weather);
			}
		}
	}
	@Override
	protected WeatherState nextState() {
		return new LeiZhenYuState();
	}
}
class LeiZhenYuState extends WeatherState{
	@Override
	public void doSth( String weather ){
		if( "雷阵雨".equals(weather) ){
			System.out.println("躲在家中追美剧");
		}else{
			if( this.nextState()!=null){
				nextState().doSth(weather);
			}
		}
	}

	@Override
	protected WeatherState nextState() {
		return new DaTaiYangState();
	}
}
class DaTaiYangState extends WeatherState{
	@Override
	public void doSth( String weather ){
		if( "大太阳".equals(weather) ){
			System.out.println("躲在家中空调WIFI西瓜");
		}else{
			if( this.nextState()!=null){
				nextState().doSth(weather);
			}
		}
	}
	@Override
	protected WeatherState nextState() {
		return new DaBingBaoState();
	}
}
class DaBingBaoState extends WeatherState{
	@Override
	public void doSth( String weather ){
		if( "大冰雹".equals(weather) ){
			System.out.println("站在阳台看美丽的冰雹");
		}else{
			if( this.nextState()!=null){
				nextState().doSth(weather);
			}
		}
	}
	@Override
	protected WeatherState nextState() {
		return new XiaXueState();
	}
}
class XiaXueState extends WeatherState{
	@Override
	public void doSth( String weather ){
		if( "下雪".equals(weather) ){
			System.out.println("出去堆堆雪人");
		}else{
			if( this.nextState()!=null){
				nextState().doSth(weather);
			}
		}
	}

	@Override
	protected WeatherState nextState() {
		return new BaoFengXueState();
	}
}
class BaoFengXueState extends WeatherState{
	@Override
	public void doSth( String weather ){
		if( "暴风雪".equals(weather) ){
			System.out.println("躲在家中烤火...");
		}else{
			if( this.nextState()!=null){
				nextState().doSth(weather);
			}
		}
	}
	@Override
	protected WeatherState nextState() {
		return null;
	}
}


测试一下:

public class Test {
	public static void main(String[] args) {
		PrepareDoSth pds = new PrepareDoSth("暴风雪");
		pds.doSth();
		pds.setWeather("小雨");
		pds.doSth();
		pds.setWeather("晴朗");
		pds.doSth();
	}
}


输出*****************************************************

躲在家中烤火...
蒙蒙细雨,独自外出雨中漫步思考人生...
与心爱的女神野外约起!

**********************************************************

我们来看一下改写后的程序,没错,代码量变多了!但是扩展性更好了,后续增加新的功能只需要增加新的状态类就可以了, 我们观察下状态类,发现它们都持有下一个状态的引用,它们若是自己对某个变量的当前状态不感兴趣,则会交给下一个状态去处理,以此类推...


那么到底该不该用状态模式呢?我认为这取决于你程序的复杂度,这里只是一个很简单的例子,如果你的程序足够复杂,程序运行依赖某个状态变量的变化,且判断非常之多且代码需求多变的话,还是可以考虑使用状态模式的,只不过会增加代码量,但好处就是将来要做修改可以起到更小的现有代码侵入性;


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值