java状态模式

 状态模式,又称状态对象模式(Pattern of Objects for States),状态模式是对象的行为模式。

  状态模式允许一个对象在其内部状态改变的时候改变其行为。这个对象看上去就像是改变了它的类一样。


状态模式的结构

  用一句话来表述,状态模式把所研究的对象的行为包装在不同的状态对象里,每一个状态对象都属于一个抽象状态类的一个子类。状态模式的意图是让一个对象在其内部状态改变的时候,其行为也随之改变。状态模式的示意性类图如下所示:

                                                                                                                  

  状态模式所涉及到的角色有:

  ●  环境(Context)角色,也成上下文:定义客户端所感兴趣的接口,并且保留一个具体状态类的实例。这个具体状态类的实例给出此环境对象的现有状态。

  ●  抽象状态(State)角色:定义一个接口,用以封装环境(Context)对象的一个特定的状态所对应的行为。

  ●  具体状态(ConcreteState)角色:每一个具体状态类都实现了环境(Context)的一个状态所对应的行为。

   我们知道java是面向对象的设计语言,而面向对象就是希望做到代码的责任分解,在《重构》一书中,我记得有这么一句话,如果一个方法太长了,可能就会有坏味道,什么叫做坏味道呢?代码过长,可能意味着你的这段代码责任重大,责任太过繁重,不利于复用,修改,不够灵活,容易出错。这个时候状态设计模式就出现了,对于一个状态的表达式过于复杂的时候,把状态判断的逻辑转移到表示不同状态的一系列类当中,可以把复杂的判断逻辑简化。

这里以我自己为例:大概是星期天的活动安排吧,首先用普通的面向对象

public class sunday {

	// 一天的时间
	int time;
	// 上午是否及时起床
	boolean isup = false;

	public sunday() {

	}

	public void todaydo() {

		if (time <= 12) {

			if (isup) {

				System.out.println("上午一直在睡大觉!");

			} else {

				if (time <= 10) {

					System.out.println("吃早餐,去玩耍,买菜做饭!");

				} else if (time <= 11) {

					System.out.println("吃早餐,买菜做饭!");

				} else if (time <= 12) {

					System.out.println("买菜做饭!");

				}

			}

		} else {

			System.out.println("逛超市!");

		}

	}

}

我们可以看到复杂的逻辑判断,现在我要下午先睡会觉,再去超市

public class sunday {

	// 一天的时间
	int time;
	// 上午是否及时起床
	boolean isup = false;

	public sunday() {

	}

	public void todaydo() {

		if (time <= 12) {

			if (isup) {

				System.out.println("上午一直在睡大觉!");

			} else {

				if (time <= 10) {

					System.out.println("吃早餐,去玩耍,买菜做饭!");

				} else if (time <= 11) {

					System.out.println("吃早餐,买菜做饭!");

				} else if (time <= 12) {

					System.out.println("买菜做饭!");

				}

			}

		} else {
             if(time<15){
			
                System.out.println("吃过午饭休息一会!");
			
             }else{
            	 
     			System.out.println("逛超市!");
             }
		}

	}

}

这里对类做了修改,可以看出来逻辑会越来越复杂,显然这不是一个好的现象

现在用状态设计模式

抽象状态接口 

public interface state {

	void handle(stateSunday t);
}

环境角色 星期天

public class stateSunday {

	//具体状态类
	state state;
	// 明天得时间
	int time;

	// 是否能及时起床
	boolean isup;

	public stateSunday(state state) {

		this.state = state;
	}

	public int getTime() {
		return time;
	}

	public void setTime(int time) {
		this.time = time;
	}

	public boolean isIsup() {
		return isup;
	}

	public void setIsup(boolean isup) {
		this.isup = isup;
	}

	//处理
	public void  request() {

		state.handle(this);

	}

}

状态的入口类

public class noonstate implements state {

	public noonstate() {

	}

	@Override
	public void handle(stateSunday t) {

		if (t.time <= 12) {
			// 判断是否及时起床
			if (t.isup) {

				new noonone().handle(t);

			} else {

				new sleep().handle(t);
			}

		} else {

			new afternoon().handle(t);

		}
	}

}
状态一 二 三 等等:

public class noonone implements state {

	public noonone() {
		// TODO Auto-generated constructor stub
	}

	@Override
	public void handle(stateSunday t) {

		if (t.time <= 10) {

			System.out.println("当前时间:"+t.time+"点,"+"出去吃个美美的早餐,然后去玩耍,买菜做饭!");

		} else {


			new noonTwo().handle(t);

		}

	}

}

public class noonTwo implements state {

	public noonTwo() {
		// TODO Auto-generated constructor stub
	}

	@Override
	public void handle(stateSunday t) {
		
		if (t.time <= 11 ) {

			System.out.println("当前时间:"+t.time+"点,"+"时间有点紧,出去吃早餐,然后买菜回来做饭!");

		}else{
			
			new noonThree().handle(t);
		}
		

	}

}

public class noonThree implements state {

	public noonThree() {
		// TODO Auto-generated constructor stub
	}

	@Override
	public void handle(stateSunday t) {
		
		if ( t.time <=12) {

			System.out.println("当前时间:"+t.time+"点,"+"太晚了,早饭不吃了出去买菜回来做饭!");

		}
	

	}

}

public class sleep implements state {

	public sleep() {
		// TODO Auto-generated constructor stub
	}

	@Override
	public void handle(stateSunday t) {
		
		if(t.time<=12){
			
		System.out.println("当前时间:"+t.time+"点,"+"一直睡大觉!");

		}
	}

}

public class afternoon implements state {

	public afternoon() {
		// TODO Auto-generated constructor stub
	}

	@Override
	public void handle(stateSunday t) {
	
		System.out.println("当前时间:"+t.time+"点,"+"逛超市!");

	}

}

客户端测试:

	public static void main(String[] args) {
		
		state s=new noonstate();
		stateSunday  t=new  stateSunday(s);
        t.isup=true;
        t.time=9;
        t.request();
        t.time=11;
        t.request();
        t.time=12;
        t.request();
        t.time=13;
        t.request();
	}

结果:

当前时间:9点,出去吃个美美的早餐,然后去玩耍,买菜做饭!
当前时间:11点,时间有点紧,出去吃早餐,然后买菜回来做饭!
当前时间:12点,太晚了,早饭不吃了出去买菜回来做饭!
当前时间:13点,逛超市!

现在也修改为下午要休息到15点钟之后在去逛超市:

public class afternoon implements state {

	public afternoon() {
		// TODO Auto-generated constructor stub
	}

	@Override
	public void handle(stateSunday t) {
	
		if(t.time<=15){
			
			System.out.println("当前时间:"+t.time+"点,"+"休息一会!");
	
		}else{
			
			System.out.println("当前时间:"+t.time+"点,"+"逛超市!");
		}
		


	}

}
从代码看,我们只需要修改一个类的一个逻辑,不会产生更复杂的逻辑,如果复杂的话还可以再分出去一个类,逻辑简单。

认识状态模式

  ●  状态和行为

  所谓对象的状态,通常指的就是对象实例的属性的值;而行为指的就是对象的功能,再具体点说,行为大多可以对应到方法上。

  状态模式的功能就是分离状态的行为,通过维护状态的变化,来调用不同状态对应的不同功能。也就是说,状态和行为是相关联的,它们的关系可以描述为:状态决定行为

  由于状态是在运行期被改变的,因此行为也会在运行期根据状态的改变而改变。

  ●  行为的平行性

  注意平行线而不是平等性。所谓平行性指的是各个状态的行为所处的层次是一样的,相互独立的、没有关联的,是根据不同的状态来决定到底走平行线的哪一条。行为是不同的,当然对应的实现也是不同的,相互之间是不可替换的。

                                                          

  而平等性强调的是可替换性,大家是同一行为的不同描述或实现,因此在同一个行为发生的时候,可以根据条件挑选任意一个实现来进行相应的处理。

                                                              

  大家可能会发现状态模式的结构和策略模式的结构完全一样,但是,它们的目的、实现、本质却是完全不一样的。还有行为之间的特性也是状态模式和策略模式一个很重要的区别,状态模式的行为是平行性的,不可相互替换的;而策略模式的行为是平等性的,是可以相互替换的。

  ●   环境和状态处理对象

  在状态模式中,环境(Context)是持有状态的对象,但是环境(Context)自身并不处理跟状态相关的行为,而是把处理状态的功能委托给了状态对应的状态处理类来处理。

  在具体的状态处理类中经常需要获取环境(Context)自身的数据,甚至在必要的时候会回调环境(Context)的方法,因此,通常将环境(Context)自身当作一个参数传递给具体的状态处理类。

  客户端一般只和环境(Context)交互。客户端可以用状态对象来配置一个环境(Context),一旦配置完毕,就不再需要和状态对象打交道了。客户端通常不负责运行期间状态的维护,也不负责决定后续到底使用哪一个具体的状态处理对象。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值