设计模式笔记-Chain of Responsibility职责链模式

这个模式我觉得是很简单的--单例模式还有很多陷阱呢,职责链模式在你了解了使用场景以及它的实现之后,一切都是顺理成章的事。

请假--大家都举这个例子,3天以内组长批,3-7天部门经理批,7天以上总经理批。请假的人只管把假条交上就行了,批假的处理不用管,这就实现了请求和处理的解耦(这话怎么好多模式都这么说)。在实现上就是,要在处理类中组合一个上一级的对象指针就行了,自己处理不了交给它处理。该模式的好处还有:请求者不用和每一层上级都建立联系,这个就是解耦了;如果想跳级,找更高级的处理,通过动态指定处理类及后继者就行了,不用每次从头(组长)开始,这也体现了该模式的一个缺点:很多情况下,链开始部分的处理类只是进行任务的传递,这些垃圾对象的申请浪费了内存。

设计模式笔记-Chain of Responsibility职责链模式_第1张图片

实现代码如下:

class Request {
private:
	int day;
public:
	Request(int d): day(d){}
	void SetDay(int d) { day = d; }
	int getDay() { return day; }
};

class Manager {
public:
	virtual bool HandleRequest(Request) = 0;
protected:
	Manager* _successor;
};

class  LeaderManager :public Manager {
public:
	LeaderManager(Manager* m) { _successor = m; }
	bool HandleRequest(Request) ;
};

class	DepartmentManager :public Manager {
public:
	DepartmentManager(Manager* m) { _successor = m; }
	bool HandleRequest(Request) ;
};

class TopManager :public Manager {
public:
	TopManager(Manager* m) { _successor = m; }
	bool HandleRequest(Request);
};
bool LeaderManager::HandleRequest(Request req)
{
	if (req.getDay() <= 3)
	{
		cout << "Leader handled!" << endl;
		return true;
	}
	return _successor->HandleRequest(req);
}

bool DepartmentManager::HandleRequest(Request req)
{
	int day = req.getDay();
	if (/*day > 3 && */day <=7) //不能加大于3的判断,部门经理当然可以直接处理3天以内的
	{
		cout << "Department Manager handled!" << endl;
		return true;
	}
	return _successor->HandleRequest(req);
}

bool TopManager::HandleRequest(Request req)
{
	cout << "Top Manager handled!" << endl;
	return true;
}
int main()
{
	Manager *top = new TopManager(NULL);
	Manager * department = new DepartmentManager(top);
	Manager * leader = new LeaderManager(department);

	Request req(15);
	//req.SetDay(3);
	leader->HandleRequest(req);
	return 0;
}
职责链会有很多误用,比如项目中用SQL Server, DB2, Oracle3种方式连接数据库,如果你是想通过用户传参数决定用哪种数据库,那用职责链就很不好,用工厂模式或驱动表比较好;如果你的逻辑是,如果一个数据库连接不成功,换下一个,还可以考虑该模式,当然这也不是个好方法。上面请假是个好例子。





你可能感兴趣的:(设计模式)