`

五十九:状态模式

阅读更多
状态模式允许一个对象在其内部状态改变时改变其行为:这个对象看上去就像是改变了它的类一样。我打个比方吧,人饿了就吃饭,渴了就喝水,不饿也不渴就给我坐着别动..

一:状态模式的结构
用一句话来表述,状态模式把所研究的对象的行为包装在不同的状态对象里,每一个状态对象都属于一个抽象状态类的一子类。状态模式的意图是让一个对象在其内部状态改变的时候,其行为也随之改变.它所涉及到的角色有:
(A)抽象状态(State)角色:定义一个接口,用以封装环境(Context)对象的一个特定状态所对应的行为
(B)具体状态(ConcreteState)角色:每一个具体状态类都实现了环境(Context)的一个状态所对应的行为
(C)环境(Context)角色:定义客户端所感兴趣的接口,并且保留一个具体状态类实例,这个具体状态类的实例给出此环境对象的现在状态.
可以知道,环境类Context是所考察的类,而它的行为sampleOperation是委派给类型为State的一个对象,由于State本身是一个抽象类或接口,实际担当此任务的是具体状态类ConcreteState,具体状态类可能有很多。通过使用多态性原则,可以动态地改变环境类Context的属性State的内容,使其从一个指向一个具体状态类变换到指向另一个具体状态类,从而使环境类的行为sampleOperation由不同的具体状态类来执行.

二:用状态模式实现系统登录
用户进入系统前处于Logout状态,用户使用正确的用户名和密码便可以渡到Login状态。当用户处于Login状态时可以发出Logout命令过渡到Logout状态,用户在Login状态时重新发送Login的命令不会改变状态.不同的状态对象会产生不同的网页,对应Login状态的状态对象给出欢迎网页,对应Logout的状态对象重新给出登录网页,系统需要一个登录网页作为客户端,登录网页接收用户名和密码,并把用户提交给一个Servlet,这个Servlet便可以在doPost或doGet方法中接收用户名和密码并且创建对应的状态对象。代码如下:

<title>用户登录</title>
<title>系统首页</title>

package cai.milenfan.basic.test; 

import java.io.IOException; 
import javax.servlet.ServletException; 
import javax.servlet.ServletRequest; 
import javax.servlet.http.*; 

public class ContextServlet extends HttpServlet { 
public void doGet(HttpServletRequest request, HttpServletResponse response) 
throws ServletException, IOException { 
doService(request, response); 
} 
public void doPost(HttpServletRequest request, HttpServletResponse response) 
throws ServletException, IOException { 
doService(request, response); 
} 
public void doService(HttpServletRequest request, HttpServletResponse response) 
throws ServletException, IOException { 
String userId = request.getParameter("userid"); 
String password = request.getParameter("password"); 
String btnAction = request.getParameter("btnAction"); 
writelogline("before logging"); 
if (btnAction.equalsIgnoreCase("log on")) { 
writelogline("logging in"); 
this.getState().login(userId, password); 
} else if (btnAction.equalsIgnoreCase("log out")) { 
writelogline("logging out"); 
this.getState().logout(); 
} 
response.sendRedirect(this.getState().getNextPage());
} 
public UserState getState() { 
return userState.getCurrentState(); 
} 
private static void writelogline(String msg) { 
System.out.println(msg); 
} 
private UserState userState = new LogoutState();
} 


package cai.milenfan.basic.test; 

//代表用户状态,有两个状态:一个是未登录状态,一个是已登录状态 
public abstract class UserState { 
public UserState() { 
this.nextPage = PAGE_LOGIN; 
} 
public abstract boolean login(String userId, String password); 
public abstract void logout(); 
public void setCurrentState(UserState state) { 
this.state = state; 
} 
public UserState getCurrentState() { 
if (this.state == null) { 
this.state = new LoginState(); 
} 
return this.state; 
} 
public String getNextPage() { 
return nextPage; 
} 
public void setNextPage(String nextPage) { 
this.nextPage = nextPage; 
} 
private UserState state; 
private String nextPage; 
protected static String PAGE_WELCOME = "/test/index.jsp"; 
protected static String PAGE_LOGIN = "/test/stateTest.jsp"; 
} 



package cai.milenfan.basic.test; 

public class LoginState extends UserState { 
public LoginState() { 
// write code here 
} 
public boolean login(String userId, String password) { 
setNextPage(UserState.PAGE_WELCOME); 
setCurrentState(new LoginState()); 
return true; 
} 
public void logout() { 
setNextPage(UserState.PAGE_LOGIN); 
setCurrentState(new LogoutState()); 
} 
} 



package cai.milenfan.basic.test; 

public class LogoutState extends UserState { 
public LogoutState() { 
// write your code here 
} 

public boolean login(String userId, String password) { 
StringBuffer sql = new StringBuffer(50); 
sql.append("SELECT COUNT(*) FROM user_info WHERE user_id = '").append( 
userId).append("' AND password = '").append(password).append("'"); 

int counting = DBManager.getAggregate(sql.toString()); 

if (counting &gt; 0) { 
this.setNextPage(UserState.PAGE_WELCOME); 
this.setCurrentState(new LoginState()); 
return true; 
} else { 
this.setNextPage(UserState.PAGE_LOGIN); 
this.setCurrentState(new LogoutState()); 
return false; 
} 
} 

public void logout() { 
this.setCurrentState(new LogoutState()); 
this.setNextPage(UserState.PAGE_LOGIN); 
} 
} 



package cai.milenfan.basic.test; 

public class DBManager { 
public DBManager() { 
} 
public static int getAggregate(String sql) { 
return 1; 
} 
}
分享到:
评论

相关推荐

    Head First 设计模式 JAVA源码

    所有的设计模式Java实现。...第二十四讲:状态模式 第二十五讲:命令模式 第二十六讲:开放-封闭原则 第二十七讲:里氏转换原则 第二十八讲:依赖倒转原则 第二十九讲:迪米特法则 第三十讲:设计模式总结

    设计模式PPT.rar

    22第二十二讲备忘录模式 23第二十三讲状态模式 24第二十四讲命令模式 25第二十五讲访问者模式 26第二十六讲开放封闭原则 27第二十七讲单一职责原则 28第二十八讲里氏代换原则 29第二十九讲依赖倒转原则 30第三十讲...

    设计模式-7种开发语言(C#、JAVA、JavaScript、C++、Python、Go、PHP).pdf

    24种设计模式的入门,整合7种开发语言的代码示例。...第十九节 备忘录模式 第二十节 状态模式 第二十一节 访问者模式 第二十二节 原型模式 第二十三节 享元模式 第二十四节 责任链模式 第二十五节 解释器模式

    C++设计模式

    (十二)状态模式 32 (十三)适配器模式 34 (十四)备忘录模式 37 (十五)组合模式 39 (十六)迭代器模式 45 (十七)单例模式 46 (十八)桥接模式 47 (十九)命令模式 49 (二十)责任链模式 52 (二十一)...

    LabVIEW宝典课件

    入门篇 第一章:打开LabVIEW编程...第十二章:VI模板、设计模式、状态图 第十三章:串并口通讯、网络与DSC 第十四章:数据库、报表工具 第十五章:LabVIEW与RT系统 第十六章:LabVIEW与数据采集 第十七章:FPGA工具包

    LabVIEW宝典课件.ppt

    LABVIEW入门教程PPT,分别为...第十二章:VI模板、设计模式、状态图 第十三章:串并口通讯、网络与DSC 第十四章:数据库、报表工具 第十五章:LabVIEW与RT系统 第十六章:LabVIEW与数据采集 第十七章:FPGA工具包

    网钛文章管理系统 V2.91最新版

    八、独创的首页布局支持五种不同的模式:左两栏右热门文章和投票(3:3:2)、全三栏(1:1:1)、淘宝客排行榜、淘宝客店铺推荐、淘宝客个性化版,后台可直接设置,一个系统搭建五种网站,褡阌没Р煌的需要。...

    VISTA-120安装配置指南

    第十九章: 防区索引及防区类型定义 51 第二十章: 数据项描述 55 第二十一章: #93 菜单模式编程 66 #93 主菜单选项 66 防区编程 68 序列号编程 71 报告码编程 73 编程防区描述符 76 描述符单词、字母表 78 设备编程...

    Java基础知识点总结.docx

    十九、 Ajax原理及实现步骤★★★★★ 130 Ajax概述 130 Ajax工作原理 130 Ajax实现步骤 130 详解区分请求类型: GET或POST 131 $.ajax标准写法 134 二十、 正则表达式:其实是用来操作字符串的一些规则★★★☆ 135 ...

    大型网页游戏架构书

    制作使用的设计模式: Strategy 模式; 工厂模式; 单例模式; 外观模式. Decorator 模式: 五.事件管理(GameEvent 包) 划分不同的情节,用不同的类来描述情节。包括不同的任务。 初步想法:写出不同的事件,每一...

    Linux命令笔记

    第五部分:系统管理 系统管理/工作管理 1:把进程放入后台(&,ctrl+z) 2:查看后台的工作 语法:jobs [选项] 3:将后台暂停的工作恢复到前台执行 语法:fg %工作号 4:把后台暂停的工作恢复到后台执行 语法:bg %工作号 ...

    面向对象与UML资料

    第九章 GRASP: 职责分配模式 97 导言 97 职责和方法 98 UML类图表示方法 98 职责和交互图 98 模式 99 GRASP: 职责分配中通用原则的模式 99 专家 99 问题: 99 解决方案: 99 举例: 99 专家模式的优点是: 100 创建...

    ASP.NET教学讲义,完整章节

    第十五章:创建Web服务 210 15.1 Web服务简介 210 15.2 Web服务 210 15.3 Web服务的特征 210 15.4 Web服务体系结构 211 15.5 Web服务协议栈 211 15.6 使用.net2005创建Web服务 212 15.7 创建自定义的Web服务 214 ...

    asp.net知识库

    ASP.NET运行模式:PageHandlerFactory 利用搜索引擎引用来高亮页面关键字 网站首页的自动语言切换 应用系统的多语言支持 (一) 应用系统的多语言支持 (二) 自动返回上次请求页面(小技巧) ASP.NET 2.0 控件 ASP...

    华为HCIP-RS V2.5培训视频教程【共42天242集】.rar

    目录:网盘文件,永久链接 ...第三十九天-MPLS-LDP工作机制、标签管理模式、PHP、VPN 第四十天-MPLS-单域方案原理 第四十一天-QoS-服务模型、报文分类标记 第四十二天-QoS-拥塞管理和避免、流量监管、流

    Quartz-Job-Scheduling-Framework-中文版-V0.9.1.zip

    有状态和无状态的 Job。 第四章. 部署 Job (第三部分) 内容提要:Job 的易失性、持久性和可恢复性,如何从 Scheduler 中移除、中断 Job。Quartz 已为我们提供了哪些 Job。最后是 Java 线程的简单介绍。 第四章. ...

    如何查杀运行状态下的EXE、DLL病毒

    第九招:取消“磁盘空间不足”通知 当磁盘驱动器的容量少于200MB时Windows XP便会发出“磁盘空间不足”的通知,非常烦人。可以打开“注册表编辑器”,定位到HKEY_CURRENT_USERSoftwareMi ...

    java8源码-LambdaPractice:《java8实战》代码练习

    1、添加设计模式代码实践,状态模式state和代理模式proxy ####第十周完成工作 1、添加设计模式代码实践,模板方法模式templateMethod,迭代器模式和组合模式iteratorAndComposite ####第九周完成工作 1、添加设计模式...

    Java语言基础下载

    第二十九章: Jsp 技术 583 学习目标 583 JSP介绍 584 JSP语法 584 模板元素 588 指令元素 588 页面指令 588 标签库指令 593 脚本元素 593 动作元素 597 &lt;jsp:include&gt; 598 JSP内置对象 605 Session和Application...

    智能照明系统介绍.pptx

    第十:智能灯光照明控制系统还有停电自锁的功能,即当您的家里停电了,来电以后所有的灯将保持熄灭状态。 智能照明系统介绍全文共7页,当前为第6页。 智能灯光控制系统的好处 第一:可以实现场景控制,定时控制,...

Global site tag (gtag.js) - Google Analytics