技术理论和技术实践,对程序员来说,是两个非常重要的指标。
是面试时重要的两方面,是定工资时重要的参考依据。
- 如果说“某人有十年 xx 开发经验”,这是在说技术实践——经验丰富
- 如果说“某人精通设计模式、算法、xx语言……”,这是在说技术理论——基础牢靠
如果只注重实践,往往沦为十年码农;而只强调理论,就显得纸上谈兵。
应该均衡。
设计模式的目的
“算法”的目的很明显:提高运行效率,或减少运行时间,或减少运行空间。
但仔细想想设计模式是干嘛用的?
- 使你的代码更易维护、易拓展、好看
在敏捷开发已经成为主流的时代,这三项“程序素质”非常重要。
你的客户没有清晰、确切的需求,只有模糊的概念。
于是你们不可能在一开始就定下:应该做什么,怎么做。
“改需求”是必然的。
尽管对开发者来说非常痛苦,但避免不了。
这时候,程序运行的快慢往往不被重视,因为要先确定做得对不对。
功能不对头,再快也没用。
但写程序也像盖楼:当你盖了十层楼,而客户说:“三层盖得不太好看,你们改一下,四楼以上就不用动了哈,只把三楼拆了再改就行。用不了多长时间,对吧”。
这是每个程序员的噩梦,也是产品经理和程序员之间的大战的导火索。
而设计模式的目标,就是把你的楼平铺下来。
把盖一个十层的楼,改为盖十个一层的房间。
设计模式是一种修炼
一个算法写好之后,一般情况下,可以复制、粘贴到你的项目。
但设计模式不行,它不可以复制粘贴,因为它不是知识。
当老师给你讲了“冒泡排序”后,你知道什么时候该用、怎么用这个算法。
但当老师给你讲了“发布订阅”后,你是否知道什么时候用?
或者,你用过吗?
但算法的最终目的,不是介绍那些经典算法。
而是教你写算法,新的算法。
类似的,设计模式是通过 23 种范式,教你如何组织代码。
教你如何把一个十层的楼,改成十个一层的楼。
或者说,它不是一个技术。
什么是技术?
- 打开冰箱
- 把大象放进去
- 关闭冰箱
这才是技术,解决一个具体的问题:如何把大象放入冰箱。
设计模式不解决具体的问题,它指导你解决问题。
所以对老师来说,设计模式是一个很难教的科目。
如果小明没吃过火锅,你不可能教给小明:火锅是什么味道的。
你需要带他去吃一吃川渝火锅、潮汕火锅、铜火锅。
高内聚与低耦合
这是设计模式的核心思想之一。
低耦合
低耦合很多人都熟:把东西分开。
假设,你有 5 个功能需要实现,而这 5 个功能有一个交叉段:
- 都需要向数据库里取一条数据
- 然后把这个数据以短信形式发给某个人
- ……
这时候,很容易想到:把这些交叉段封装在一个函数里。
这样,当“发短信”的方式发生变动时,你就不需要改五个地方。
而且,你需要考虑:将来的需求,可能产生更多的交叉点,或者没那么多交叉点,或者交叉点不同。
这时候,你可能就需要“为将来打算”:能分就分。
于是,你的代码变得:这里一堆、那里一堆。
其中某一堆需要变动时,对其他堆的影响很小、或没有。
很好。
但,有时候会变得太松散。
高内聚
这是很容易被忽略的,它和“低耦合”同样重要。
甚至在某些场景下,更重要。
这两年,大家都在不自觉得开始“高内聚”。(react16.8、vue3……)
高内聚要求程序员:把东西放一起。
这看似和“低耦合”矛盾,但实际上场景不一样。
它要求把“分散了的代码”写在一起。
只注重“低耦合”,会把程序变得很松散,往往产生无意义的分离。
最直观的表现就是,写一个相当简单的功能,要改动好多个文件。
等你发现不需要这个功能时,又要删好几个文件。
最常冒出的念头就是,“这段功能,以后会不会复用啊,要不要分成一个单独的函数或类呢?”
这是过度设计。
如果一个功能几乎不会被分成好多步,那就应该写在一起。
但如果你在维护一个老程序,那它的大框架往往决定了程序的内聚性。那就很无力了。
比如,以前。你的页面写在 html 里,样式写在 css 文件里,逻辑写在 js 文件里。
写一个按钮,至少改动三个文件。
你需要分别在文件浏览器里找到这三个文件、修改、保存。
如果这三个文件还不是在一个文件夹里,那情况就更糟了。
vue2 搞出了一个新的文件类型 .vue
,你可以把 html、css、js 写在一个文件里。
但这三个东西仍然写在三个地方:它们不是连续的。
当你的一个文件有上百行、上千行时,来回滑滚轮,真的很痛苦。
而且,你需要定义:
- update 时,怎样怎样
- mount 时,……
- destroy 时,……
- 被鼠标点了一下时,……
- 当隔壁组件发生变动时,……
vue3 继续提高了框架的内聚性,这里不再赘述。