设计模式-外观模式C++

一、简介

外观模式(Facade Pattern)隐藏系统的复杂性,并向客户端提供了一个客户端可以访问系统的接口。这种类型的设计模式属于结构型模式,它向现有的系统添加一个接口,来隐藏系统的复杂性。

这种模式涉及到一个单一的类,该类提供了客户端请求的简化方法和对现有系统类方法的委托调用。

我们可以将这个类看作是复杂系统的外观,对客户端提供调用系统实现某种功能的接口,而如何调用(对系统接口的调用顺序和调用依赖)不对客户端展示,由外观类自己处理。

二、外观模式实例

我们知道新生入学是十分麻烦的事情,需要办理各种手续,甚至可以让学生和家长忙碌一整天。假如某院校提供一批接待人员帮助新生办理新生入学事务,而新生只需要提供本人身份信息给接待人员即可。

在这个事例中,新生入学系统就是一个复杂的系统;新生是客户端;接待人员可以看做入学系统的外观。

下面用代码来体现

1)复杂系统-入学系统的基类

class AdmissionSystem
{
public:
	AdmissionSystem() {}
	virtual ~AdmissionSystem() {}

	void GetStudentID()
	{
		cout << "领取学生证" << endl;
	}

	void ConfirmDormitory()
	{
		cout << "确认宿舍+床位号" << endl;
	}

	void GetTextBook()
	{
		cout << "领取教材" << endl;
	}

	virtual void ConfirmClass() = 0;
};

2)复杂系统的子系统-各个学院的入学系统

子系统可能存在不同的执行步骤、不同的功能和不同的依赖

//理学院入学系统
class FacultyOfScience : public AdmissionSystem
{
public:
	void ConfirmClass()
	{
		cout << "进入理学院:确认学生班级" << endl;
	}
};

//工学院入学系统
class FacultyOfEngineering : public AdmissionSystem
{
public:
	void ConfirmClass()
	{
		cout << "进入工学院:确认学生班级" << endl;
	}

	void GetComputer()
	{
		cout << "领取电脑" << endl;
	}
};

//艺术学院入学系统
class FacultyOfArt : public AdmissionSystem
{
public:
	void ConfirmClass()
	{
		cout << "进入艺术学院:确认学生班级" << endl;
	}

	void ConfirmActivityRoom()
	{
		cout << "确认学生活动室" << endl;
	}
};

3)外观模式的重点-外观类:入学系统的接待人员

//接待人员
class AdmissionSystemHandlers
{
public:
	AdmissionSystemHandlers()
	{
		_scienceHandler = new FacultyOfScience();
		_engineerHandler = new FacultyOfEngineering();
		_artHandler = new FacultyOfArt();
	}

	~AdmissionSystemHandlers()
	{
		delete _scienceHandler;
		delete _engineerHandler;
		delete _artHandler;

		_scienceHandler = nullptr;
		_engineerHandler = nullptr;
		_artHandler = nullptr;
	}

	//入学理学院
	void ScienceAdmission()
	{
		if (nullptr == _scienceHandler)
		{
			cout << "不存在接待人员" << endl;
			return;
		}

		_scienceHandler->GetStudentID();
		_scienceHandler->ConfirmClass();
		_scienceHandler->ConfirmDormitory();
		_scienceHandler->GetTextBook();
	}

	//入学工学院
	void EngineerAdmission()
	{
		if (nullptr == _engineerHandler)
		{
			cout << "不存在接待人员" << endl;
			return;
		}

		_engineerHandler->GetStudentID();
		_engineerHandler->ConfirmClass();
		_engineerHandler->ConfirmDormitory();
		_engineerHandler->GetTextBook();
		_engineerHandler->GetComputer();
	}

	//入学艺术学院
	void ArtAdmission()
	{
		if (nullptr == _artHandler)
		{
			cout << "不存在接待人员" << endl;
			return;
		}

		_artHandler->GetStudentID();
		_artHandler->ConfirmClass();
		_artHandler->ConfirmDormitory();
		_artHandler->GetTextBook();
		_artHandler->ConfirmActivityRoom();
	}

private:
	FacultyOfScience* _scienceHandler;
	FacultyOfEngineering* _engineerHandler;
	FacultyOfArt* _artHandler;
};

4)使用

int main(int argc, char *argv[])
{
	AdmissionSystemHandlers hander;
	//学生甲:入学理学院
	cout << "学生甲申请入学理学院" << endl;
	hander.ScienceAdmission();
	cout << endl;
	//学生乙:入学艺术学院
	cout << "学生乙申请入学艺术学院" << endl;
	hander.ArtAdmission();
	system("pause");
	return 0;
}

5)输出

三、总结

从上述实例可以看见,对于客户端(学生)来说,只要知道想要实现的功能(入学某某学院),就可以从外观类(入学系统接待人员)处一键获取结果。而客户端不需要知道如何使用这个复杂系统是才能实现这个功能,因为这部分工作都由外观类来完成。

这样,我们降低了客户端和系统的耦合性,不容易出错,对客户端使用系统更加友好。

但是它也存在缺点,即外观模式不符合开闭原则。如何需要新增对客户端提供的功能,需要修改外观类,而如果需要新增实现某个功能的步骤和逻辑,也要对现有接口进行修改。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值