三分钟理解“状态模式”——设计模式轻松掌握

什么是状态模式?

一个函数原本有很多判断语句,现在把判断语句中的每一种状态封装成一个类,每一个状态类中均有一个handle()函数,该函数能对当前状态做出处理,并且能指明不能处理时的下一个状态类。

状态模式的类图

1.将一个原本的判断结构封装成一个个状态类,每个状态类都有函数handle(Context);

该函数对本状态作出处理,当无法处理时,将context肚子中的成员变量state改成能处理的那个状态类的对象,并执行context的request()函数;

handle()函数实现如下:

public void handle(Context Context){
	//判断是否能处理
	if(本类能处理){
		进行处理;
	}

	//本类不能处理时
	else{
		//将context的state变量设为能处理状态类的对象
		context.setState(new ConcreteStateB());

		//执行context中的request,让下一个状态类处理
		context.request();
	}
}

2.创建一个Context类,它是提供给客户端执行整个状态模式的接口;

Context类中含有State类型的成员变量state,还有一个handle()函数,该函数用于执行state中的request()函数。

class Context(){
	private State state;

	public void request(){
		this.state.handle();
	}
}

3.当客户端调用context的request()函数时,request调用当前context肚子里的那个state的handle函数,如果能处理就处理掉,如果不能处理就将context的state设为能处理的那个状态类,然后再调用request函数。

然后新的处理函数又被执行,直到遇到能执行的处理类为止。

状态模式与职责链模式的异同?

PS:职责链模式的详细介绍请移步至:http://blog.csdn.net/u010425776/article/details/48037939

相同点:状态模式和职责链模式都是将判断语句中的每一个判断分支封装成一个个类。

不同点:状态模式中,每个状态类中既包含了符合条件时的处理方法,也在不符合条件时指明下一个状态类,然后执行该状态类中的处理函数;而在职责链模式中,每一个处理类的处理函数中只有处理当前状态的方法,若不能处理时下一个处理类是由客户端指定的。

综上所述:状态模式的判断流程是在低层模块中定义好的,职责链模式的处理流程是让用户自己设置的。

状态模式的好处

1.遵循了“单一职责原则”:状态模式把一个复杂的判断结构拆分成一个个拥有先后关系的状态类,从而缩小了原本含有大量判断代码的那个函数的体积;原本这个函数中因为有大量的判断导致这个函数责任过大,而现在这个函数的功能不变,但只有一个Context类,从而职责就小了很多。

2.遵循了“开放-封闭原则”:如果此时需要增加判断分支,只要增加一个新的State子类即可,无需像原来那样修改判断语句的代码。

PS:我们要避免函数过长的现象。因为一个函数过长说明这个函数中职责太多,违背了单一职责原则;我们尽量要把长函数分解成一个个小函数,每个小函数只做一件事。

何时使用状态模式?

当一个函数中判断分支很多时,就需要使用状态模式。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏前端杂货铺

Angular源码分析之$compile

@(Angular) $compile,在Angular中即“编译”服务,它涉及到Angular应用的“编译”和“链接”两个阶段,根据从DOM树遍历Angula...

2815
来自专栏全沾开发(huā)

如何在ES5与ES6环境下处理函数默认参数

1234
来自专栏xingoo, 一个梦想做发明家的程序员

Elasticsearch——Rest API中的常用用法

本篇翻译的是Elasticsearch官方文档中的一些技巧,是使用Elasticsearch必不可少的必备知识,并且适用于所有的Rest Api。 返回数...

1867
来自专栏Golang语言社区

Node.js新手必须知道的4个JavaScript概念

如果只需要知道一种编程语言就可以构建一个全栈的应用程序,是不是特别了不起?Ryan Dahl为了把这个想法成为现实,创造了node.js。Node.js是建立在...

2674
来自专栏编程之旅

Swift中的"警卫队"

大半个月没有更新自己的博客了,最近在忙一个新项目时间非常紧张,所以最近的博客更新进度就要稍微放缓一点了。

541
来自专栏更流畅、简洁的软件开发方式

【实体类变形】—— 元数据(另类ORM) 描述字段的数据

     放假了,不知道有没有加班的,先祝大家国庆节快乐!      上次说得有点乱,“行列转换”这个词可能误导了大家,那么把这个词扔掉吧。我们重新开始。假设我...

20610
来自专栏owent

Lua 挺好用的样子

其实对于理解Javascipt的人来说,Lua也很容易理解,因为他们太多的地方相像了。

943
来自专栏JMCui

MongoDB系列一(查询).

一、简述     MongoDB中使用find来进行查询。查询就是返回一个集合中文档的子集,子集合的范围从0个文档到整个集合。默认情况下,"_id"这个键总是被...

4446
来自专栏小尘哥的专栏

thymeleaf全局常量定义

目测应该是重写这货就可以了,talk is cheap,show me the code

541
来自专栏日常分享

$.ajax()方法详解

1.url: 要求为String类型的参数,(默认为当前页地址)发送请求的地址。

822

扫描关注云+社区