什么是状态呢?这个非常好理解,就比如我们经常听到的一句广告词 “不在状态怎么办?脉动回来!!!” , 那么这就是状态的体现啦,这里的状态指的是你的精神,你的精神非常好,可能会赶紧看书工作,稍微差点,可能得眯眼休息下,差到完全处于懵逼状态,那你可能得选择好好休息睡个觉什么的了;
所以你的精神状态决定了你接下来的行为,用代码来表示的话,状态就是一个变量,而变量的变化,直接影响程序的走向...
今天我们就来举一个关于状态的例子, 举个通俗易懂的吧, 拿天气来举例 !
/**准备做某事的类,什么样的天气决定你将要去做某事*/
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();
}
}
躲在家中烤火...
蒙蒙细雨,独自外出雨中漫步思考人生...
与心爱的女神野外约起!
**********************************************************
我们来看一下改写后的程序,没错,代码量变多了!但是扩展性更好了,后续增加新的功能只需要增加新的状态类就可以了, 我们观察下状态类,发现它们都持有下一个状态的引用,它们若是自己对某个变量的当前状态不感兴趣,则会交给下一个状态去处理,以此类推...
那么到底该不该用状态模式呢?我认为这取决于你程序的复杂度,这里只是一个很简单的例子,如果你的程序足够复杂,程序运行依赖某个状态变量的变化,且判断非常之多且代码需求多变的话,还是可以考虑使用状态模式的,只不过会增加代码量,但好处就是将来要做修改可以起到更小的现有代码侵入性;