前言

以小说的笔法写的设计模式系列文章,你绝对看得懂!

设计模式系列·王小二需求历险记(一)设计模式系列·王小二需求历险记(二)设计模式系列·封装、继承、多态设计模式系列·初探设计模式之王小二的疑问设计模式系列·Facade模式之MVC的烦恼设计模式系列·Adapter 模式之如何优雅的使用别人的轮子设计模式系列·类爆炸之Bridge模式设计模式系列·工厂方法模式之 Code Review设计模式系列·抽象工厂模式

------华丽的分割线------

0x1 不断变化的需求

需求总是在变化的”,在无数次与产品经理的”需求大战“中,小二对这句话深有体会。

这不,前些天,小二就经历了一件欲哭无泪的事情...

0x2 产品经理的需求

产品经理走到小二面前:“小二,我们需要给年会员发送短信,你多长时间能搞定?”

小二沉思了一会,拍拍胸脯:“没问题,不就是发送短信嘛。一周内搞定”。

0x3 面向过程的开发

拿到需求后,小二就快速的对需求拆分了步骤:

  1. 在数据库中获取所有的会员;
  2. 获取所有的年会员的信息;
  3. 按照注册时间排序;
  4. 依次给这些会员发送短信。

好了,需求的实现,拆分的如此简单明了,下一步就撸起袖子开始干呗!
经过一周的努力,明天终于要上线了,小二内心中满满的都是成就感。

“等等,小二,发送短信的事,需求要变一下...”
"啥?明天就上线了,你告诉我要变需求?有没有搞错?"

“小二,这个需求确实紧急,没有办法。我们除了给年会员发送短信外,还需要发送微信。你谅解下,帮帮忙,我也是确实没有办法...”
"唉,好吧,就这一次,下不为例!"

刚刚写好的812行代码,又要重新修改...

经过一个晚上10小时的加班,小二终于搞定了,代码从之前的812行变为了1300行...

项目如期上线,小二也松了口气,但最近整晚的加班确实吃不消了。

小二回过头来想想:“这产品经理每一次的需求变化,我都得更改我的整个脚本或整个函数。这样太容易出错了,有没有好点的办法,不让我这么痛苦?...”

0x4 模块化

小二忽然灵光一闪:“与其写成一个庞大的函数,为什么不把程序模块化呢?下次变化的时候,那我只需要更改我这个模块就可以了。这不是更好理解与维护吗?”

小二内心窃喜,就这么干!

于是,小二将整个发送消息的过程拆分成了不同的函数,不同的模块。

//1、获取年会员的信息[包括mobile、email、微信号...]
 function get_year_vip(){}
 //2、按照注册时间排序
 function sort_year_vip(){}
 //3、发送消息($user_info为用户信息,$content为消息内容)
 function send_message($user_info,$content){}复制代码

那么,当我需要从发送短信变为发送短信和邮件的时候,我只需要更改send_message()这个函数就可以了。good job!

0x5还不够灵活

在牛人云集的公司,小二想去请教下C哥,看看有没有更好的解决办法。

听完小二的描述,C哥说到:“嗯。从一大坨代码到模块化,程序变得更好理解和维护了,不错不错。”

听到C哥的赞赏,小二高兴极了,瞬间从之前低落的心情变得彩虹满天飞。

“不过,你这个还不够灵活。”

“还不够灵活?”

“是啊。比如发送消息模块,我现在需要发送微信。但是短信、邮件的内容是字符串,微信的内容是数组。那这个send_message()函数是不是就不能用了?"

”你这么一说还真是“

”很明显,模块化可以帮你写出更加容易理解和维护的代码,但是,模块化并不能帮助你写出能应付所有变化的代码。“

”嗯...是的“

”并且,函数还有一个问题。如果有很多地方对你的函数有依赖,在使用你的函数(你或许不知道别人在使用你的函数)。那么,你对这个函数一更改,也会间接的对其他地方产生bug。这就是强耦合带来的弊端。“

”对,对!C哥说的太对了!那么,如何去解决呢?“