IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 设计模式,门面模式,c++实现,委托,c++实现委托 -> 正文阅读

[C++知识库]设计模式,门面模式,c++实现,委托,c++实现委托

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

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

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

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

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

类图摘自设计模式之禅:越简单越不好理解呢
在这里插入图片描述

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

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

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

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

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

注意点
门面类不应该参与业务逻辑。
原因:门面类封装了服务并且时直接对外开放调用的,这要求门面类的稳定,稳定就是少修改,
倘若门面类对外开放的接口中有业务逻辑的组成部分,比如先调用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,厨房通过调用这些功能类实现了对业务逻辑“做咖啡”的维护,并维护其他几个饮料提供服务,与功能类共同组成了门面类的子系统,门面类不参与功能以及业务,只是好好负责接活和委托,在调用模块客户看来,这个门面系统是相当稳定且简单的。

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-10-17 11:49:20  更:2021-10-17 11:50:20 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 3:48:13-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码