我所理解的设计模式(C++实现)——状态模式(State Pattern)
概述:
看看我们平时用的开关,同样一个开关他有2种状态:开和关,当她处于不同的状态的时候她的行为是不一样的,比如当她是开着的时候,你按她一下,她就变成了关闭状态,她是关着的时候按她一下,她就变成了开着的状态。看上去就像是改变了它的类一样,其实我们开发者都知道,我们里面用到了if-else,但是当碰到更多状态时就会造成很多很多if-else,设计和维护就相当的复杂,我们将要学习的状态模式就是允许一个对象在其内部状态改变时改变它的行为,使对象看起来似乎修改了它的类。
类图和实例:
上下文环境(Context):它定义了客户程序需要的接口并维护一个具体状态角色的实例,将与状态相关的操作委托给当前的Concrete State对象来处理。
抽象状态(State):定义一个接口以封装使用上下文环境的的一个特定状态相关的行为。
具体状态(Concrete State):实现抽象状态定义的接口。
这里我们举星际争霸里的坦克作为例子,它不架起来的时候可以攻击,可以移动。架起来的时候攻击增强,但是不能移动:
#include <iostream>
class SiegeTank;
class ISiegeTankState
{
public:
virtual void move(int x, int y) = 0;
virtual void attack() = 0;
}; class SiegeState : public ISiegeTankState
{
public:
SiegeState(SiegeTank* pTank): m_pTank(pTank){} virtual void move(int x, int y)
{
std::cout << "Can't move in siege mode." << std::endl;
} virtual void attack()
{
std::cout << "Attacking for 40" << std::endl;
} private:
SiegeTank* m_pTank;
}; class TankState : public ISiegeTankState
{
public:
TankState(SiegeTank* pTank): m_pTank(pTank){} virtual void move(int x, int y)
{
std::cout << "Move to (" << x << ", " << y << ")" << std::endl;
} virtual void attack()
{
std::cout << "Attacking for 20" << std::endl;
} private:
SiegeTank* m_pTank;
}; class SiegeTank
{
public:
SiegeTank()
{
m_pTankState = new TankState(this);
m_pSiegeState = new SiegeState(this);
m_pSiegeTankState = m_pTankState;
} void enterTankMode()
{
m_pSiegeTankState = m_pTankState;
std::cout << "Switch to tank mode" << std::endl;
} void enterSiegeMode()
{
m_pSiegeTankState = m_pSiegeState;
std::cout << "Switch to siege mode" << std::endl;
} public:
void attack()
{
m_pSiegeTankState->attack();
} void move(int x, int y)
{
m_pSiegeTankState->move(x, y);
} private:
void setState(ISiegeTankState* pSiegeTankMode)
{
m_pSiegeTankState = pSiegeTankMode;
} private:
TankState* m_pTankState;
SiegeState* m_pSiegeState;
ISiegeTankState* m_pSiegeTankState;
}; int main()
{
SiegeTank tank;
tank.enterTankMode();
tank.attack();
tank.move(1, 1); tank.enterSiegeMode();
tank.attack();
tank.move(2, 2); tank.enterTankMode();
tank.attack();
tank.move(3, 3); return 0;
}
解决的问题:
状态模式主要解决的是当控制一个对象状态装换的条件表达式过于复杂时的情况。把状态的判断逻辑转移到表示不同状态的一系列类中,可以把复杂的判断逻辑简单化。
当一个对象行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为时,就可以考虑使用状态模式了。
优缺点:
优点
1,状态模式将与特定状态相关的行为局部化,并且将不同状态的行为分割开来。
2,所有状态相关的代码都存在于某个ConcereteState中,所以通过定义新的子类很容易地增加新的状态和转换。
3,状态模式通过把各种状态转移逻辑分不到State的子类之间,来减少相互间的依赖。
缺点
1,状态模式的使用必然会增加系统类和对象的个数。
2,状态模式的结构与实现都较为复杂,如果使用不当将导致程序结构和代码的混乱。
LCL_data原创于CSDN.NET【http://blog.csdn.net/lcl_data/article/details/10248415】
更多设计模式文章请参考:我所理解的设计模式
我所理解的设计模式(C++实现)——状态模式(State Pattern)的更多相关文章
- 乐在其中设计模式(C#) - 状态模式(State Pattern)
原文:乐在其中设计模式(C#) - 状态模式(State Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 状态模式(State Pattern) 作者:webabcd 介绍 允 ...
- 二十四种设计模式:状态模式(State Pattern)
状态模式(State Pattern) 介绍允许一个对象在其内部状态改变时改变它的行为.对象看起来似乎修改了它所属的类. 示例有一个Message实体类,对它的操作有Insert()和Get()方法, ...
- 状态模式-State Pattern(Java实现)
状态模式-State Pattern 在状态模式(State Pattern)中,类的行为是基于它的状态改变的.当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类. State接口 ...
- 设计模式(十二):通过ATM取款机来认识“状态模式”(State Pattern)
说到状态模式,如果你看过之前发布的重构系列的文章中的<代码重构(六):代码重构完整案例>这篇博客的话,那么你应该对“状态模式”并不陌生,因为我们之前使用到了状态模式进行重构.上一篇博客我们 ...
- [设计模式] 20 状态模式 State Pattern
在GOF的<设计模式:可复用面向对象软件的基础>一书中对状态模式是这样说的:允许一个对象在其内部状态改变时改变它的行为.对象看起来似乎修改了它的类.状态模式的重点在于状态转换,很多时候,对 ...
- 【UE4 设计模式】状态模式 State Pattern
概述 描述 允许一个对象在其内部状态改变时改变它的行为,对象看起来似乎修改了它的类. 其别名为状态对象(Objects for States),状态模式是一种对象行为型模式. 有限状态机(FSMs) ...
- C#设计模式——状态模式(State Pattern)
一.概述在面向对象软件设计时,常常碰到某一个对象由于状态的不同而有不同的行为.如果用if else或是switch case等方法处理,对象操作及对象的状态就耦合在一起,碰到复杂的情况就会造成代码结构 ...
- [设计模式-行为型]状态模式(State)
一句话 在一个类的对象中维护状态的类的对象 概括
- 《JAVA设计模式》之状态模式(State)
在阎宏博士的<JAVA与模式>一书中开头是这样描述状态(State)模式的: 状态模式,又称状态对象模式(Pattern of Objects for States),状态模式是对象的行为 ...
- 十一个行为模式之状态模式(State Pattern)
定义: 当一个对象有多个状态,并且在每个状态下有不同的行为,可以使用状态模式来在其内部改变状态时改变其行为,而客户端不会察觉状态的改变,仍使用同样的方法或接口与对象进行交互. 结构图: Context ...
随机推荐
- [Qt] qtcreator 中打开console
(1) qtcreator-->左侧Projects-->Run-->中间的checkbox (Run in terminal)打上勾 (2) 在项目的.pro文件中加上 " ...
- css(二)
重新排传智的首页!头部和左边的部分完成了! <!doctype html> <html lang="en"> <head> <meta c ...
- 聚聚科技---PHP开发笔试题及答案
1. echo(), print(), print_r()的区别? echo是PHP语言结构, print和print_r是函数.语言结构没有返回值,函数可以有返回值(即便没有用) . print( ...
- LaunchScreen.xib 设置启动图
1.LaunchScreen.xib 中拖入UIImageView 约束都设置为0 2.新建一个Image Set 起名为LaunchScreen Devices设置为:Device Speecif ...
- ZigBee心电传输(三)
这段时间因为另外一个项目需要,我搞Zed板去了.现在接着上一步的工作吧,继续把心电做完.这里想要测试一下把心电波形数据传输出来,然后用协调器接收,并从串口显示出来.之后再用ZigBee转蓝牙,从而可以 ...
- 每天进步一点点——Linux系统时间来处理
转载请注明出处:http://blog.csdn.net/cywosp/article/details/25839551 在程序中时间处理往往是一个麻烦的事.Linux系统提供了非常多关于时间处理的函 ...
- Qt学习博客推荐
附录C Qt资源 C.1 Qt 官方资源 全 球各大公司以及独立开发人员每天都在加入 Qt 的开发社区.他们已经认识到了Qt 的架构本身便可加快应用程序开发进度.这些开发人员,无论是想开发单平台软件. ...
- SOAP 简单对象访问协议
webService三要素 SOAP.WSDL(WebServicesDescriptionLanguage).UDDI(UniversalDescriptionDiscovery andIntegr ...
- VirtualBox虚拟机网络设置
VirtualBox虚拟机网络设置 测试环境:物理机win10企业版本,VirtaulBox版本5.0.14,虚拟机安装Windows XP及linux系统 想实现虚拟机上网的最简单方式,修改虚拟机网 ...
- HTML5 格式化、样式、链接、表格
HTML格式化.样式.链接.表格的使用举例