当前位置: 首页 > 后端技术 > PHP

PHP设计模式的门面模式

时间:2023-03-30 03:38:57 PHP

门面模式,也叫外观模式。无论是立面还是外表,都是我们的外在媒介,就像我们的脸一样。所以这个模式最大的特点就是表演“好看”。怎么说?一堆复杂的对象调用,自己看不出来,尤其是老系统升级维护的时候。使用门面封装旧系统的函数调用,从外面看和新系统一样。这就是门面模式的目的!Gof类图及解释GoF定义:为子系统中的一组接口提供一致的接口。Facade模式定义了一个高级接口,使该子系统更易于使用。GoF类图代码实现类SubSystemOne{publicfunctionMethodOne(){echo'子系统方法一',PHP_EOL;}}classSubSystemTwo{publicfunctionMethodTwo(){echo'子系统方法二',PHP_EOL;}}classSubSystemThree{publicfunctionMethodThree(){echo'子系统方法三',PHP_EOL;}}classSubSystemFour{publicfunctionMethodFour(){echo'子系统方法四',PHP_EOL;}}定义四个或更多的子系统,这没什么好说的,可以想象有很多子系统,而且和这四个子系统不一定相似,有可能相差很大。门面类{private$subStytemOne;私人$subStytemTwo;私人$subStytemThree;私人$subStytemFour;公共函数__construct(){$this->subSystemOne=newSubSystemOne();$this->subSystemTwo=newSubSystemTwo();>subSystemThree=newSubSystemThree();$this->subSystemFour=newSubSystemFour();}publicfunctionMethodA(){$this->subSystemOne->MethodOne();$this->subSystemTwo->MethodTwo();}publicfunctionMethodB(){$this->subSystemOne->MethodOne();$this->subSystemTwo->MethodTwo();$this->subSystemThree->MethodThree();$this->subSystemFour->MethodFour();}}通过门面类把这些子系统包装起来,对外只提供门面新定义的方法。$facade=newFacade();$facade->MethodA();$facade->MethodB();客户端调用很简单,我们不需要知道调用了哪些子系统,只需要知道门面方法做了什么就可以了!门面模式就是这么简单,真正在项目中做过开发的人肯定都在不知不觉中使用过这种模式。当你需要为一个复杂的子系统提供一个简单的接口时,门面模式就非常适用。同时,如果客户端程序与抽象类的实现部分存在较大的依赖关系,也可以引入门面模式进行解耦,提高子系统的独立性和可维护性。另外,当你需要构建一个层次化的子系统时,门面可以作为每个子系统的入口。Laravel中的门面系统相信用过框架的人都会用到,比如:Cache::put()。在Laravel中,facades是使用魔法方法__callStatic()实现的。然后让对象的方法直接使用静态方法来调用。是不是很神奇。有兴趣的朋友可以翻一下源码,源码在/Illuminate/Support/Facades/Facade.php。要点:三层结构或MVC也是门面模型的一种体现。前面说过,门面模式适用于分层子系统的维护。三层结构,MVC、MVP、MVVM本质上都是为了分层,分层的目的是降低系统的复杂度。仅仅卖我们的手机是不够的。我们的最终目标是成为像小米一样的高科技家电公司。但是我们生产不了那么多的家电产品,所以我们决定建一个商城(Facade),让一些质量非常好的商家加入我们的阵营,在商城里一起销售他们的产品(SubSystem)。当然,这些产品都是我们精挑细选出来的,绝对是精品中的精品!!完整代码:https://github.com/zhangyue0503/designpatterns-php/blob/master/19.facade/source/facade.php示例这次我们将在发送维度对短信的发送进行封装,将不同的短信进行组合并封装了推送算子的接口。发送的时候,只需要使用发送类来控制短信的发送或者用不同的第三方服务进行推送。想想就很方便!短信发送类图完整源码:https://github.com/zhangyue0503/designpatterns-php/blob/master/19.facade/source/facade-push.phpaliYunService=newAliYunService();$this->jiGuangService=newJiGuangService();$this->message=newMessageInfo();$this->push=newPushInfo();}publicfunctionPushAndSendAliYun(){$this->message->Send($this->aliYunService);$this->push->Push($this->aliYunService);}publicfunctionPushAndSendJiGuang(){$this->message->Send($this->jiGuangService);$this->push->Push($this->jiGuangService);}}classMessageInfo{publicfunctionSend($service){$service->Send();}}classPushInfo{publicfunctionPush($service){$service->Push();}}classAliYunService{publicfunctionSend(){echo'发送阿里云短信!',PHP_EOL;}publicfunctionPush(){echo'推送阿里云通知!',PHP_EOL;}}classJiGuangService{publicfunctionSend(){echo'发送极光短信!',PHP_EOL;}publicfunctionPush(){echo'推送极光通知!',PHP_EOL;}}$send=newSend();$send->PushAndSendAliYun();$send->PushAndSendJiGuang();解释还是熟悉的菜谱和熟悉的味道这里,你可以想象我们的第三方服务类都是比较老的接口,或者已经是复杂的接口。这时候使用外观模式可以配合新系统,也可以降低复杂度,但是需要注意的是外观类本身可能会成为复杂度的来源,不过好在我们可以遵循单一职责原则,一个外观类只做一件事。下期的外观模式真的没什么好说的,因为它真的很简单,而且无处不在。不要被Laravel花哨的Facade类所迷惑,它并没有那么复杂。下次要学的还是很简单的模式,会不知不觉用到:模板方法模式,各个媒体平台都可以搜索【硬核项目经理】