设计模式 | 访问者模式、状态模式

举报
mindtechnist 发表于 2023/05/11 14:39:07 2023/05/11
【摘要】 目录一、访问者模式1. 什么是访问者模式2. 访问者模式案例二、状态模式1. 什么是状态模式2. 状态模式案例一、访问者模式1. 什么是访问者模式Visitor Pattern,访问者模式,是一种行为型设计模式。访问者模式把数据结构和作用于数据结构上的操作进行了分离,在不修改已有类的前提下可以增加新的操作,而新增新的操作就相当于新增一个访问者。Visitor:抽象访问者角色,声明了访问操作的...

目录

一、访问者模式

1. 什么是访问者模式

2. 访问者模式案例

二、状态模式

1. 什么是状态模式

2. 状态模式案例


一、访问者模式

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;
}

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。