购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

1.2 改弦更张,以模式引领架构之舞

1.2.1 三个话题,初识架构

1.过程语言有架构么

在我当时的实践范畴内,C语言的世界只有两部分,一是以.h结尾的头文件,二是以.c结尾的体文件。那么以C语言为代表的面向过程的语言有架构么?为什么我和室友做的项目,我们从未染指架构,也把整套软件做出来了呢?答案只有一种可能,那就是我们都具有架构思想,也在无形中使用了架构技能,只不过是草莽的、个人主义的、缺乏理论体系支撑的,是一种隐式使用方式。

如果说架构是软件结构,那么架构思想发生作用时,一定是在软件设计环节。如此说来,对于C语言,软件设计的核心是头文件函数名称和参数的定义(宏声明也可以算作在内)。那架构还称得上是一门学问么?

读过《UNIX环境高级编程》这本神作之后,我的架构思想进一步豁然开朗了。函数头文件设计的是单一系统进程内的结构,整个软件的架构则更多地关心进程间的通信 关系。函数定义与进程间通信,在当时是架构关注点的核心内容。在本书所讲四个时期中,函数无疑是体积最小的架构量子。

函数定义是最重要的架构思想——关注分离点(也可以称其为边界和耦合性设计)的体现,进程间通信是架构中的永恒话题——系统间关系设计与实现方式的体现。

虚拟化语言大行其道之后,架构才开始立体化、复杂化。如果人类使用一辈子UNIX系统和C语言,应该永远不会为架构话题所烦恼。纵观近25年的架构发展历程,用最精简的话语描述:随着硬件、算力、虚拟化技术、开源化生产结构和平台化思维这几方面的发展,软件规模变得越来越大,架构量子体积和服务颗粒度也因此越来越大。一言以蔽之,我们与纯粹的系统、纯粹的编程背道而驰 ,渐行渐远。在跨系统、跨生态的环境下,小团队自研实现各端、打通所有链条,确实不太现实,凭一己之力从头做技术创业的日子,已是一去不复返。

对读者当前的实际工作,这些思考可能无法带来直接帮助。但是,积极思考,努力让“陈旧的过去”变得“依然生动且鲜活”,不仅可以发掘软件技术中的情愫和品位,让技术工作变得不那么无趣,而且能够于无形中提升技术底蕴。尤其是对于管理者、布道师岗位而言,这些思考绝非是徒劳无功之举。

2.三层体系,标准—平台—应用

对于2003年开始使用WebSphere做J2EE编程的经历,至今记忆犹新,课程作业多是以JavaBean为核心的EJB应用。我一直在用WebSphere写应用代码,仅此而已。我曾想,应用程序之外还有什么?为何程序员对于(应用程序之外的)其他部分的控制无能为力?这需要在感性的程序学习后面,理性地找到规则。在一次吃饭时,我对同学道出了心中的规则,EJB提供了标准规范(或者说是范式),制定了接口应该如何发布,应该如何继承去实现JavaBean等方方面面的技术规则,WebSphere是遵循这套标准,实现了其规则的(开发)工具平台,提供了Java编译环境、UI和对象关系映射能力、MVC脚手架、装载了实现EJB规范的相关框架和类库,我们这些“小蚂蚁”则使用平台提供的封装类库、开发方式做应用软件。好吧,这就是典型的“从标准规范到开发平台,从开发平台到应用软件”的演进。

从代码角度去解读应用的形成过程,框架与库之间的区别在于:开发人员通过代码调用(类)库,而框架会调用开发人员编写的代码(意指开发人员从框架中派生出子类,框架反过来调用这些子类)。框架是底层基座,开发人员编写的代码是中枢,类库是上层依赖。因此,在对应用的耦合性影响方面,框架最大,开发人员编写的代码次之,类库最弱。多个框架相互对接融合的难度会很大,进行基础框架升级(或打补丁)会很痛苦。那么,对框架的更新要时刻关注,相比较而言,库则更为灵活、实用,完全可以采取“有新功能出现时再花费精力更新”的按需更新策略。

回忆起来,我那时架构思维的全部精华,好像即是如此。

那时我有意将很多工作都试图向着这个方向去理解,大多数都是成立的。RFC是标准规范,按照RFC规范实现的Java程序包是类库,类库里封装了符合TCP通信标准的数据结构和通信机制,调用这个类库即可实现一个TCP通信程序。

将软件的世界理解为标准规范、开发平台、应用软件这样的三层体系,是有作用的。可以用其来衡量自身的技术水平和价值定位。高端专家做标准,技术大牛玩平台,中低端的程序员写应用。价值档次的划分当然不能如此武断,写应用代码的收入也不一定最低。但是,总体来说,越在上游越具备竞争优势,这个结构理论是正确的。

能在年轻时认识到这些,算是给个人发展提供了实惠好用的指示器。对于这样的认知(或者说判断),越早理解,越能在技术发展趋势和同业者竞争面前获得先机。

任何人总要有一种属于自己的理解世界的方式。对这个认识进行泛化,即演变形成了方法论——三层解析法。对于任何对象,我常常用这个方法论去拆解,当初遇大模型时,我将数学算法理解为标准,把实现了算法的Transformer技术框架理解为平台,将使用这个平台开发出来的ChatGPT、BERT理解为应用产品。

这对我结构性地看待一切软件工作都有极大的帮助,虽然不能让我立刻做出一个应用系统,但是可以让我对任何软件项目,甚至是软件领域的任何工作,能够快速地识别、理解和记忆,这不仅仅是方法论,更固化成为我的思维模式和潜意识。

三层解析法,不管对不对,总能用得上(至少对我是这样的),这是头脑思维惯性,形成了一种心智模式,贯穿终生。

3.Eclipse如此神奇

Eclipse开发平台的崛起,让我对架构一词有了莫名的思考。相比于编程,我对架构的世界明显更为敏感,更具洞察力和领悟力,好像从来不需要有人为我指点迷津。回头来看,这门学问好像也只能靠自学成才。

对于WebSphere的使用还未精通之时,2004年,班里已经开始大面积使用Eclipse开发平台。不论是WebSphere,还是更好用的Eclipse,都是实现了J2EE标准的开发平台。我有些因循守旧,对新鲜事物谨慎有加,因此一直不愿意切换开发平台,非要找个说服自己的理由。然而经过不长的时间,便知找到这个理由是顺理成章之事,那就是Eclipse的开源和大量的插件。在对GitHub几乎一无所知,也不知道何为智能手机时,Eclipse几乎记载了我对平台型软件的所有认知。具有功能外挂、自定义扩展、灵活集成等特征的平台型软件,此时已经开始大显身手,功能型软件则江河日下。用架构模式去理性理解Eclipse,对那时的我来说简直是天方夜谭。几年之后通过搜索引擎我才了解到,这是著名的微内核模式。这样的系统通常很庞大,但是却很稳定,因为大部分的变更发生在插件上,不会影响核心部分的运行。

如果说WebSphere是功能完整的开发平台,那么Eclipse则是平台型开发平台,两者看似先后出现,但究其本质而言,两者已不可同日而语。

1.2.2 设计模式,席卷天下

1.我心中的架构鼻祖

1995年夏,身处硅谷的创始人保罗·格雷厄姆和一位朋友联手开发了名为Viaweb的首个互联网应用程序,他们一开始就思考了一个开发的方向。对于个人计算机,当时只有桌面软件这一种应用程序存在形态,他们想到了另外一个方法:让软件在公司的服务器上运行,将浏览器作为操作界面。尽管当时没听说过(对此)有何命名,但是这就是真正意义上的BS结构,即BS架构。

将软件运行在服务端,对于软件维护者和个人用户是双赢的技术决策。软件通过网络使用,而不是运行在个人计算机中。现在来看这很顺其自然,让很多烦琐的事情变得简单:BS结构的系统,在服务器端统一开发、部署和运行,不再强依赖于桌面终端类型,摆脱了开发桌面软件的程序语言选型难题。但在当时的技术条件下,网络通信昂贵且不便捷,Windows浏览器还不成熟,这个设计可谓是“脑洞大开”之举。

在做软件架构培训课时,我曾经问过学员这样的问题:你心中的架构鼻祖是什么?不出所料,得到的最多答案是MVC架构。相比而言,可能是我入行更早些的原因吧,BS结构是我心目中的现代软件架构的鼻祖。在Java等更多高级语言出现后,21世纪软件架构得到了长足的发展,无论是单体架构、面向服务架构(简称SOA)、微服务架构还是云原生架构,本质上都完全接受、融合了BS架构,并在此基础上发展演变。BS架构从始至终屹立不倒。之所以将BS架构称为现代架构的鼻祖,是因为早在20世纪60年代就有计算机了,只要有计算机就有架构,但是这远在本书所定义的四个时期之外,我无法做出任何评价。因此特意使用现代二字,来做一个时间限制。

犹记得当时我将BS架构当作不折不扣的先进架构理念来看待,但20多年后的当前从业者,早已视其为一种基础的、常识性的概念。这就是软件世界中事实标准的典型例子。一个知识被广泛接纳后,转变为一种既定的概念,几乎不再需要被二次学习,可能只有我这老古董才会追忆过去,如此翻一翻BS架构的前世今生。

2.面向对象设计的标配

C语言比Java语言更加纯粹,但是在很多方面,Java语言比C语言更有内涵。令人印象深刻的是,Java是一种很有玩味儿的语言,我当时无法用技术名词表达出来,现在来看,其实这个词就是模式。即便现在,我还常与同事津津乐道地谈论Java语言的AOP(面向切面编程)和IOC(控制反转)等模式特征。

2002年,我在学校书店翻阅了《设计模式》一书,这本书由Erich Gamma、Richard Helm、Ralph Johnson和John Vlissides四人合著,这几位作者常被称为“四人组”(Gang of Four, GoF),而这本书也就被称为“四人组(或GoF)”书。

《设计模式》这本书列举并描述了23种设计模式,虽然这本书的英文版是1995年出版的,出版中文版已是7年之后,但是在我看来,这就是设计模式在我国软件业流行起来的开山之作,在当时是面向对象设计方面最有影响的书籍。

就Java语言体系来说,设计模式是Java基础知识和J2EE框架知识之间一座隐形的桥。设计模式的内容本身属于技术范畴,这个观点无可厚非,但是究其本质而言,它讲述的是思想,展示了接口或抽象类在实际案例中灵活应用的智慧,以及如何让程序尽可能地可重用。这其实在向一个极限挑战:软件需求变幻无穷,计划没有变化快,但是我们还是要寻找出不变的内容,并将它和变化的内容分离开来,这需要非常的智慧和经验。而GoF的设计模式,是这方面探索成果的重要里程碑。

J2EE属于框架软件,框架软件设计的原则是将一个领域中不变的部分先定义好,比如整体结构和主要职责(如数据库操作、事务跟踪、安全等),剩余的就是变化的部分,针对这个领域中具体应用产生具体不同的变化需求,而这些变化就是J2EE程序员所要做的。

与工厂、单例这些模式共同到来的,还有闻名遐迩的MVC架构,那个年代各大企业招聘程序开发岗位的面试题中,设计模式和MVC几乎是必需的。只要能答对这些问题,对Java的异常、事务、锁、多线程、JDBC再有些实战能力,找到一份像样的工作还是没有问题的。

在面向过程的语言时代,要设计程序的逻辑处理流程以及程序文件本身,是典型的逻辑流程驱动设计。进入面向对象的语言时代,设计者更关注类之间的关系,设计模式能让任何类如同积木块一样组合,程序的能力因此真正“活”了起来。对于软件架构,此时更具象的、显式的表达词语是Module(模块),它是一组子程序和变量,可以被视为一个整体(架构量子)。在通常情况下,模块外部的代码只能访问模块内部一部分专门对外公开的子程序和变量。

设计模式席卷天下,意味着高级程序员必须使用设计模式来设计类图和包结构,架构量子的体积已经明显增大,这个趋势在各类软件设计中表现得极为明显。

架构关注点聚焦于模块后,“一个系统由多个模块组成”成为当时(对系统的组成)最为通识的理解。注意,此时还未进入分布式系统时代,在单体系统(或者单体系统组成的系统群)中,“面向服务”的理念还未大展拳脚,与大多数人一样,此时我对软件的理解还是功能性的。

设计模式发展至今,其概念早已被泛化,JavaScript有设计模式,数据库有设计模式,大模型智能体也有设计模式……几乎任何技术领域都可以有设计模式。相比之下,GoF设计模式不仅最为经典,而且最纯粹、精致,它的地位坚如磐石、不可撼动。 C/rGXVu6WTKwtxeUSS2WnlDqhPXBb159oCLZ3S6k8Ybq86KSjJo1uG7i2rREFdef

点击中间区域
呼出菜单
上一章
目录
下一章
×