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