在软件构建过程种,对于某一项任务,它常常有稳定的整体操作结构,但各个子步骤却有很多改变的需求,或者由于固有原因(比如框架与应用之间的关系)而无法和任务的整体结构同时实现。

模板模式要做的就是在确定稳定操作结构的前提下,来灵活应对各个滋补粥的变化或者晚期的实现需求。

这里还是举一个笔者自己项目的一个例子:

一个远控软件。服务端在进行一系列操作之后(初始化套接字、网卡、bind、listen),客户端connect之后会创建一个连接,我们称之为主连接。主连接专门用来创建子连接,这里的子连接指不同子功能(文件管理,CMD管理、窗口管理等)所需的连接。这个过程的整体流程如下图所示。

step1,构建主连接。

step2,服务端那边点击了某一功能(以文件管理为例),向肉鸡发送消息,说要构建子连接。

step3,肉鸡这边创建一个线程,用于文件管理的数据传输以及处理。

step4,调用connect函数与服务端构建子连接。

step5,服务端这边调用accept函数,会生成一个socket用于这个子连接通信。

step6,传输一些初始化数据,用于显示在新的对话框种。

step7,服务端创建对话框,并展示数据。

step8,肉鸡创建一个Manager对象,处理服务端到来的数据,因为功能很多(删除文件,新建文件,传输文件)要针对不同功能进行处理,服务端创建的新对话框也有这个功能。注意678并没有什么先后顺序。

step9,两者之间传输数据(construct构建数据包,send发送数据包,destruct拆解数据包,recv接收数据包)。

step10 step11,主对话框拆解数据包,根据完成端口completion key参数去到对应的文件管理对话框中处理。

step12,肉鸡去对应的manager对象处理。

我们来看看上边九个步骤。可以定义出两个模板

class ServerDeal {
	void CreateNewConnection();
	virtual void Click();
	void Accept();
	virtual void Construct();
	virtual void Destruct();
	void Send();
	void Recv();
	virtual void CreateDialog();
};
void ServerDeal::CreateNewConnection()
{
	Click();//点击一个功能,准备打开相应对话框,这是一个虚函数,变化部分。

	Accept();//从全连接队列中取出该连接,正常函数,不变部分。
	CreateDialog();//创建对话框,虚函数,变化部分
	while (1)
	{
		Construct();//构建数据包,虚函数,变化部分
		Send();//发送数据,普通函数,不变部分

		Recv();//接收数据,普通函数,不变部分
		Destruct();;//解析数据包,虚函数,变化部分
	}

}

class ClientDeal {
	void CreateNewConnection();
	virtual void CreateThread();
	void Connect();
	virtual void Construct();
	virtual void Destruct();
	void Send();
	void Recv();
	virtual void CreateManager();
};

void ClientDeal::CreateNewConnection()
{
	Recv();//接收服务端Click发来的数据,普通函数,不变部分。
	CreateThread();//创建新线程,虚函数,变化部分。
	Connect();//新连接,普通函数,不变部分。

	Send();//传输一些初始数据,普通函数,不变部分。
	CreateManager();//创建Manager对象,虚函数,变化部分。

	while (1)
	{
		Construct();//构建数据包,虚函数,变化部分
		Send();//发送数据,普通函数,不变部分

		Recv();//接收数据,普通函数,不变部分
		Destruct();;//解析数据包,虚函数,变化部分
	}
}

上述代码只是个伪代码,其中细节并没有在这展开。将整体的流程封装成了一个类或者一个函数,包含不变部分(普通函数)以及变化部分(虚函数)。虚函数提供接口以给特定的功能定义自身特有的处理逻辑。

有了这个模板会有什么好处。因为针对所有的具体功能,创建子连接都是这个过程,把这个流程定义在这个类里边,具体功能直接调用这个函数即可,而不需要针对每个具体功能再写一次这个业务逻辑,这就是模板的思想。

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐