如果你看过查理芒格的<穷查理宝典>,或者听过罗振宇的<罗辑思维>,应该对非常熟悉多元思维模型这个概念。思维模型又称为心智模型,英文为mental model,是认知心理学的一个概念,用于解释个体为现实世界中之某事所运作的内在认知历程(wikipedia)。如今思维模型的范围被扩展了很多,基本上囊括了人类解决问题时所使用的各种思考框架、设计原则,以及心理学的各种认知偏差、非理性行为等。多元思维模型就是强调在思考问题的过程中,要综合考虑各种场景的可能性,充分借用各学科的有效工具,只有在多维度思考的过程中,才有可能逼近真相。
软件工程师在构建复杂系统的时候,也会有意无意的应用大量认知模型,正是这些有效的认知模型,帮助我们构建了当今无比复杂的信息系统,把全球所有60亿人口都裹挟进了数字智能时代。
这篇文章介绍了在软件系统设计与开发过程中最常用的10个认知模型。
抽象也许是设计复杂系统的最重要的工具,抽象能力的高低是软件工程师优秀与平庸的最重要的区别之一,抽象能力的强弱直接决定了我们解决问题的规模大小和复杂度。
当我们在设计一个通信系统的时候,简单来说会做如下抽象:
这些都是在一个层面上的抽象,使得开发者在开发系统的时候可以专注于当前抽象的模块,业务流程更为清晰,降低开发时的心智负担。
抽象在具体实现过程中,有两种最重要的模型,一是分层,二是分治。
分层就是把一个复杂系统划分成若干个层次,每一层专注于解决某一领域的问题,并向上层提供服务,上层解决的问题依赖于下层提供的抽象。有些层解决的问题可能会需要与其他所有层进行交互,这种层体现在层次图上就是一个纵向的层(比方说监控、配置管理等)。
分层架构
通信系统中著名的OSI协议模型,以及我们每个人每天上网的时候都会用到的TCP/IP协议栈,就是最典型的分层设计模型。
TCP/IP模型和OSI模型
我们整个人类社会其实都是分层设计,比方说在企业里,最下面是底层劳动者,中间有各级经理、总监等管理者,上面是一堆CXO,再往上还有董事会。
分治就是分而治之,是人类自古以来应对复杂问题的最直观的解决方案。
当我们面对一个复杂的大问题,我们可以把这个问题分解成若干个较小的问题,如果这些小问题还是太复杂,我们就进一步分解,知道每一个小问题都可以通过可行的步骤解决为止。在小问题解决以后,我们再一步步把每一个小问题的解决方案以及结果组合起来,最终解决那个复杂的大问题。
Google提出的MapReduce算法就是一个典型的分治的例子。
简单来说,MapReduce包括两个步骤,一是Map,二是Reduce。通过Map,把一个输入数据映射为多个数据,然后对这多个数据同时进行运算处理,然后通过Reduce把运算的结果综合起来得到输入数据的最终结果。
分治思想其实体现在我们生活的方方面面,从政治上的封建诸侯、郡县制到现代公司里的分公司、产品线,可以说如果没有分治思想,人类就不可能进行大规模协作,因此也不可能发展出当前的文明。
任何事物都处在动态发展的过程中,软件系统也不例外。随着时间的推移,一个软件系统的业务需求、运行环境可能会不断发生变化,这就要求软件系统本身能够适应这些变化,不断进行演化。
比方说,某个创业公司一开始设计一个通信系统的时候,可能只需要支持1万个用户,那用单体架构(所有功能跑在一个进程内,这个进程部署在一台机器上)就完全可以满足需求。慢慢的,用户越来越多,团队规模越来越大,为了方便业务开发及管理,就需要划分功能,抽象出若干个功能模块(注册、鉴权、呼叫等),每个功能跑在单独的机器上,由单独的部门维护,组合起来完成整个业务需求。随着用户的增长,每个功能模块的性能都到了极限,这时候就需要考虑用把每个功能抽象成单独的服务,部署在服务器集群上,使每个功能可以独立优化、扩展,这时候可能还会有单独的部门维护服务器集群,提供各个业务都需要的底层功能。
架构师的一项核心能力就是根据业务、环境的迭代,不断推动架构的演化,保证系统架构走在业务演进的前面,而不会成为业务发展的绊脚石。在架构设计的时候,要充分考虑到系统演化的需求,在设计上要考虑灵活性,以应对将来的演化需求。
一般来说,一个软件产品演化的起点是MVP,通过重构的方式推进系统的演化,同时在开发过程中要尽量遵循KISS原则。
MVP是Minimum Viable Product的缩写,意思是最小化可行性产品,是精益创业提出的一个概念,意思是用最小的代价发布可用的产品,从而最大程度的获得用户的反馈并验证产品的商业可行性。
在很多情况下,开发一款完整产品的代价是非常昂贵的,在市场接受度不确定的情况下,创业公司可以通过MVP不断验证产品设计和市场反应,然后慢慢通过演化的方式迭代产品。即使是微信这样成功的产品,在一开始也是从很单一的功能开始迭代的:
MVP的思想在社会学上同样有所体现,比方说历史上空想社会主义者建立的实验性社区,中国改革开放初期的特区等。
重构是进行系统演化的重要手段,小到一个变量名,大到整个系统,都需要不断进行重构。重构就是在不改变外部行为的前提下,优化内部实现。这种优化可以是提高代码的可读性,增强代码的灵活性,或者改变代码内部结构与设计。
一般来说,当我们决定要进行重构的时候,出发点总是好的,总是希望能够把原来意大利面条似的的代码整理成清晰美观又灵活的代码。但是,现实并不总是像想象的那样美好。比方说苏州的伦敦桥:
KISS是Keep It Simple, Stupid的首字母缩写。这是一种经验原则,要求设计系统的时候尽量保持简单。换句话说,“简单就是美”。
当把KISS原则用在用户体验的设计上时,就是要把一个产品做的连白痴都会用。最典型的就是苹果公司的极简主义设计哲学。
当把KISS原则应用在代码设计上时,核心就是要保持模块的功能单一,所谓的高内聚、低耦合。最典型的例子就是UNIX的设计哲学:
设计模式代表了开发人员一致认同的最佳实践,每一个设计模式都描述了一个典型问题的通用解决方案,可以使开发人员能够用简洁一致的术语进行沟通,减少沟通过程中的不确定性,并且可以提供一个较高的抽象层次。设计模式就像一套久经考验的模板,当你碰到某些问题的时候,如果能简单的套用模板,就可以快速高效的解决问题。
比方说,如果你的系统里有若干个子系统,其中一个子系统的状态变化需要通知到其他子系统,这时候就可以应用观察者模式。或者,你的系统在不同的情况下需要和不同的外部系统(比方说不同的数据库)进行交互,这时候就可以应用接口模式把不同外部系统的差异封装起来。
设计模式在非技术领域也有很多应用,比方说国内科技公司流行的VIE架构,就是一种解决美元资本和国内政策限制的一个有效的商业设计模式。
VIE架构示例
计算机系统在进行通信的时候,通常会指定一套统一的协议,通信各方都遵循同样的语法、语义、时序进行通信。通信协议就像人类的语言,大家都遵从同样的一套系统,才可以互相理解沟通。
在互联网领域,使用最广泛的就是TCP/IP协议族。协议族是由很多个协议组成的一个协议家族。其中最重要的是IP和TCP两个协议,这也是我们平时上网时用的协议。
TCP通信流程
我们在开发一个新系统的时候,只要遵从大家都认可的协议,就可以保证可以和遵从同样协议的系统通信。比方说,我们开发新的网站,只要遵从HTTP协议,页面用HTML/JavaScript开发,就可以保证浏览器可以访问到我们的网站,而不用管浏览器是怎么开发的。只要对外提供服务的接口协议保持不变,不管内部架构如何演化,都可以保证对外提供一致的服务。
类似的,摩斯码是电报通讯的标准协议,只要收发双方都用摩斯码,就可以把消息发送到全世界。
“不要重复发明轮子”的意思是尽可能复用已有的代码、模块、框架、系统、服务等基础设施,其核心逻辑是复用。复用的好处有很多:保持代码简单,更好的可维护性,更短的开发时间,业界的最佳实践等。
比方说,如果你想自己搭建一个博客,或者简单的商务网站,直接用WordPress就可以了,甚至不用写一行代码。
而有赖于开源领域的各位大牛的贡献,我们现在甚至可以通过组装各个开源模块构建一个复杂的分布式系统。
既然有桥可以过,为什么非要摸石头呢?
既然有好的模块可以用,那就不要自己造轮子了呗。
这10个认知模型是软件工程师在平时工作中最常用的,同时也被应用在社会、商业等各个方面。抽象、分层、分治帮助我们站在更高的角度分析架构设计;演化、MVP、重构、KISS原则让我们以尽量灵活的方式设计系统;设计模式为我们提供了一套精炼有效的问题解决模板;协议使系统的接口和实现可以分离,并且使不同的系统可以直接通信,而不用考虑各自的实现;不要重复发明轮子,站在巨人的肩膀上。
希望这10个认知模型能够帮助你更好的解决问题。
作者:DeepNoMind
链接:https://www.jianshu.com/p/b5a10a3ff123
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。