每一个程序员都听过架构这个词,每一个程序员都有自己对此的理解和看法,本文分享我对架构的理解。
因为我是程序员,所以本文讨论的架构特指软件架构(Soft Architecture)。
我看过很多关于架构方面的书,每一位作者给出的定义都不一样,本质上却相差不多。
概括而言,架构是:
针对系统的表达,描述了系统的要素组成,及要素之间的交互关系。
上面就描述了针对一个系统的架构,有 3 个顶层模块 ,模块 E、模块 F、模块G。
模块间有交互,并且模块 E 中还有模块。
所以,一般讲架构时,我们是指:
这很容易造成一种错觉,就是架构嘛,也没有什么难度,人人都会。
我认为架构的本质是面向需求的。
有人认为架构很简单其实是多半自己没有真正做过架构设计,大多数人都有一个心理误区,高估自己的能力和努力,而低估别人的价值和专业性。
很多架构师已经不在一线写代码了,所以会让一线人员认为他们不会,认为他们只会面向文档,面向 PPT。
另外一种可能是,架构很简单的原因是本身业务就非常简单。
我的第一份工作做的东西就是用 C 语言点亮一块 LCD 屏,并解析串口协议,在屏幕上绘制规定的图形,比如圆形、矩阵、椭圆。
整个代码逻辑很简单。
uboot 代码启动
设备初始化
while(1)
{
接收中断
解析通信数据
执行对应的绘图的函数
}
就是这种开发,枯燥、单调且无聊。
所以,这种情况是不会需要架构的。
如果,你问我怎么不做架构设计,我会一脸的问号看向你的。
但后来,我发现有些不对劲。
任何一个函数都要自己去实现,并且没有什么迁移性,我根据自己的查阅了解到 ucos ii 系统可以解决我这个问题,因为里面有很多现成的绘图函数,直接调用就好了。
但对于一个刚毕业的学生来说,在没有人能够给予指导的情况下,移植 ucos ii 可不是一件简单的事情。
其中的任务管理、任务调度、进程通信、窗口管理等等是我一个应届生生命不能承受之轻。
多年来,我一直有一个遗憾就是,因为没有强力的推动,我始终没有在我第一份工作离职前把代码优化一下,把 ucos ii 整上去。
我驾驭不了其中的架构成为安慰自己的唯一理由。
所以,我可以回答这一节的问题:认为架构简单是因为低估复杂度
有人认为架构容易,有人认为架构很难。
我个人认为很难的地方在于架构设计不统一
在学校读书时,接触到的架构是 TCP/IP 架构。
我之前做 Android 开发,他的系统架构是这样的:
再后来,在市面上买的很多关于架构方面的树,因为作者都是搞 WEB 出身的,所以基本上架构长这样:
后来,从事自动驾驶行业,一般公认的架构是这样的:
如果,从事汽车软件的开发,那么 AUTOSAR 的架构是这样的:
当然,还有一种 Clean 架构是长这样的:
《孙子兵法》写道:兵无常势,水无常形。
有些地方也可以这样形容架构。
具体问题具体分析,指望那一把锤子去找钉子是不行的。
这个过程充满一定的艺术性,所以也是它难的体现。
架构不是形式主义,它伴随着业务的发展而动态改变。
上图,是微信最早版本的客户端架构,现在看来非常的菜。
但当时实际情况是,微信是从 0 到 1 的,负责客户端开发的是 2 个人用了 1 个月,其中一位同学还是实习生。
后来,微信的业务急剧发展,架构也快速迭代,等到 v3.X 的版本时,标准化程度已经很高了。1
淘宝最初的页面是长这样的:
大家可以想想要怎么设计这样一个架构呢?
事实上,你们可能会大跌眼镜。
淘宝的技术首先是买来的,一个很基础的 LAMP 架构,全部用的开源的技术:
可就这么一个简单的东西,打败了当时的国际巨头 ebay。
所以,微信和淘宝的例子说明了架构需要面向业务,脱离业务谈架构是不现实的。
但架构也不是无字天书,做架构实际还是用公认的一些手段的
架构是多面的,不同的维度去打量它,它会呈现不同的面貌。
一般而言,人们将架构分为 3 类。
逻辑架构描述了一个系统的要素组成,各个模块间的交互关系。
比如,一个图书馆里系统中,用户登录模块就是一个逻辑单元。
物理架构是从硬件的角度看问题,比如存储用户数据的那台 mysql 服务器部署在哪个地理位置,处理业务逻辑的代码又放在哪个云,等等等等。
系统架构是最难的,逻辑架构一般是结构化的表示,而系统架构除了系统的结构化表示外,还需要处理非功能性的要求。
例如双 11 淘宝网能顶住那么大的流量,这体现了它架构的高并发特点。
而高并发其实算性能要求,这属于系统架构需要讨论的事情。
系统架构一般需要考虑如下特性:
但系统架构不是独立存在的,它需要根据这些特性要求,有效地协调逻辑架构和物理架构。
能做好系统架构的人技术素质特别过硬,对于软件、硬件、业务的理解要十分到位。
这也解释了架构设计为什么难。
设计架构一般需要通过图形化的方式描述出来,有一个行业上比较认可的就是 RUP 的 4+1 视图。
1995年,Philippe Kruchten在《IEEE Software》上发表了题为《The 4+1 View Model of Architecture》的论文,引起了业界的极大关注,并最终被RUP采纳。2
古人说:
横看秦岭测成风,远近高低各不同
4 + 1 的视图其实也是这个意思,从不同的切面描述系统。
逻辑视图是针对功能的,包括显性的功能,及辅助性功能,通过功能需求对系统进行模块划分,这样的视图非常直观容易懂,即使不是软件开发的人员,也可以弄明白和设计。
开发视图自然是针对开发者设计的,主要是程序包的概念,描述了系统的软件环境,包括第三方 SDK,开源框架,软件开发定义的功能层,业务层,通信层。
进程视图自然描述了系统中质量属性,这种属性是程序运行起来的质量要求。
比如,开发视图更多是指导程序代码的编写,是静态化的。
而进程视图关注线程、进程的状态,要确保程序运行起来后的通行、并发、同步问题。
物理视图很容易理解,面向安装和部署,是针对硬件的,是硬件资源的分配。
比如,WEB 系统你要考虑服务器的的分配。
比如,嵌入式系统你要考虑 CPU、GPU、ASIC 、专用内存的分配。
软件代码是用例和场景驱动的,场景做不好很可能会引起灾难。
比如,自动驾驶汽车撞人,这说明它的软件系统成熟度不够,场景及用例都不充分。
另外,4+1 的那个 1 是指场景视图,是对另外 4 个视图的冗余。
4+1 的视图一般可以用 UML 来绘制,不熟悉的同学可以去寻找相关的资料。
提到架构的时候,有一些关键词也会连带出现。
架构是系统描述,也是一种设计思想。
平台是架构的实现,是实实在在的代码体现,它由许多模块和组件构成。
模块(Module) 是针对功能的独立封装,有自己的输入输出规范,模块的存在使得开发可以并行。
组件(Component) 和模块很像,但它更体现零部件的属性,它是可以复用的。比如,一个按钮、一个窗口都可以在不同的地方复用,但它是同一份代码。抽象一点,如果一份代码被另外一个项目的产品采用,在一个更大的系统当中,这份代码就是一个组件。
配置,平台有很多组件和模块,但不是具体的产品,每个产品的需求不一样,所以需要结合需求,对平台做配置,裁剪或者是扩展对应的模块,最终形成产品。
大多数程序员成为不了架构师,但这并不影响我们去了解架构。
也许无法立即做架构师,但想要成为某类人,不能让自己永远停留在想的阶段,要先动起来。
这是经典书籍《高效能人士 7 个习惯》中最重要的观点。
比如想做产品经理,不能总是等待上级给予这样的机会,自己业余时间可以多做练习。 比如,想成为项目经理,除了系统化学习 PMP 知识外,平常也需要培养自己的进度、风险、质量意识,有目的的向领导申请承接更多的任务。 如果,想成为架构师也是这样的,平常就需要自己学习、暗自练习,这条路挺窄的,但即使最后你没能等到这个职位,就你本身而言的成长收获也已经足够多了。
并且,有理想总比好过没有理想,人总需要向上生长。
很多同学可能有困惑,已经工作好多年了,但似乎很难再突破,一个重要的原因就是视野所限。
如果这世上有一座等级森严的大厦,你在第 7 层干的非常好,可以欢快地从本层这个房间移动到另外一个房间,有一天你累了,你无聊了,在不干坏事的前提下,你可以尽你所能,偷偷跑到 10 楼看看。
等你跑回 7 层的时候,希望你内心的嗔与痴可以少点,视野被打开后,也许可以发现我们之前纠结的很多地方有更好的处理方式,干的活还会是一样,但你变得更加轻松自如了。