设计模式基础——状态模式
2016-02-01 17:04
197 查看
状态模式和策略模式比较相似,都是将算法抽象出来成为独立的类。但是相比策略模式,状态模式下的独立类中间存在着内在的联系。
引用《Head First: Design Patterns》中的原话:
A little known fact: the Strategy and State Patterns were twins separated at birth. As you know, the Strategy Pattern went on to create a wildly successful business around interchangeable algorithms. State, however, took the perhaps more noble path of
helping objects to control their behavior by changing their internal state. He’s often overheard telling his object clients, “Just repeat after me: I’m good enough, I’m smart enough, and doggonit...”
下面是一个例子:
上例中,Gun有两种状态,一种是有子弹的,一种是没有子弹的。
当Character使用Gun时,会遇到两种情况,即上面说的有子弹和没有子弹两种情况。且两种情况交替出现。
这里使用了Gun的两种状态,并包装了它们使用时的算法,这样Character就不需要直接去关注两种情况的不同,反正直接使用就可以了。
下面是具体的代码:
1. Character类:
引用《Head First: Design Patterns》中的原话:
A little known fact: the Strategy and State Patterns were twins separated at birth. As you know, the Strategy Pattern went on to create a wildly successful business around interchangeable algorithms. State, however, took the perhaps more noble path of
helping objects to control their behavior by changing their internal state. He’s often overheard telling his object clients, “Just repeat after me: I’m good enough, I’m smart enough, and doggonit...”
下面是一个例子:
上例中,Gun有两种状态,一种是有子弹的,一种是没有子弹的。
当Character使用Gun时,会遇到两种情况,即上面说的有子弹和没有子弹两种情况。且两种情况交替出现。
这里使用了Gun的两种状态,并包装了它们使用时的算法,这样Character就不需要直接去关注两种情况的不同,反正直接使用就可以了。
下面是具体的代码:
1. Character类:
/****************** Character声明 ********************/ class Character { private: //Gun的两种状态 Gun *hasBulletsState; Gun *noBulletsState; //currentState可以是上面的任意一种 Gun *currentState; public: //构造函数 Character(); //获取和设置状态的函数 Gun * getNoBulletsState(); Gun * getHasBulletsState(); void setState(Gun *gs); //主函数 void useGun(); };2. Character类的实现:
/****************** Character定义 ********************/ Character::Character() { //初始化时就要确定所有的状态 hasBulletsState = new HasBulletsGun(); hasBulletsState->setOwner(this); hasBulletsState->setBullets(BULLETS_SIZE); noBulletsState = new NoBulletsGun(); noBulletsState->setOwner(this); this->currentState = hasBulletsState; } Gun * Character::getNoBulletsState() { return this->noBulletsState; } Gun * Character::getHasBulletsState() { return this->hasBulletsState; } void Character::setState(Gun *gs) { this->currentState = gs; } void Character::useGun() { currentState->active(); }3. Gun类及其定义:
/****************** Gun声明 ********************/ class Gun { private: Character *owner; int bulletsCount; public: void setOwner(Character *ch); Character *getOwner(); void setBullets(int count); int getBullets(); void fire(); virtual void active(); }; /****************** Gun定义 ********************/ void Gun::active() { cout << "Gun active." << endl; } void Gun::setBullets(int count) { this->bulletsCount = count; } int Gun::getBullets() { return this->bulletsCount; } void Gun::fire() { this->bulletsCount--; cout << "Fire one bullet. Bullets left: " << this->bulletsCount << endl; } Character *Gun::getOwner() { return this->owner; } void Gun::setOwner(Character *ch) { this->owner = ch; }4. Gun的子类状态:
/****************** HasBulletsGun定义 ********************/ class HasBulletsGun : public Gun { public: void active() override; }; void HasBulletsGun::active() { fire(); if (getBullets() == 0) { getOwner()->setState(getOwner()->getNoBulletsState()); } } /****************** NoBulletsGun定义 ********************/ class NoBulletsGun : public Gun { public: void active() override; }; void NoBulletsGun::active() { cout << "No bullets left. Setting bullets... " << endl; getOwner()->getHasBulletsState()->setBullets(BULLETS_SIZE); getOwner()->setState(getOwner()->getHasBulletsState()); cout << "Done" << endl; }5. 测试代码:
/****************** 测试 ********************/ int main(void) { Character *ch = new Character(); for (int i = 0; i < 10; i++) {<span style="white-space:pre"> </span>//开枪10次,中间会有重新装弹的过程 ch->useGun(); } return 0; }6. 下面是测试结果:
相关文章推荐
- Attribute "resultType" must be declared for element type "insert"或"update"
- 中科燕园GIS外包----机场project地理信息系统EGIS
- android 窗口的使用
- 使用C#编写简单的图形化的可发送附件的邮件客户端程序
- hdu 2097 Sky数
- 父类方法中使用this,那么这个this指的是谁?
- 树莓派无显示器上手步骤
- strindex实现
- fir.im Weekly - 技术人也要苦练“七十二变”
- Android Fragment是什么
- 游戏中接入第三方渠道时 关于meta-data的一些小问题
- 网狐 自绘 倒计时和准备按钮
- Java实现排队论的原理
- VNC Server Configuration
- POJ3461 字符串hash
- python 几种常见的测试框架
- iOS开发-NSInteger 和 int 的区别
- 加载动作
- MongoDB的安装以及自启动问题
- OI知识体系