行为型(二)—状态模式

1、介绍

状态模式中的行为是由状态决定的,不同的状态有不同的行为。状态模式与策略模式的结构一样的,但它们的目的和本质不同,状态模式的行为是平行的,不可替换的,而策略模式的行为是对立的,可替换的。

2、定义

Allow an object to alter its behavior when its internal state changes. The object will appear to change its class.

当一个对象的内在类改变时允许改变其行为,这对象看起来像是改变了其类。

3、使用场景

  1.  对象的行为依赖它所处的状态,并且在运行是根据状态改变它的行为
  2. 代码中含有大量的跟状态有关的条件语句。

4、UML类图


角色说明:

  1. Context:屏蔽高层模块对行为的直接访问,它持有一个State类的引用
  2. State:对每个行为的抽象
  3. ConcreteStateA、ConcreteStateB:具体的行为类。

5、示例

以遥控器为例来说明状态模式的实现。首先状态模式分为开机和关机状态,在开启状态下,可以进行切换频道、关机操作,但重复开机按键无效;在关机状态下,切换频道和重复关机无效,只能先进行开机操作。

首先看一下普通的实现方式。

/**
 * 电视控制类,含有开机、关机、下一个频道、上一个频道的功能
 * @author Administrator
 *
 */
public class TVController1 {
	private final static int POWER_ON = 1;
	private final static int POWER_OFF = 2;
	private int mState = POWER_OFF;
    public void powerOn(){
		if (mState == POWER_OFF) {
			System.out.println("开机了");
		}
		mState = POWER_ON;
	}
    public void powerOFF(){
    	if (mState == POWER_ON) {
			System.out.println("关机了");
		}
		mState = POWER_OFF;
	}
	public void nextChannel(){
		if (mState == POWER_ON) {
			System.out.println("下一个频道");
		}else {
			System.out.println("抱歉,没有开机");
		}
		
	}
    public void preChannel(){
    	if (mState == POWER_ON) {
			System.out.println("上一个频道");
		}else {
			System.out.println("抱歉,没有开机");
		}
	} 
}

在TVController类中,同名mState存储电视状态,在进行频道切换时,必须通过if-else进行条件判断进行操作,代码重复,相对较为混乱。

接下来,通过状态模式来实现。

/**
 * 状态接口
 * @author Administrator
 *
 */
public interface TVState {
	public void nextChannel();
	public void preChannel();
}
/**
 * 具体状态实现类,开机状态
 * @author Administrator
 *
 */
public class PowerOnState implements TVState {

	@Override
	public void nextChannel() {
		System.out.println("下一个频道");
	}

	@Override
	public void preChannel() {
		System.out.println("上一个频道");
	}

}
/**
 * 具体状态实现,关机状态
 */
public class PowerOffState implements TVState{
	@Override
	public void nextChannel() {
		System.out.println("抱歉,请先开机");
	}

	@Override
	public void preChannel() {
		System.out.println("抱歉,请先开机");
	}
}
/**
 * 电源操作接口
 */
public interface PowerController {
	public void powerOn();
	public void powerOff();
}
public class TVController implements PowerController{
	private TVState mState = null;

	public void setState(TVState state) {
		this.mState = state;
	}
	
	public void nextChannel(){
		mState.nextChannel();
	}
	
	public void preChannel() {
		mState.preChannel();
	}

	@Override
	public void powerOn() {
		setState(new PowerOnState());
		System.out.println("开机了");
	}

	@Override
	public void powerOff() {
		setState(new PowerOffState());
		System.out.println("关机了");
	}	
}
/**
 * 客户端调用
 */
public class Client {
	public static void main(String[] args) {
		TVController controller = new TVController();
		controller.powerOn();
		controller.nextChannel();
		controller.preChannel();
		
		controller.powerOff();
		controller.nextChannel();
		controller.preChannel();
	}
}

输出结果如下:

开机了
下一个频道
上一个频道
关机了
抱歉,请先开机
抱歉,请先开机

6、总结

优点:State模式将所有与一个状态对象有关的行为组织成一个接口类,统一管理,结构清晰,避免代码臃肿,同时也保证了可扩展性和可维护性

缺点:子类太多,不易管理
Python网络爬虫与推荐算法新闻推荐平台:网络爬虫:通过Python实现新浪新闻的爬取,可爬取新闻页面上的标题、文本、图片、视频链接(保留排版) 推荐算法:权重衰减+标签推荐+区域推荐+热点推荐.zip项目工程资源经过严格测试可直接运行成功且功能正常的情况才上传,可轻松复刻,拿到资料包后可轻松复现出一样的项目,本人系统开发经验充足(全领域),有任何使用问题欢迎随时与我联系,我会及时为您解惑,提供帮助。 【资源内容】:包含完整源码+工程文件+说明(如有)等。答辩评审平均分达到96分,放心下载使用!可轻松复现,设计报告也可借鉴此项目,该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的。 【提供帮助】:有任何使用问题欢迎随时与我联系,我会及时解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 下载后请首先打开README文件(如有),项目工程可直接复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值