状态模式(state)C++实现
2016-04-06 20:30
465 查看
状态模式
当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。状态模式主要解决的是当控制一个对象状态转换的条件表达式过于复杂时的情况。把状态的判断逻辑转移到表示不同状态的一系列类当中,可以把复杂的判断逻辑简化。
将与特点状态相关的行为局部化,并且将不同状态的行为分割开来!
UML:
代码实现:
以前很喜欢玩war3里面的国家对抗,是一个建造类游戏。里面的建筑在不同的时候有不同的状态,例如兵营在产兵的时候会发白光,
受伤的时候会着火,建造的时候有建筑特效。兵营在建造没完成的时候不能升级和产兵,升级的时候不能产兵,受伤着火了也能继续产兵或升级。
假设这些建筑的状态和表现为:建造-建造特效、受伤-受伤着火、升级-升级蓝光、生成-生产白光、修复-修复绿光。
实现各种状态代码state.h:
#ifndef STATE_H #define STATE_H #include <iostream> using namespace std; class absState{ public: virtual void show() = 0; }; class buildingState:public absState{ public: virtual void show() { cout<<"建造特效 "; } }; class fireState:public absState{ public: virtual void show() { cout<<"受伤着火 "; } }; class productionState:public absState{ public: virtual void show() { cout<<"生产白光 "; } }; class upGradeState:public absState { public: virtual void show() { cout<<"升级蓝光 "; } }; class repairState:public absState { public: virtual void show() { cout<<"修复绿光 "; } }; #endif
建筑实现代码building.h:
#ifndef BUILDING_H #define BUILDING_H #include "state.h" #include <map> #include <iostream> using namespace std; enum StateType { BUILDING, INJURED, REPAIR, UPGRADE, PRODUCTION }; class absBuilding { public: absBuilding(char* name):mName(name){} virtual void show() { cout<<mName<<"表现:"<<endl; map<StateType, absState*>::iterator beg = mStates.begin(); for ( ; beg != mStates.end(); beg++) { beg->second->show(); } cout<<endl; }; void eraseState(StateType type) //实现删除一个特效 { auto result = mStates.find(type); if(result != mStates.end()) mStates.erase(result); } protected: char* mName; map<StateType, absState*> mStates; }; class concreteBuilding:public absBuilding { public: concreteBuilding(char* name):absBuilding(name) { mStates[BUILDING] = new buildingState(); } void upGrade() { auto result = mStates.find(UPGRADE); if(result == mStates.end()) { mStates[UPGRADE] = new upGradeState(); } eraseState(BUILDING); //升级的时候必须是建造过程已经结束,所以需要删掉“建筑”状态 eraseState(PRODUCTION); //升级的时候不能进行生产 } void production() { auto result = mStates.find(PRODUCTION); if(result == mStates.end()) { mStates[PRODUCTION] = new upGradeState(); } eraseState(BUILDING); //生产的时候必须已经建造完成 eraseState(UPGRADE); //生产的时候不能升级 } void injured() { auto result = mStates.find(INJURED); if(result == mStates.end()) { mStates[INJURED] = new fireState(); } } void repair() { auto injuredVal = mStates.find(INJURED); if(injuredVal == mStates.end()) return; auto result = mStates.find(REPAIR); if(result == mStates.end()) { mStates[REPAIR] = new repairState(); } } }; #endif
客户端代码main.cpp:
#include <iostream> #include "tank.h" #include "building.h" using namespace std; class SiegeTank; void main() { concreteBuilding cb("兵营"); cb.production(); cb.injured(); cb.repair(); cb.show(); return; }
结果:
相关文章推荐
- C++中的异常浅析
- 【C++】多文件程序结构
- c++中.dll与.lib文件的生成与使用的详解
- c语言的问卷调查
- c++操作符重载
- C语言的知识与能力的自评
- C++命名空间理解
- c++覆盖 重载 隐藏 的关系
- C++编程思想第二章练习答案
- lamda:和c++差不多
- Sublime text2 C/C++ 编译环境设置
- POJ 2236-Wireless Network(并查集)
- C语言入门基础篇,内存与变量关系
- C++入门基础知识:类和引用
- C++基础学习教程(六)----类编写的前情回想以及项目实战(1)
- Eclipse CDT MinGW生成C++动态链接库及Java JNI的调用例子
- C语言 格式问题
- C++Primer_笔记_异常处理
- C++之类的const成员变量和const成员函数
- 在VS2015中用C++创建DLL并用C#调用且同时实现对DLL的调试