ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

设计模式,门面模式,c++实现,委托,c++实现委托

2021-10-16 22:02:30  阅读:150  来源: 互联网

标签:功能 Handle 委托 Drink c++ 门面 设计模式 子系统 mDrink


委托:类a将功能委托类b实现
翻译:在类a中包含一个功能类b指针或对象,用到b功能类的功能时通过其指针或者对象调用b的功能,在调用模块看来,问题是交给类a解决了,而实际上,类a通过其成员类b对象或指针解决的该问题,此过程为“a委托b完成了问题”。
顺便一提:a依赖b指的是a类中包含一个b的基类的指针,就不一定是基类对象了,因为基类可能就是虚基类,产生不了对象。

门面模式:或叫外观模式(是前台吗?来杯咖啡。)

定义:将一个子系统的外部与内部的通信必须通过一个统一的对象进行。

翻译
子系统:由一个或多个功能类组成,一般是一群功能类组成,对某个或某些业务进行一系列处理后实现了一个服务内容。

统一的对象(门面):一个类,
该类中依赖(包含功能类基类)或关联(包含功能类子类)了子系统中调用到的所有功能类,
该类对外只提供一个接口(只有一个public函数,剩下的数据或函数访问权限都不是public),代表外部可调用的服务;
在这个对外开放的接口函数中,需要对完成对所有子系统中功能类的调用以达到需求,
当需求改变时,内部依赖或关联的功能类与调用逻辑按照需求扩展,该类提供的服务接口函数保持不变,

作用
使功能类和高层调用模块解耦,减少系统的相互依赖,
外界访问到子系统内部便会强耦合,低内聚,维护困难;
外界访问门面类的一个服务接口就能弱耦合,高内聚,内部扩展方便,
对调用者毫无影响,因为对外接口没变化。

优点
减少依赖,降低耦合,主要是调用模块和子系统功能类之间的依赖和耦合。
使用灵活,门面接口不变,子系统自由活动。
安全,不在门面上开通的方法外部访问不到。

缺点
不符合开闭原则,对修改关闭,对扩展开放,在系统投产后发现有需要修复的错误时,只能修改门面的代码,继承覆写都不顶用,所以,设计时要慎之又慎。

使用场景
为一个复杂的模块或子系统提供一个供外界访问的借口。
子系统相对独立,对外部而言是黑盒,例如:计算利息,计算健康分数,计算综合分数等。
预防低水平人员带来的风险扩散,项目开发中的低水平技术人员容易因个人代码质量影响整体项目,故需规定其在指定的子系统中开发,然后再提供接口进行访问操作。

一个子系统有多个门面的场景
门面大到不能忍:代码超过200行就建议拆分。
子系统有不同访问路径:等级不同,权限不同,资源不同等,就可以给门面进行扩展(继承或代理)。

注意点
门面类不应该参与业务逻辑。
原因:门面类封装了服务并且时直接对外开放调用的,这要求门面类的稳定,稳定就是少修改,
倘若门面类对外开放的接口中有业务逻辑的组成部分,比如先调用a功能,然后b功能,然后c功能,业务改变时,门面就要相应的改,业务逻辑依赖于门面类,导致门面类不稳定。
避免门面类参与业务逻辑的方法:
子系统中不仅要有功能类实现功能,还要有业务逻辑类组合功能形成完整业务并提供该业务接口,门面类使用业务逻辑类提供的接口向外界提供服务,通过在子系统中增加业务逻辑类,使门面类与业务逻辑解耦,只负责向外界提供服务接口,并将外界需求委托给业务逻辑类。

代码示例:前台不生产咖啡,只是咖啡的搬运工,并将生产咖啡的任务委托给了厨房

//饮料类
class Drink
{
public:
	Drink()
	{
		kind = 0;
	}

	Drink(int value)
	{
		kind = value;
	}

	void get()
	{
		if (kind < 2)
		{
			cout << "一杯凉茶" << "准备好了" << endl;
		}
		else if (kind < 4)
		{
			cout << "一杯奶" << "准备好了" << endl;
		}
		else if (kind < 6)
		{
			cout << "一杯咖啡" << "准备好了" << endl;
		}
		else
		{
			cout << "一杯饮料" << "准备好了" << endl;
		}
	}

	int GetKind()
	{
		return kind;
	}

protected:
	int kind;
};

//厨房员工
class WaterPullIn
{
public:
	Drink* Handle(Drink* drink)
	{
		return (new Drink(drink->GetKind() + 1));
	}
};

//厨房员工
class SugarPullIn
{
public:
	Drink* Handle(Drink* drink)
	{
		return (new Drink(drink->GetKind() + 1));
	}
};

//厨房员工
class MilkPullIn
{
public:
	Drink* Handle(Drink* drink)
	{
		return (new Drink(drink->GetKind() + 1));
	}
};

//厨房员工
class CoffeeBeanPullIn
{
public:
	Drink* Handle(Drink* drink)
	{
		return (new Drink(drink->GetKind() + 1));
	}
};

//厨房类,包含了所有厨房员工,并提供饮品供应服务
class Kitchen
{
public:
	Drink* GetCoffee()
	{
		mDrink = new Drink();
		mDrink = mWaterPullIn->Handle(mDrink);
		mDrink = mSugarPullIn->Handle(mDrink);
		mDrink = mMilkPullIn->Handle(mDrink);
		mDrink = mCoffeeBeanPullIn->Handle(mDrink);
		return mDrink;
	}

	Drink* GetMilk()
	{
		mDrink = new Drink();
		mDrink = mWaterPullIn->Handle(mDrink);
		mDrink = mMilkPullIn->Handle(mDrink);
		return mDrink;
	}

	Drink* GetCooltea()
	{
		mDrink = new Drink();
		mDrink = mWaterPullIn->Handle(mDrink);
		return mDrink;
	}

protected:
	Drink* mDrink;
	WaterPullIn* mWaterPullIn;
	SugarPullIn* mSugarPullIn;
	MilkPullIn* mMilkPullIn;
	CoffeeBeanPullIn* mCoffeeBeanPullIn;
};

//前台类,也就是门面类
class Stage
{
public:
	void SetKitchen(Kitchen* kitchen)
	{
		mKitchen = kitchen;
	}

	Drink* GetCoffee()
	{
		return mKitchen->GetCoffee();
	}

protected:
	Kitchen* mKitchen;
};

void func()
{
	Kitchen* WaiBao = new Kitchen();
	Stage* HotelStage = new Stage();
	HotelStage->SetKitchen(WaiBao);

	//在前台点一杯咖啡
	Drink* Coffee = HotelStage->GetCoffee();
	Coffee->get();
}

int main()
{
	func();
	return 0;
}

在这里插入图片描述
运行结果正确,在这次代码中,门面类Stage接收了客户想要咖啡的请求,但并没有去做咖啡,而是将该服务委托给了厨房Kitchen,厨房类中包含了制作饮品的功能类,WaterPullIn,SugarPullIn,milkPullIn,CoffeeBeanPullIn,厨房通过调用这些功能类实现了对业务逻辑“做咖啡”的维护,并维护其他几个饮料提供服务,与功能类共同组成了门面类的子系统,门面类不参与功能以及业务,只是好好负责接活和委托,在调用模块客户看来,这个门面系统是相当稳定且简单的。

标签:功能,Handle,委托,Drink,c++,门面,设计模式,子系统,mDrink
来源: https://blog.csdn.net/ganfanren00001/article/details/120804068

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有