第十五篇:状态模式

来源:互联网 发布:做数据分析用什么软件 编辑:程序博客网 时间:2024/05/16 01:26

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

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

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

/**准备做某事的类,什么样的天气决定你将要去做某事*/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{@Overrideprotected void doSth(String weather) {//什么也不做,直接交给下一个状态对象去做if( this.nextState()!=null){nextState().doSth(weather);}}//返回该状态后的下一个状态@Overrideprotected WeatherState nextState() {return new QingLangState();}}class QingLangState extends WeatherState{@Overridepublic void doSth( String weather ){//如果不是我想要的状态,我直接交给下一个状态对象去做if( "晴朗".equals(weather) ){System.out.println("与心爱的女神野外约起!");}else{if( this.nextState()!=null){nextState().doSth(weather);}}}@Overrideprotected WeatherState nextState() {return new XiaoYuState();}}class XiaoYuState extends WeatherState{@Overridepublic void doSth( String weather ){if( "小雨".equals(weather) ){System.out.println("蒙蒙细雨,独自外出雨中漫步思考人生...");}else{if( this.nextState()!=null){nextState().doSth(weather);}}}@Overrideprotected WeatherState nextState() {return new LeiZhenYuState();}}class LeiZhenYuState extends WeatherState{@Overridepublic void doSth( String weather ){if( "雷阵雨".equals(weather) ){System.out.println("躲在家中追美剧");}else{if( this.nextState()!=null){nextState().doSth(weather);}}}@Overrideprotected WeatherState nextState() {return new DaTaiYangState();}}class DaTaiYangState extends WeatherState{@Overridepublic void doSth( String weather ){if( "大太阳".equals(weather) ){System.out.println("躲在家中空调WIFI西瓜");}else{if( this.nextState()!=null){nextState().doSth(weather);}}}@Overrideprotected WeatherState nextState() {return new DaBingBaoState();}}class DaBingBaoState extends WeatherState{@Overridepublic void doSth( String weather ){if( "大冰雹".equals(weather) ){System.out.println("站在阳台看美丽的冰雹");}else{if( this.nextState()!=null){nextState().doSth(weather);}}}@Overrideprotected WeatherState nextState() {return new XiaXueState();}}class XiaXueState extends WeatherState{@Overridepublic void doSth( String weather ){if( "下雪".equals(weather) ){System.out.println("出去堆堆雪人");}else{if( this.nextState()!=null){nextState().doSth(weather);}}}@Overrideprotected WeatherState nextState() {return new BaoFengXueState();}}class BaoFengXueState extends WeatherState{@Overridepublic void doSth( String weather ){if( "暴风雪".equals(weather) ){System.out.println("躲在家中烤火...");}else{if( this.nextState()!=null){nextState().doSth(weather);}}}@Overrideprotected 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();}}


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

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

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

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


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


0 0
原创粉丝点击