设计模式_状态模式(23)

28 篇文章 0 订阅
25 篇文章 0 订阅
  • 什么是状态模式
  • 状态模式的例子
  • 状态模式的优缺点
  • 状态模式的使用场景
  • 闲言碎语

什么是状态模式

   在现实生活我们在不同的时候点会做不同的事情.也会有不同的状态.当然,编程的是世界中我们也会在不同的时间可能有不同的状态,不同的处理,这时我们就要用到状态模式了.她的目的就是:允许对象在内部状态发生改变时改变它的行为,对象看起来好像修改了它的类。

  UML:


状态模式的例子

状态模式的接口

package com.designPattern.state;

/**
 * 状态模式的接口
 * 
 * @author Jason
 *
 */
public interface State {
	// 每个状态需要完成任务的接口
	public void doAction(Context time);
}

抽象层(可有可无)

package com.designPattern.state;

/**
 * 状态的抽象实现
 * 
 * @author jason
 *
 */
public abstract class AbstractState implements State {

	// 任务的默认实现
	@Override
	public void doAction(Context time) {

	}
}

三个具体的状态(早上,中午,晚上)

package com.designPattern.state;

/**
 * 早上的状态
 * 
 * @author jason
 *
 */
public class MorningState extends AbstractState {
	public static int MIN_TIME = 0;
	public static int MAX_TIME = 10;

	@Override
	public void doAction(Context time) {// 早上做的的事情
		if (time.getTime() < MIN_TIME) {
			System.out.println("请输入正确的时间!");
			return;
		}
		if (MIN_TIME <= time.getTime() && MAX_TIME > time.getTime()) {
			System.out.println("这是早上!");
		} else {
			time.setState(new AfternoonState());
			time.doThing();
		}
	}

}


 package com.designPattern.state;

/**
 * 下午的状态
 * 
 * @author jason
 *
 */
public class AfternoonState extends AbstractState {
    public static int MIN_TIME = 10;
    public static int MAX_TIME = 14;

    @Override // 下午应该做的事情
    public void doAction(Context time) {
        if (MIN_TIME > time.getTime()) {
            time.setState(new MorningState());
            time.doThing();
        }
        if (MIN_TIME <= time.getTime() && MAX_TIME > time.getTime()) {
            System.out.println("这是中午!");
        }
        if (MAX_TIME < time.getTime()) {
            time.setState(new EveningState());
            time.doThing();
        }
    }
}


package com.designPattern.state;

/**
 * 晚上的状态
 * 
 * @author jason
 *
 */
public class EveningState extends AbstractState {
    public static int MIN_TIME = 14;
    public static int MAX_TIME = 24;

    @Override // 晚上做的事情
    public void doAction(Context time) {
        if (MIN_TIME > time.getTime()) {
            time.setState(new AfternoonState());
            time.doThing();
        }
        if (MIN_TIME <= time.getTime() && MAX_TIME > time.getTime()) {
            System.out.println("这是晚上!");
        }
        if (time.getTime() > MAX_TIME) {
            System.out.println("输入的时间有误");
        }
    }
}


端口类(对状态进行维护)

package com.designPattern.state;

/**
 * 状态管理的容器
 * 
 * @author jason
 *
 */
public class Context {
	public State state;
	public int time;

	public Context(int time) {
		super();
		this.state = new MorningState();// 默认为早上状态
		this.time = time;
	}

	public void doThing() {
		state.doAction(this);
	}

	public State getState() {
		return state;
	}

	public void setState(State state) {
		this.state = state;
	}

	public int getTime() {
		return time;
	}

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

}

测试类

package com.designPattern.state;

import org.junit.Test;

/**
 * 状态模式的测试类
 * 
 * @author jason
 *
 */
public class TestCase {
	@Test
	public void test() {
		Context context = new Context(7);
		context.doThing();
		context.setTime(15);
		context.doThing();
		context.setTime(17);
		context.doThing();
		context.setTime(7);
		context.doThing();
	}
}

状态模式的优缺点

 优点

   在不同状态需要有不同响应的使用场景下,避免了使用if/else导致代码臃肿,使代码结构清晰的同时保证了拓展性和维护性。

 缺点

   增加了类的个数,让代码感觉有点混乱,但易于维护.

状态模式的使用场景

  (1)对象的行为依赖于它的状态,并且可以在运行时根据状态改变行为。

  (2)代码中包含大量与对象状态有关的if/else语句,这些条件对应于对象的各种状态,这些冗余条件语句的出现导致代码的可维护性和灵活性变差,这种情况适合使用状态模式进行优化。


闲言碎语

   从代码可以看出,为了保证状态的转换,我们在具体的的状态类中也需要写大量的if-else去确保状态间进行正确的切换.我曾经尝试使用模板方法将其进行转换的的部分进行抽离.但发现无法进行完全抽离.存在这个问题的可能是我对状态模式的理解有误.也可能是与之结合的方法有误.这个问题待日后再试!

   状态模式和策略模式从结构上看十分相似.但他们内部运行的机理是完全不同.可以拿策略模式的代码和状态模式进行比较便可知道!



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值