状态模式
当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。
状态模式主要解决的是当控制一个对象状态转换的条件表达式过于复杂时的情况。把状态的判断逻辑转移到表示不同状态的一系列类当中,可以把复杂的判断逻辑简化。
将与特点状态相关的行为局部化,并且将不同状态的行为分割开来!
UML:
代码实现:
以前很喜欢玩war3里面的国家对抗,是一个建造类游戏。里面的建筑在不同的时候有不同的状态,例如兵营在产兵的时候会发白光,
受伤的时候会着火,建造的时候有建筑特效。兵营在建造没完成的时候不能升级和产兵,升级的时候不能产兵,受伤着火了也能继续产兵或升级。
假设这些建筑的状态和表现为:建造-建造特效、受伤-受伤着火、升级-升级蓝光、生成-生产白光、修复-修复绿光。
实现各种状态代码state.h:
1 #ifndef STATE_H
2 #define STATE_H
3 #include <iostream>
4 using namespace std;
5
6 class absState{
7 public:
8 virtual void show() = 0;
9 };
10
11 class buildingState:public absState{
12 public:
13 virtual void show()
14 {
15 cout<<"建造特效 ";
16 }
17 };
18
19 class fireState:public absState{
20 public:
21 virtual void show()
22 {
23 cout<<"受伤着火 ";
24 }
25 };
26
27 class productionState:public absState{
28 public:
29 virtual void show()
30 {
31 cout<<"生产白光 ";
32 }
33 };
34
35 class upGradeState:public absState
36 {
37 public:
38 virtual void show()
39 {
40 cout<<"升级蓝光 ";
41 }
42 };
43
44 class repairState:public absState
45 {
46 public:
47 virtual void show()
48 {
49 cout<<"修复绿光 ";
50 }
51 };
52 #endif
建筑实现代码building.h:
1 #ifndef BUILDING_H
2 #define BUILDING_H
3 #include "state.h"
4
5 #include <map>
6 #include <iostream>
7 using namespace std;
8
9 enum StateType
10 {
11 BUILDING, INJURED, REPAIR, UPGRADE, PRODUCTION
12 };
13
14 class absBuilding
15 {
16 public:
17 absBuilding(char* name):mName(name){}
18 virtual void show()
19 {
20 cout<<mName<<"表现:"<<endl;
21 map<StateType, absState*>::iterator beg = mStates.begin();
22 for ( ; beg != mStates.end(); beg++)
23 {
24 beg->second->show();
25 }
26 cout<<endl;
27 };
28 void eraseState(StateType type) //实现删除一个特效
29 {
30 auto result = mStates.find(type);
31 if(result != mStates.end())
32 mStates.erase(result);
33 }
34 protected:
35 char* mName;
36 map<StateType, absState*> mStates;
37 };
38
39 class concreteBuilding:public absBuilding
40 {
41 public:
42 concreteBuilding(char* name):absBuilding(name)
43 {
44 mStates[BUILDING] = new buildingState();
45 }
46 void upGrade()
47 {
48 auto result = mStates.find(UPGRADE);
49 if(result == mStates.end())
50 {
51 mStates[UPGRADE] = new upGradeState();
52 }
53 eraseState(BUILDING); //升级的时候必须是建造过程已经结束,所以需要删掉“建筑”状态
54 eraseState(PRODUCTION); //升级的时候不能进行生产
55 }
56 void production()
57 {
58 auto result = mStates.find(PRODUCTION);
59 if(result == mStates.end())
60 {
61 mStates[PRODUCTION] = new upGradeState();
62 }
63 eraseState(BUILDING); //生产的时候必须已经建造完成
64 eraseState(UPGRADE); //生产的时候不能升级
65 }
66 void injured()
67 {
68 auto result = mStates.find(INJURED);
69 if(result == mStates.end())
70 {
71 mStates[INJURED] = new fireState();
72 }74 }
75 void repair()
76 {
77 auto injuredVal = mStates.find(INJURED);
78 if(injuredVal == mStates.end())
79 return;
80 auto result = mStates.find(REPAIR);
81 if(result == mStates.end())
82 {
83 mStates[REPAIR] = new repairState();
84 }86 }
87 };
88
89 #endif
客户端代码main.cpp:
1 #include <iostream>
2 #include "tank.h"
3 #include "building.h"
4
5 using namespace std;
6 class SiegeTank;
7
8 void main()
9 {
10 concreteBuilding cb("兵营");
11 cb.production();
12 cb.injured();
13 cb.repair();
14 cb.show();
15 return;
16 }
结果:
原文链接: https://www.cnblogs.com/wrbxdj/p/5361004.html
欢迎关注
微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍
原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/231480
非原创文章文中已经注明原地址,如有侵权,联系删除
关注公众号【高性能架构探索】,第一时间获取最新文章
转载文章受原作者版权保护。转载请注明原作者出处!