一、访问者模式
1. 什么是访问者模式
Visitor Pattern,访问者模式,是一种行为型设计模式。访问者模式把数据结构和作用于数据结构上的操作进行了分离,在不修改已有类的前提下可以增加新的操作,而新增新的操作就相当于新增一个访问者。
- Visitor:抽象访问者角色,声明了访问操作的方法,方法的参数为被访问的元素;
- ConcreteVisitor:具体访问者角色,实现抽象访问者中声明的方法;
- Element:抽象元素角色,声明接受访问的操作,并接收一个访问者对象作为参数;
- ConcreteElement:具体元素角色,实现被访问的操作;
- ObjectStructure:结构对象角色,包含一个具体元素的引用的容器;
2. 访问者模式案例
定义一个抽象访问者类和一个抽象元素类
1. class Element; 2. 3. class Visitor //抽象访问者 4. { 5. public: 6. virtual void visit(Element* e) = 0; 7. }; 8. 9. class Element //抽象元素 10. { 11. public: 12. virtual void reception(Visitor* v) = 0; 13. virtual string get_name() = 0; 14. };
以领导访问公司部门为例,创建两个公司部门
1. class Department1 : public Element //部门1 2. { 3. public: 4. virtual void reception(Visitor* v) 5. { 6. v->visit(this); 7. } 8. virtual string get_name() 9. { 10. return "第一事业部"; 11. } 12. }; 13. 14. class Department2 : public Element //部门2 15. { 16. public: 17. virtual void reception(Visitor* v) 18. { 19. v->visit(this); 20. } 21. string get_name() 22. { 23. return "第二事业部"; 24. } 25. };
创建访问者,董事长和部门分管领导
1. class President : public Visitor //董事长 2. { 3. public: 4. virtual void visit(Element* e) 5. { 6. cout << "董事长访问:" << e->get_name() << endl; 7. } 8. }; 9. 10. class Leader1 : public Visitor //分管领导1 11. { 12. public: 13. virtual void visit(Element* e) 14. { 15. cout << "第一分管领导访问:" << e->get_name() << endl; 16. } 17. }; 18. 19. class Leader2 : public Visitor //分管领导2 20. { 21. public: 22. virtual void visit(Element* e) 23. { 24. cout << "第二分管领导访问:" << e->get_name() << endl; 25. } 26. };
首先在客户端实现,分管部门的领导对自己的部门进行访问
1. { 2. v1 = new Leader1; 3. v2 = new Leader2; 4. 5. e1 = new Department1; 6. e2 = new Department2; 7. 8. e1->reception(v1); 9. e2->reception(v2); 10. }
然后我们在客户端增加操作,假设董事长要来视察,因为董事长职位最大,可以对整个公司进行访问,这是可以创建一个结构对象角色,把所有的部门都包含进来
1. class Group : public Element //整个集团 2. { 3. private: 4. list<Element*> l; 5. public: 6. virtual void reception(Visitor* v) 7. { 8. for (list<Element*>::iterator it = l.begin(); it != l.end(); it++) 9. { 10. (*it)->reception(v); 11. } 12. } 13. void add_element(Element* e) 14. { 15. l.push_back(e); 16. } 17. virtual string get_name() 18. { 19. return "整个集团公司"; 20. } 21. };
然后在客户端进行操作,首先把各个部门对象加入到集团公司对象中,然后董事长进行访问
1. { 2. v = new President; 3. 4. e = new Group; 5. e1 = new Department1; 6. e2 = new Department2; 7. 8. //组织集团架构 加入所有部门 9. e->add_element(e1); 10. e->add_element(e2); 11. 12. //董事长访问 13. e->reception(v); 14. }
二、状态模式
1. 什么是状态模式
State Pattern,状态模式,是一种行为型设计模式。通过改变对象的内部状态来达到改变对象行为的目的,“这个对象表现得就好像改变了它的类一样”。其实说白了就是,根据用户是输入的条件,满足一定条件就改变对象的行为,不同条件执行不同的操作。
- State:抽象状态,定义了一个接口,接口声明了一个与上下文环境相关的状态的行为;
- ConcreteState:具体状态,定义了本状态的行为和转换到另一个状态的判定条件;
- Context:上下文、环境,负责状态的转换,包含了一个表示当前状态的State类型的引用;
2. 状态模式案例
定义状态类
1. class State 2. { 3. public: 4. virtual void get_state(Machine* m) = 0; 5. }; 6. 7. class State1 : public State 8. { 9. public: 10. virtual void get_state(Machine* m); 11. }; 12. 13. class State2 : public State //状态2 14. { 15. public: 16. virtual void get_state(Machine* m); 17. };
实现状态对应行为
1. void State1::get_state(Machine* m) 2. { 3. if (m->get_flag() == 1) 4. { 5. //当前状态标志是1,则执行状态1 6. cout << "执行状态1" << endl; 7. } 8. else 9. { 10. //当前状态标志不是1,则切换为状态2 11. 12. //删除原来的状态 13. delete m->get_current(); 14. //把当前状态设置为状态2 15. m->set_flag(2); 16. m->set_current(new State2); 17. //执行状态 18. m->get_current()->get_state(m); 19. } 20. } 21. 22. void State2::get_state(Machine* m) 23. { 24. if (m->get_flag() == 2) 25. { 26. cout << "执行状态2" << endl; 27. } 28. else 29. { 30. //删除原状态 31. delete m->get_current(); 32. //设置新的当前状态 33. m->set_flag(1); 34. m->set_current(new State1); 35. //执行当前状态 36. m->get_current()->get_state(m); 37. } 38. }
定义一个Context类
1. class Machine 2. { 3. private: 4. State* current; //当前状态 5. int flag; //状态标志 6. public: 7. State* get_current() 8. { 9. return this->current; 10. } 11. void set_current(State* s) 12. { 13. this->current = s; 14. } 15. void set_flag(int flag) 16. { 17. this->flag = flag; 18. } 19. void execute_state() 20. { 21. current->get_state(this); 22. } 23. int get_flag() 24. { 25. return flag; 26. } 27. };
客户端实现状态行为的执行和转换
1. int main() 2. { 3. Machine* m = NULL; 4. State* s = NULL; 5. 6. m = new Machine; 7. 8. cout << "======初始状态======" << endl; 9. //初始化为状态1 10. s = new State1; 11. m->set_flag(1); 12. m->set_current(s); 13. m->execute_state(); 14. 15. cout << "======切换为状态2======" << endl; 16. //切换为状态2 17. m->set_flag(2); 18. m->execute_state(); 19. 20. cout << "======切换为状态1======" << endl; 21. //切换为状态1 22. m->set_flag(1); 23. m->execute_state(); 24. 25. delete s; 26. delete m; 27. 28. system("pause"); 29. return 0; 30. }