【设计模式学习笔记】模板模式、命令模式、责任链模式、策略模式案例详解(C++实现)

目录

一、模板模式

1. 什么是模板模式

2. 模板模式的案例

二、命令模式

1. 什么是命令模式

2. 命令模式的案例

三、责任链模式

1.什么是责任链模式

2. 责任链模式案例

四、策略模式

1. 什么是策略模式

2. 策略模式的案例


一、模板模式

1. 什么是模板模式

Template Pattern,模板方法模式,是一种行为型模式。通过模板模式可以把特定步骤的算法接口定义在抽象基类中,通过子类继承对抽象算法进行不同的实现来达到改变算法行为的目的。通俗来讲就是,在抽象类中定义好算法步骤并统一接口,在子类中实现接口,这就实现了算法操作步骤和算法实现的解耦合。模板模式一般应用于,具有同样的操作步骤,但是这些操作的细节不同的场景。

  • AbstractClass:定义了算法的框架和步骤;
  • ConcreteClass:实现AbstractClass中的方法;

 2. 模板模式的案例

我们把穿衣服看做一个固定流程,先穿外套,再穿裤子,最后穿鞋

class WearClothes //穿衣服
{
public:
	virtual void wear_coat() = 0;
	virtual void wear_pants() = 0;
	virtual void wear_shoe() = 0;
public:
	void wear_order() //穿衣服的顺序已经提前确定好了---模板
	{
		wear_coat(); //先穿外套
		wear_pants(); //再穿裤子
		wear_shoe(); //最后穿鞋
	}
};

 然后定义穿睡衣,穿西装两个类,穿衣服的顺序都是固定的,但是穿的衣服有所不同

class WearSuit : public WearClothes //穿西装
{
	virtual void wear_coat()
	{
		cout << "穿西服外套" << endl;
	}
	virtual void wear_pants()
	{
		cout << "穿西服裤子" << endl;
	}
	virtual void wear_shoe()
	{
		cout << "穿小皮鞋" << endl;
	}
};

class WearPajamas : public WearClothes //穿睡衣
{
	virtual void wear_coat()
	{
		cout << "穿睡衣" << endl;
	}
	virtual void wear_pants()
	{
		cout << "穿睡裤" << endl;
	}
	virtual void wear_shoe()
	{
		cout << "穿拖鞋" << endl;
	}
};

最后客户端执行穿衣服操作

int main()
{
	WearClothes* wear = NULL;

	//穿西装应酬
	wear = new WearSuit;
	wear->wear_order();
	delete wear;

	//穿睡衣睡觉
	wear = new WearPajamas;
	wear->wear_order();
	delete wear;

	system("pause");
	return 0;
}

 二、命令模式

1. 什么是命令模式

Command Pattern,命令模式,是一种行为型设计模式。命令模式就是把命令对象、命令的创建者、命令的调用者、命令的执行者(接收者)分离,首先看一个命令模式中的四个角色:

  • Command:抽象命令,定义了操作的接口,把命令封装成一个类,通过继承在ConcreteCommand中来实现具体的命令操作;
  • ConcreteCommand:具体命令,实现抽象命令的接口,是被命令调用者Invoker调用的主体,并且包含了一个对命令接收者Receiver的引用;
  • Receiver:命令的执行者,收到命令后执行相应的操作;
  • Invoker:命令的调用者,客户创建命令,并通过Incoker去调用命令,Invoker包含了对Command的引用,并负责去调用命令中的操作;

 2. 命令模式的案例

以办理银行业务为例,首先创建一个银行职员作为命令接收者,他可以执行存款取款操作。

//Receiver
class Banker
{
public:
	void saving_money()
	{
		cout << "办理存款业务" << endl;
	}
	void withdraw_money()
	{
		cout << "办理取款业务" << endl;
	}
};

 创建一个命令抽象类,并通过继承实现一个存款命令类和一个取款命令类,这两个具体命令方法分别可以调用命令执行者的存款操作和取款操作。

class Command
{
public:
	virtual void conduct_business() = 0;
};

class SaveCommand : public Command
{
private:
	Banker* bker;
public:
	SaveCommand(Banker* bker)
	{
		this->bker = bker;
	}
	virtual void conduct_business()
	{
		this->bker->saving_money();
	}
};

class WithdrowCommand : public Command
{
private:
	Banker* bker;
public:
	WithdrowCommand(Banker* bker)
	{
		this->bker = bker;
	}
	virtual void conduct_business()
	{
		this->bker->withdraw_money();
	}
};

创建一个命令调用者,它可以调用命令对象(命令调用者Invoker中包含了命令Command的引用,它可以调用命令,而具体命令ConcreteCommand中包含了命令接收者Receiver的引用,具体命令可以调用Receiver的操作,客户通过命令调用者Invoker来命令Receiver进行相应操作)。

//Invoker
class Manager
{
private:
	Command* com;
public:
	Manager(Command* com)
	{
		this->com = com;
	}
	void order()
	{
		com->conduct_business();
	}
};

最后客户端创建命令,并通过Invoker来调用命令,使Receiver执行相应操作

int main()
{
	Manager* m = NULL;
	Command* com = NULL;
	Banker* bker = NULL;

	bker = new Banker;
	com = new SaveCommand(bker); //存款命令
	m = new Manager(com);
	m->order();

	delete com;
	delete m;
	com = new WithdrowCommand(bker); //取款命令
	m = new Manager(com);
	m->order();

	delete m;
	delete com;
	delete bker;

	system("pause");
	return 0;
}

 三、责任链模式

1.什么是责任链模式

Chain of Responsibility Pattern,CoR责任链模式,是行为型设计模式之一。责任链模式就像一个链表,将对象连成一个链式结构,并沿着这条链传递请求,直到请求被某个对象处理。在责任链模式中,客户端只要把请求放到对象链上即可,不需关心请求的传递过程和处理细节,实现了请求发送和请求处理的解耦合。 

  • Handler:抽象处理者,定义了处理请求的接口,并包含一个指向下一个对象的指针;
  • ConcreteHandler:具体处理者,负责处理请求或把请求沿着对象链传递给下一个具体处理者;

 2. 责任链模式案例

定义抽象处理者和具体处理者

class Handler
{
protected: //供子类使用
	Handler* next;
public:
	virtual void perform_task() = 0; //统一的任务接口
	Handler* set_next(Handler* next) //设置下一个要执行的任务
	{
		this->next = next;
		return this->next;
	}
};

class Task1 : public Handler
{
public:
	virtual void perform_task()
	{
		cout << "任务 1 执行" << endl;
		if (next != NULL) //如果有下一个任务,则执行
		{
			next->perform_task();
		}
	}
};

class Task2 : public Handler
{
public:
	virtual void perform_task()
	{
		cout << "任务 2 执行" << endl;
		if (next != NULL)
		{
			next->perform_task();
		}
	}
};

class Task3 : public Handler
{
public:
	virtual void perform_task()
	{
		cout << "任务 3 执行" << endl;
		if (next != NULL)
		{
			next->perform_task();
		}
	}
};

客户端发出请求

int main()
{
	Handler* task1 = NULL;
	Handler* task2 = NULL;
	Handler* task3 = NULL;

	task1 = new Task1;
	task2 = new Task2;
	task3 = new Task3;

	//任务流程:task1 -> task2 -> task3 -> 结束
	cout << "任务流程:task1 -> task2 -> task3 -> 结束" << endl;
	task1->set_next(task2);
	task2->set_next(task3);
	task3->set_next(NULL);

	task1->perform_task();
	cout << "===================================" << endl;

	//改变流程
	cout << "任务流程:task3 -> task2 -> task1 -> 结束" << endl;
	task1->set_next(NULL);
	task2->set_next(task1);
	task3->set_next(task2);

	task3->perform_task();
	cout << "===================================" << endl;

	delete task3;
	delete task2;
	delete task1;

	system("pause");
	return 0;
}

四、策略模式

1. 什么是策略模式

Strategy Pattern,策略模式,行为型模式之一。策略模式可以定义一个算法族,把一系列算法封装起来并提供一个统一接口,这样算法之间的切换或其他变化不会影响客户端。其关键在于,把算法的抽象接口封装在一个类中,算法的实现由具体策略类来实现,,而算法的选择由客户端决定。

  • Strategy:抽象策略类,定义算法族的统一接口;
  • ConcreteStrategy:具体策略类,实现了具体的算法操作;
  • Context:上下文,包含一个策略类的引用,根据不同策略执行不同操作,策略的选择由客户端决定;

 2. 策略模式的案例

定义一个排序算法策略

class Strategy //策略
{
public:
	virtual void sort() = 0;
};

class SelectSort : public Strategy
{
public:
	virtual void sort()
	{
		cout << "选择排序算法" << endl;
	}
};

class InsertSort : public Strategy
{
public:
	virtual void sort()
	{
		cout << "插入排序算法" << endl;
	}
};

定义上下文

class Context
{
private:
	Strategy* m_strategy;
public:
	void set_strategy(Strategy* m_strategy)
	{
		this->m_strategy = m_strategy;
	}
	void execute_strategy()
	{
		this->m_strategy->sort();
	}
};

客户端选择具体排序算法

int main()
{
	Strategy* s1 = NULL;
	Context* c = NULL;

	c = new Context;

	cout << "========================" << endl;
	//使用选择排序算法进行排序
	cout << "使用选择排序算法进行排序" << endl;
	s1 = new SelectSort;
	c->set_strategy(s1);
	c->execute_strategy();
	delete s1;
	cout << "========================" << endl;

	cout << "使用插入排序算法进行排序" << endl;
	s1 = new InsertSort;
	c->set_strategy(s1);
	c->execute_strategy();
	delete s1;
	delete c;
	cout << "========================" << endl;

	system("pause");
	return 0;
}

posted @ 2022-04-21 12:00  Mindtechnist  阅读(44)  评论(0编辑  收藏  举报  来源