Loading... >> 隔离接口,通过中间层来减少两层之间的耦合性 目的:隔离接口——中间层。迪米特法则 门面模式原理和实现都特别简单,应用场景也比较明确,主要在接口设计方面使用。 >> > > # 一、门面模式的原理与实现 > > 门面模式,也叫外观模式,英文全称是 Facade Design Pattern。 > > Provide a unified interface to a set of interfaces in a subsystem. Facade Pattern defines a higher-level interface that makes the subsystem easier to use. > > 翻译成中文就是:门面模式为子系统提供一组统一的接口,定义一组高层接口让子系统更易用。 > > ## 1、门面模式的应用场景举例 > > 在 GoF 给出的定义中提到,“门面模式让子系统更加易用”,实际上,它除了解决易用性问题之外,还能解决其他很多方面的问题。关于这一点,我总结罗列了 3 个常用的应用场景,你可以参考一下,举一反三地借鉴到自己的项目中。 > > ### 1.1、 解决易用性问题 > > 实际上,从隐藏实现复杂性,提供更易用接口这个意图来看,门面模式有点类似之前讲到的迪米特法则(最少知识原则)和接口隔离原则:两个有交互的系统,只暴露有限的必要的接口。除此之外,门面模式还有点类似之前提到封装、抽象的设计思想,提供更抽象的接口,封装底层实现细节。 > > 就好比客户端要访问不同的业务处理,直接调用业务类代码使得代码编写的复杂度上升,其实业务层完全可以将这些业务处理进行封装,提供一些简单的调用接口,从而减少复杂性 > > ### 1.2、 解决性能问题 > > 如果门面接口不多,我们完全可以将它跟非门面接口放到一块,也不需要特殊标记,当作普通接口来用即可。如果门面接口很多,我们可以在已有的接口之上,再重新抽象出一层,专门放置门面接口,从类、包的命名上跟原来的接口层做区分。如果门面接口特别多,并且很多都是跨多个子系统的,我们可以将门面接口放到一个新的子系统中。 > > ### 1.3、关于粒度的讨论 > > 接口粒度设计得太大,太小都不好。太大会导致接口不可复用,太小会导致接口不易用。在实际的开发中,接口的可复用性和易用性需要“微妙”的权衡。针对这个问题,我的一个基本的处理原则是,尽量保持接口的可复用性,但针对特殊情况,允许提供冗余的门面接口,来提供更易用的接口。 > > # 二、一个配置相关的范例 > > ## 1、引入外观(facade)模式 > > graphic、sound、chatvoice——业务类 conffacade 外观模式强调的是一种程序设计思想 **外观模式体现了面向对象程序设计的一个原则——迪米特法则**(Law of Demeter,简称LoD)。 得墨忒耳法则或者最小知识原则(Least Knowledge Principle,简称LKP): 一个对象应该对其他对象尽可能少的了解,从而降低各个对象之间的耦合,提高系统可维护性。 > > 外观设计模式的定义(实现意图):提供了一个统一的接口,用来访问子系统中的一群接口。外观定义了一个高层接口,让子系统更容易使用。 **外观模式为客户端和子系统之间提供了一种简化的交互渠道但是 并没有为子系统增加新的行为**。如果希望增加新行为,应该通过修改子系统角色(业务类)来实现。 > > 改进前: > > ```cpp > //图形相关类 > class graphic > { > //-------------单件类实现相关begin-------------- > private: > graphic() {}; > graphic(const graphic& tmpobj); > graphic& operator=(const graphic& tmpobj); > ~graphic() {}; > public: > static graphic& getInstance() > { > static graphic instance; > return instance; > } > //-------------单件类实现相关end-------------- > > public: > void display(bool enable) //是否全屏显示(true:是) > { > cout << "图形->是否全屏显示->" << enable << endl; > //其他代码略...... > } > void effect(bool enable) //是否开启特效(true:是) > { > cout << "图形->是否开启特效->" << enable << endl; > } > void resolution(int index) //设置窗口分辨率 > { > cout << "图形->分辨率设置选项->" << index << endl; > } > void antialiasing(bool enable)//是否开启抗锯齿(true:是) > { > cout << "图形->是否开启抗锯齿->" << enable << endl; > } > //....其他接口略 > }; > > //声音相关类 > class sound > { > //-------------单件类实现相关begin-------------- > private: > sound() {}; > sound(const sound& tmpobj); > sound& operator=(const sound& tmpobj); > ~sound() {}; > public: > static sound& getInstance() > { > static sound instance; > return instance; > } > //-------------单件类实现相关end-------------- > > public: > void bgsound(bool enable) //是否开启背景声音(true:是) > { > cout << "声音->是否开启背景声音->" << enable << endl; > } > void envirsound(bool enable) //是否开启环境音效(true:是) > { > cout << "声音->是否开启环境音效->" << enable << endl; > } > void expsound(bool enable) //是否开启表情声音(true:是) > { > cout << "声音->是否开启表情声音->" << enable << endl; > } > void setvolume(int level) //音量大小设置(0-100) > { > cout << "声音->音量大小为->" << level << endl; > } > //......其他接口略 > }; > > //语音聊天相关类 > class chatvoice > { > //-------------单件类实现相关begin-------------- > private: > chatvoice() {}; > chatvoice(const chatvoice& tmpobj); > chatvoice& operator=(const chatvoice& tmpobj); > ~chatvoice() {}; > public: > static chatvoice& getInstance() > { > static chatvoice instance; > return instance; > } > //-------------单件类实现相关end-------------- > > public: > void micvolume(int level) //麦克风音量大小设置(0-100) > { > cout << "语音聊天->麦克风音量大小为->" << level << endl; > } > void micsens(int level) //麦克风灵敏度设置(0-100) > { > cout << "语音聊天->麦克风灵敏度为->" << level << endl; > } > void chatvolume(int level) //聊天音量设置(0-100) > { > cout << "语音聊天->聊天音量为->" << level << endl; > } > //......其他接口略 > }; > > int main() > { > graphic& g_gp = graphic::getInstance(); > g_gp.display(false); > g_gp.effect(true); > g_gp.resolution(2); > g_gp.antialiasing(false); > > cout << "---------------" << endl; > sound& g_snd = sound::getInstance(); > g_snd.setvolume(80); > g_snd.envirsound(true); > g_snd.bgsound(false); > > cout << "---------------" << endl; > chatvoice& g_cv = chatvoice::getInstance(); > g_cv.chatvolume(70); > g_cv.micsens(65); > > return 0; > } > ``` > 客户端直接调用业务类的接口 > >  > > 使用外观模式后: > > ```cpp > > //图形相关类 > class graphic > { > //-------------单件类实现相关begin-------------- > private: > graphic() {}; > graphic(const graphic& tmpobj); > graphic& operator=(const graphic& tmpobj); > ~graphic() {}; > public: > static graphic& getInstance() > { > static graphic instance; > return instance; > } > //-------------单件类实现相关end-------------- > > public: > void display(bool enable) //是否全屏显示(true:是) > { > cout << "图形->是否全屏显示->" << enable << endl; > //其他代码略...... > } > void effect(bool enable) //是否开启特效(true:是) > { > cout << "图形->是否开启特效->" << enable << endl; > } > void resolution(int index) //设置窗口分辨率 > { > cout << "图形->分辨率设置选项->" << index << endl; > } > void antialiasing(bool enable)//是否开启抗锯齿(true:是) > { > cout << "图形->是否开启抗锯齿->" << enable << endl; > } > //....其他接口略 > }; > > //声音相关类 > class sound > { > //-------------单件类实现相关begin-------------- > private: > sound() {}; > sound(const sound& tmpobj); > sound& operator=(const sound& tmpobj); > ~sound() {}; > public: > static sound& getInstance() > { > static sound instance; > return instance; > } > //-------------单件类实现相关end-------------- > > public: > void bgsound(bool enable) //是否开启背景声音(true:是) > { > cout << "声音->是否开启背景声音->" << enable << endl; > } > void envirsound(bool enable) //是否开启环境音效(true:是) > { > cout << "声音->是否开启环境音效->" << enable << endl; > } > void expsound(bool enable) //是否开启表情声音(true:是) > { > cout << "声音->是否开启表情声音->" << enable << endl; > } > void setvolume(int level) //音量大小设置(0-100) > { > cout << "声音->音量大小为->" << level << endl; > } > //......其他接口略 > }; > > //语音聊天相关类 > class chatvoice > { > //-------------单件类实现相关begin-------------- > private: > chatvoice() {}; > chatvoice(const chatvoice& tmpobj); > chatvoice& operator=(const chatvoice& tmpobj); > ~chatvoice() {}; > public: > static chatvoice& getInstance() > { > static chatvoice instance; > return instance; > } > //-------------单件类实现相关end-------------- > > public: > void micvolume(int level) //麦克风音量大小设置(0-100) > { > cout << "语音聊天->麦克风音量大小为->" << level << endl; > } > void micsens(int level) //麦克风灵敏度设置(0-100) > { > cout << "语音聊天->麦克风灵敏度为->" << level << endl; > } > void chatvolume(int level) //聊天音量设置(0-100) > { > cout << "语音聊天->聊天音量为->" << level << endl; > } > //......其他接口略 > }; > //----------------------- > //扮演外观模式角色的类 > class conffacade > { > //-------------单件类实现相关begin-------------- > private: > conffacade() {}; > conffacade(const conffacade& tmpobj); > conffacade& operator=(const conffacade& tmpobj); > ~conffacade() {}; > public: > static conffacade& getInstance() > { > static conffacade instance; > return instance; > } > > public: > void LowConfComputer() //对于低配置电脑,只开启一些低配置选项 > { > graphic& g_gp = graphic::getInstance(); > g_gp.display(true); //全屏耗费资源更低 > g_gp.effect(false); > g_gp.resolution(2); > g_gp.antialiasing(false); > > sound& g_snd = sound::getInstance(); > g_snd.bgsound(false); > g_snd.envirsound(false); > g_snd.expsound(false); > g_snd.setvolume(15); > > chatvoice& g_cv = chatvoice::getInstance(); > g_cv.micvolume(20); > g_cv.micsens(50); > g_cv.chatvolume(60); > } > > void HighConfComputer() //对于高配置电脑,能达到最好效果的项全部开启 > { > graphic& g_gp = graphic::getInstance(); > g_gp.display(false); > g_gp.effect(true); > g_gp.resolution(0); > g_gp.antialiasing(true); > > sound& g_snd = sound::getInstance(); > g_snd.bgsound(true); > g_snd.envirsound(true); > g_snd.expsound(true); > g_snd.setvolume(50); > > chatvoice& g_cv = chatvoice::getInstance(); > g_cv.micvolume(100); > g_cv.micsens(100); > g_cv.chatvolume(100); > } > }; > > int main() > { > _nmsp1::conffacade& g_cffde = _nmsp1::conffacade::getInstance(); > cout << "低配置电脑,调用LowConfComputer接口" << endl; > g_cffde.LowConfComputer(); > > cout << "---------------------------" << endl; > cout << "高配置电脑,调用HighConfComputer接口" << endl; > g_cffde.HighConfComputer(); > > return 0; > } > ``` > 客户端不需要了解业务类内部的接口打交道,降低了耦合度。当子系统发生改变的时候,只需要改变coffacade类,不需要改变客户端的代码。 > > 外观模式包含2种角色 a)Facade(外观角色):conffacade b)Subsystem(子系统角色):graphic、sound、chatvoice——业务类 > >  > 最后修改:2025 年 07 月 01 日 © 允许规范转载 打赏 赞赏作者 支付宝微信 赞 如果觉得我的文章对你有用,请随意赞赏