[设计模式] 20 状态模式 State Pattern
在GOF的《设计模式:可复用面向对象软件的基础》一书中对状态模式是这样说的:允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类。状态模式的重点在于状态转换,很多时候,对于一个对象的状态,我们都是让这个对象包含一个状态的属性,这个状态属性记录着对象的具体状态,根据状态的不同使用分支结构来执行不同的功能,就像上面的代码那样处理;就像上面说的,类中存在大量的结构类似的分支语句,变得难以维护和理解。状态模式消除了分支语句,就像工厂模式消除了简单工厂模式的分支语句一样,将状态处理分散到各个状态子类中去,每个子类集中处理一种状态,这样就使得状态的处理和转换清晰明确。

Context:定义客户端感兴趣的接口,并且维护一个ConcreteState子类的实例,这个实例定义当前状态;
State:定义一个接口以封装与Context的一个特定状态相关的行为;
ConcreteState subclasses:每一个子类实现一个与Context的一个状态相关的行为。
它们之间的协作步骤如下:
- Context将与状态相关的请求委托给当前的ConcreteState对象处理;
- Context可以将自身作为一个参数传递给处理该请求的状态对象。这使得状态对象在必要时可以访问Context;
- Context是客户使用的主要接口。客户可用状态对象来配置一个Context,一旦一个Context配置完毕,它的客户不再需要直接与状态对象打交道;
使用场合
在以下两种情况下均可使用State模式:
- 一个对象的行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为;
- 一个操作中含有庞大的多分支的条件语句,且这些分支依赖于该对象的状态。这个状态通常用一个或多个枚举常量表示。通常有多个操作包含这一相同的条件结构。State模式将每一个条件分支放入一个独立的类中。这使得你可以根据对象自身的情况将对象的状态作为一个对象,这一对象可以不依赖于其它对象而独立变化
#include <iostream>
using namespace std; class Context; class State
{
public:
virtual void Handle(Context *pContext) = ;
}; class ConcreteStateA : public State
{
public:
virtual void Handle(Context *pContext)
{
cout<<"I am concretestateA."<<endl;
}
}; class ConcreteStateB : public State
{
public:
virtual void Handle(Context *pContext)
{
cout<<"I am concretestateB."<<endl;
}
}; class Context
{
public:
Context(State *pState) : m_pState(pState){} void Request()
{
if (m_pState)
{
m_pState->Handle(this);
}
} void ChangeState(State *pState)
{
m_pState = pState;
} private:
State *m_pState;
}; int main()
{
State *pStateA = new ConcreteStateA();
State *pStateB = new ConcreteStateB();
Context *pContext = new Context(pStateA);
pContext->Request(); pContext->ChangeState(pStateB);
pContext->Request(); delete pContext;
delete pStateB;
delete pStateA;
}
简单的将对象的状态和对应状态下的行为分离开来,不再是简单的if…else或switch…case分支结构了,而是每一个状态都对应一个类,一个类集中管理一个状态;在多状态的情况下,简化了程序的维护和管理,让程序结构简明化,同时也易于扩展。
[设计模式] 20 状态模式 State Pattern的更多相关文章
- 乐在其中设计模式(C#) - 状态模式(State Pattern)
原文:乐在其中设计模式(C#) - 状态模式(State Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 状态模式(State Pattern) 作者:webabcd 介绍 允 ...
- 二十四种设计模式:状态模式(State Pattern)
状态模式(State Pattern) 介绍允许一个对象在其内部状态改变时改变它的行为.对象看起来似乎修改了它所属的类. 示例有一个Message实体类,对它的操作有Insert()和Get()方法, ...
- 【UE4 设计模式】状态模式 State Pattern
概述 描述 允许一个对象在其内部状态改变时改变它的行为,对象看起来似乎修改了它的类. 其别名为状态对象(Objects for States),状态模式是一种对象行为型模式. 有限状态机(FSMs) ...
- 【转】设计模式 ( 十七) 状态模式State(对象行为型)
设计模式 ( 十七) 状态模式State(对象行为型) 1.概述 在软件开发过程中,应用程序可能会根据不同的情况作出不同的处理.最直接的解决方案是将这些所有可能发生的情况全都考虑到.然后使用if... ...
- 设计模式 ( 十七) 状态模式State(对象行为型)
设计模式 ( 十七) 状态模式State(对象行为型) 1.概述 在软件开发过程中,应用程序可能会根据不同的情况作出不同的处理.最直接的解决方案是将这些所有可能发生的情况全都考虑到.然后使用if... ...
- 状态模式-State Pattern(Java实现)
状态模式-State Pattern 在状态模式(State Pattern)中,类的行为是基于它的状态改变的.当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类. State接口 ...
- 北风设计模式课程---状态模式State(对象行为型)
北风设计模式课程---状态模式State(对象行为型) 一.总结 一句话总结: 状态模式 具体状态的行为在具体的状态类中就解决,不用交给外部做判断.实质是将多条件判断弄成了多个类,在不同的类中做判断 ...
- 设计模式2——状态模式State
参考链接: 设计模式之状态模式:https://www.cnblogs.com/haoerlv/p/7777789.html 设计模式系列之状态模式:https://www.jianshu.com/p ...
- 设计模式(十二):通过ATM取款机来认识“状态模式”(State Pattern)
说到状态模式,如果你看过之前发布的重构系列的文章中的<代码重构(六):代码重构完整案例>这篇博客的话,那么你应该对“状态模式”并不陌生,因为我们之前使用到了状态模式进行重构.上一篇博客我们 ...
随机推荐
- 关于strong、copy、weak、assign的常规用法
strong 对于普通的OC对象都是使用strong copy 对于 NSString,Block weak 用于OC对象,1.当出现循环强引用的时候,必须要保证一端是weak, 2 ...
- UI1_UITabBarController
// // AppDelegate.h // UI1_UITabBarController // // Created by zhangxueming on 15/7/8. // Copyright ...
- OC2-xml文件解析
<?xml version="1.0" encoding="UTF-8"?> <Students class="17班" ...
- 20140213-想念是while里的死循环
// stdafx.h : 标准系统包含文件的包含文件,// 或是经常使用但不常更改的// 特定于项目的包含文件// #pragma once#include "targetver.h&qu ...
- 重新审视事件对象event
前言:之前在学习事件对象event时,一是一直在chrome浏览器(作为主运行环境)下运行调试自个儿程序,二是可能当时对事件对象理解不透彻才导致现在对事件对象的用法陷入了一个大坑,遂以此篇博客记之. ...
- 南阳理工ACM954--N!
http://acm.nyist.net/JudgeOnline/problem.php?pid=954 循环的可怕之处!! 所有的测试数据结果完全一样.只是超时!!TimeLimitExceeded ...
- score
#include<iostream> using namespace std; class student{ public: int Input() { ;i<;i++) { cou ...
- PCB参数计算神器-Saturn PCB Design Toolkit下载及安装指南
进行PCB设计,特别是高频高速设计时,难免会涉及到PCB相关参数的计算及设置,如:VIA的过流能力,VIA的寄生电容.阻抗等,导线的载流能力,两相互耦合信号线间的串扰,波长等参数. 这里向大家介绍一款 ...
- 实验九--裸机LCD
一.环境 系统:ubuntu12.04 开发板:jz2440 编译器:gcc 二.说明 有空补上 三.代码 Makefile: CC = arm-linux-gcc LD = arm-linux-ld ...
- 浅析 GRUB 如何加载 linux kernel
前言 对于 GRUB 的加载流程,网上绝大部分都是写对 menu.lst, grub.cfg 这些 GRUB 配置文件的编写流程,就像是写脚本语言一样,用些关键字就能让 PC机能正确启动桌面 Linu ...