资讯专栏INFORMATION COLUMN

设计模式系列·Facade模式之MVC的烦恼

zhichangterry / 3383人阅读

摘要:没有任何意外,王小二的公司用来开发公司的主打产品。臃肿的着手开干吧小二打开熟悉的,找到提交订单模块的。要不再去请教下哥的烦恼小二找到哥,详细的描述了他的问题。

流行的MVC架构模式

如今的Web开发,各种框架风起云涌,势如破竹。

从国民第一的ThinkPhp到称霸全球的Laravel,这些框架有一个共同特征,都采用了MVC的架构模式。

没有任何意外,王小二的公司用Thinkphp来开发公司的主打产品。

Get新需求

一天,小二刚到公司,正打算坐下来喝杯茶。

老大走了过来:“小二啊,现在有个新的需求。咱们之前提交订单的模块,需要增加发送邮件的功能,你看看能不能实现?”

小二想了想说:“没问题,最多3天搞定!”

看王小二胸有成竹的样子,老大满意的点了点头。

臃肿的Controller

着手开干吧!小二打开熟悉的IDE,找到提交订单模块的Controller。

OMG!不看不知道,一看吓一跳,这个Controller的代码竟然接近2000行。

因为用户提交订单时,会与其他模块进行交互,需要的数据也比较复杂。
只见此Controller,从Model层各种拿数据,然后各种逻辑处理,怪不得代码到了将近2000行。

“哎,这2000行代码,看着就头疼,可让我怎么写啊”...小二叹气道。

“要不再去请教下C哥?”

MVC的烦恼

小二找到C哥,详细的描述了他的问题。

C哥喝了口水,淡定的说:“这个嘛,我之前也遇到过。”

“您也遇到过,怎么解决的?”

“这个问题,哈哈,姑且就叫MVC的烦恼吧!MVC将View与Model进行了分离解耦,这固然很好,但很多人就将业务逻辑的处理写在了Controller里,导致Controller越来越臃肿,以致最后都无法维护。”

“对对对,您说的太对了,我就经常这样写。”

[图片:臃肿的代码]

给Controller减肥

C哥继续说道:其实,Controller不应该处理过多的业务逻辑。给你举两个例子就明白了。

控制器,就像遥控器一样。
你见过遥控器关心电视怎么播放视频吗?没有,遥控器只是发送播放视频的信号,具体的播放视频的细节,遥控器不会关心。

控制器,就像将军一样。
你见过将军亲自为每位士兵配备武器吗?细节部分,将军不必过问,将军的职责是领兵打仗,这叫各司其职,否则就乱了。

说到这里,小二恍然大悟:“听C哥一席话,胜读十年书啊!”

“既然这样,就给Controller减减肥吧。”C哥说到
“是啊,但是怎么减肥呢?”

初识Facade外观模式

“我给你讲一种设计模式-外观模式,你就懂了”。
“好啊好啊,洗耳恭听”。

C哥又讲到:

外观模式,提供了统一的接口,用来访问子系统中的一群接口。外观模式定义了一个高层接口,使得子系统更加易用。

也就是说,干一件很复杂的事的时候,你想团队中每个人都花一年半载去学习如何做这件事吗?利用外观模式,我只需要指定一个人去学会这些复杂的步骤,然后我再告诉这个接口人去干就行了。

Facade外观模式的应用

“如果让你实现上面那个需求,你可能会找到用户提交订单的Controller,然后在Controller里写下面一大堆代码。是不是?”

/****文件名:SubmitController.class.php(用户提交模块controller)****/
    
//..............接上...2000行代码..............//

    //获取用户邮箱
    public function get_user_email($uid){
        return new User()->get_user_email($uid);
    }
    //获取要发送给用户的内容
    public function get_email_content($uid){
        return new Email()->get_email_content($uid);
    }
    //发送邮件
    public function send_email($email,$content){
        return new Email()->send_email($email,$content);
    }
    
    //用户提交订单触发的方法
    public function submit(){
        $email=$this->get_user_email($uid);
        $content=$this->get_email_content($uid);
        $this->send_email($email,$content);
    }

“对对对,我会这么写”。

"其实你用的ThinkPhp,有一层叫Logic层,关于业务逻辑处理的部分,你可以写在Logic层里。这样,Controller层就变得很轻量了,好维护了。"

/****文件名:SendEmailFacadeLogic.class.php(发送邮件Logic)****/
    
    //获取用户邮箱
    private function get_user_email($uid){
        return new User()->get_user_email($uid);
    }
    //获取要发送给用户的内容
    private function get_email_content($uid){
        return new Email()->get_email_content($uid);
    }
    //发送邮件
    public function send_email($uid){
        $email=$this->get_user_email($uid);
        $content=$this->get_email_content($uid);
        return new Email()->send_email($email,$content);
    }
/****文件名:SubmitController.class.php(用户提交模块controller)****/
    
//..............接上...2000行代码..............//

    D("SendEmail","Logic")->send_email($uid);

“你看,加了Logic层,业务逻辑都放在Logic里面去处理,Controller是不是瘦了很多呢?Logic层为Controller提供了一个高层的接口用来发送邮件,也就是Facade模式的应用。”

加深理解

“小二,明白些了吧?”
“嗯嗯,明白了好多,犹如醍醐灌顶!”

“为了加深你的理解,我给你画个简单的实例图吧”。
“真的吗?太谢谢C哥了”。

恍然大悟

看了C哥画的图,小二小彻小悟了。

“C哥,Facade模式真不错,你看,这样统一成简单的接口后:”

1、降低了系统的耦合度。提交订单的Controller,再也不用与UserController、EmailController等耦合了。现在只需要关心SendEmailFacadeLogic就可以了。
2、并且,用户使用了Facade模式后,有了统一的入口,就很容易监控客户对系统的使用了。就如Thinkphp的单一入口一样。

“嗯嗯。小二真聪明,确实是这样。”

更多精彩,请关注公众号“聊聊代码”,让我们一起聊聊“左手代码右手诗”的事儿。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/22589.html

相关文章

  • Java开发

    摘要:大多数待遇丰厚的开发职位都要求开发者精通多线程技术并且有丰富的程序开发调试优化经验,所以线程相关的问题在面试中经常会被提到。将对象编码为字节流称之为序列化,反之将字节流重建成对象称之为反序列化。 JVM 内存溢出实例 - 实战 JVM(二) 介绍 JVM 内存溢出产生情况分析 Java - 注解详解 详细介绍 Java 注解的使用,有利于学习编译时注解 Java 程序员快速上手 Kot...

    Lucky_Boy 评论0 收藏0
  • Java开发

    摘要:大多数待遇丰厚的开发职位都要求开发者精通多线程技术并且有丰富的程序开发调试优化经验,所以线程相关的问题在面试中经常会被提到。将对象编码为字节流称之为序列化,反之将字节流重建成对象称之为反序列化。 JVM 内存溢出实例 - 实战 JVM(二) 介绍 JVM 内存溢出产生情况分析 Java - 注解详解 详细介绍 Java 注解的使用,有利于学习编译时注解 Java 程序员快速上手 Kot...

    LuDongWei 评论0 收藏0
  • JS设计模式Facade(外观)模式

    摘要:概念模式为更大的代码提供了一个方便的高层次接口,能够隐藏其底层的真是复杂性。参考设计模式设计模式系列文章设计模式之模块模式揭示模块模式设计模式之单例模式设计模式之外观模式 概念 Facade模式为更大的代码提供了一个方便的高层次接口,能够隐藏其底层的真是复杂性。可以把它想成是简化API来展示给其他开发人员。 优缺点 优点 简化接口 使用者与代码解耦 易于使用 缺点 存在隐性成本,性...

    xiaodao 评论0 收藏0
  • 理解设计模式

    摘要:适配器模式将一个类的接口转换成客户希望的另外一个接口。代理模式为其他对象提供一种代理以控制对这个对象的访问。如果用来解决排序问题不符合开闭原则,添加策略需要修改代码用策略模式将策略抽象成接口,不同的策略实现该接口。 简单工厂、工厂方法、抽象工厂 简单工厂 通过定义多个factory.produceXXX()方法,或者通过向factory.produce(type)传递type参数来生成...

    saucxs 评论0 收藏0
  • Android开源架构

    摘要:音乐团队分享数据绑定运行机制分析一个项目搞定所有主流架构单元测试一个项目搞定所有主流架构系列的第二个项目。代码开源,展示了的用法,以及如何使用进行测试,还有用框架对的进行单元测试。 Android 常用三方框架的学习 Android 常用三方框架的学习 likfe/eventbus3-intellij-plugin AS 最新可用 eventbus3 插件,欢迎品尝 简单的 MVP 模...

    hzc 评论0 收藏0

发表评论

0条评论

zhichangterry

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<