【编者的话】前些日子和团队的小伙伴们分享了自己对架构的理解,当时准备的比较仓促,讲的也比较粗糙,很多点并没有表达清楚;欣慰的是大家的反馈都比较积极,证明分享的内容是有参考价值的。
这篇博客主要把分享的内容进行整理重塑,并补充一些当时没有表达的细节,期望能够给更多人更多的启发。
圣诞那天晚上我值班,时间已经很晚了,发现团队小王同学还没回,好奇心驱使于是走过去聊了几句:原来他等着与另一个系统同步发版,辛苦却无恙。不过我好为人师的臭毛病(主要对新同学)发作,于是各种问东问西。作为过来人我太清楚职场新人的处境了,疑惑多,如果性格偏内向还不喜欢表达困惑。了解后发现小王果然存在疑惑——如何通过架构设计降低业务代码修改的难度,并抛给我一篇 博文链接 ,同时声称链接是我们组另一个技术大佬推荐的。
在打发了小王同学后,抱着“不知就要学”的心态,我打开了他给我的那个链接,主要讲的是用 Go 语言实现一种架构,内容可谓又臭又长。当天夜里无眠,我一边盯着监控面板一边理解那篇博客的内容。到第二天调班休息的时候,心里还放不下那篇博客,于是困了睡,睡醒了就打开电脑读几段,感觉到困了再继续睡,最后终于理解了文章的主旨思想及其实践的含义。
这件事情触发了我几点思考:1)小王同学的疑惑是否值得探索并解答,即“如何通过架构设计降低业务代码修改的难度”;2)能够通过架构设计降低业务代码修改(对应功能的增删改)的难度吗?3)小王做的项目的架构最初是我参与设计的,如果让我对架构进行二次设计,我是否会采用其他的架构方案?4)这个项目使用了团队内部的研发模板进行初始化,而模板的原型我也是参与制定者之一,那么这个模板所包含的架构设计是最佳实践吗?5)如果让我二次设计研发模板,会改成另一种设计吗?
通过思考得到上面问题的答案后,结合经验我又进一步深化琢磨了几个问题:a)团队应该采取什么样的方式来减少职场新人的困惑,并尽可能降低这种困惑给团队和当事人引起的不适感?b)职场新人应该如何提升自己从而拥有架构的能力?c)团队里的知识应该采取什么样的方式进行传递继承?d)对于一些高阶的方法论,如何让实践经验欠缺的同事吸收消化并运用到实际工作中?
问题需要一个一个地解决。
过去对架构思考的比较少,不过最近两个月因为工作上遇到的一些问题我一直在琢磨“分层”的技巧,并尝试论证“分层”的好处,同时细化“分层”所应遵循的原则,目标是提升自己的效率,优化团队成员的合作效率。顺着小王同学给的链接了解到整洁架构(The Clean Architectrue)的理论,算是找到了“分层”的理论支持,真可谓一个意外的收获了,
Clean-Architectrue架构图,摘自The Clean Architecture
分层思想
上图显示了整洁架构的示意图,其中每个同心圆层代表了软件开发中的不同层,越是靠近中心,同心圆层所代表的东西越抽象。可以这么理解,内部的圆层定义的是规则,外部的圆层定义的是实现机制。
整洁架构试图聚合这样几个特点:1)框架无关,即架构设计不依赖任何一个既有的开发框架,因此理论上可以使用任何框架来实践整洁架构。2)业务规则的可测性,即可以方便地测试业务逻辑所涉及的代码,不依赖UI、数据库或者 Web 服务等外部元素。3)功能实现不依赖 UI 的实现细节,比如同样一套后台系统可以用在 Web 应用,也可以用在 App 原生应用。4)业务逻辑不依赖数据库的实现细节,可以把数据保存在 Oracle、SQL Server、Mongo、MySQL 等任意一种数据库中,同时业务逻辑不需要做任何改变。5)总结起来就是:业务逻辑对外界实现完全没有依赖,任你外面的实现细节如何改变,核心业务逻辑不需修改。
依赖规则
为了实现上面所讲的特点,只需要遵循依赖规则:只允许外部圆层的代码依赖内部圆层的代码,反之则禁止。换言之,内部同心圆层的代码不知道任何外部同心圆层的代码,比如内层的代码一律禁止引用外层声明的函数、类、变量或其他任何元素。
其实上面的规则还隐含着另一个规则:当有数据传递时,只允许外部圆层接受内部圆层的数据格式,反之则不允许。这也是为避免外部的代码逻辑影响内部的代码逻辑(思考一下为什么)。
整洁架构中的术语介绍
值得说明的是,虽然整洁架构的示意图中只显示了四层结构,但是可以根据业务规模调节层数,也就是说层数不是关键,关键在于分层思想以及依赖规则。
一个关键点——控制反转
依赖规则里规定“只能外层的代码依赖内层代码”,但是在实际代码中势必会出现这种场景:外层的代码调用内层的代码处理数据,数据经过内层代码作用后需要再反传给外层进行其他处理(比如把处理好的数据保存到数据库,保存到数据库的逻辑在外层)。Clean-Architectrue架构图的右下角给出了一种示意,那么如何让这种场景满足依赖规则呢?答案就是控制反转。
对于 Go 语言来说,大体的实现是在内层定义一个 Interface 类型的数据,内层代码通过操作 Interface 的方法来实现业务逻辑,在外层实现这个 Interface 类型所包含的方法,从而达到反向控制的目的。其实这是一种设计模式,有点类似工厂方法模式或者抽象工厂模式,不是 Go 的专属,其他语言(比如 Java)均可以实现。
在领悟了整洁架构的思想后,我又把小王同学给我的又臭又长的博客读了两遍,然后思考我做的项目架构以及参与制定的开发模板是否有必要修改,假如要修改的话如何修改?如果不需要修改的话理由是什么?
经过一番分析后,我认为我做的那个项目架构没有问题(不排除一些细节存在疏漏),不需要修改。我是从具体的业务复杂度来考虑的,改进版的 MVC 架构已经足以应对。1)假如按照整洁架构的思路把项目重构一遍,并没有办法降低需求的增删改造成的开发量,该头疼的地方依然要头疼;2)项目采用小巧精悍的 MVC 架构也能够满足快速敏捷的要求,而整洁架构的定位是大型的企业级应用或应用生态,反而不适用于小复杂度的项目开发;3)重构是一件劳民伤财的事情,轻易不能做。这么分析以后,我参与自研的开发模板已经足够大部分项目使用,至少架构层没有修改的必要(其他的层面或许有改进的必要,比如通用依赖库的使用方法、测试用例编写规范等)。
虽然思考到最后发现不需要做什么,但这次思考的意义在于,让我意识到架构这件事情,并开始思考架构的含义及意义。那么,架构是什么呢?
架构是什么呢,可能这个问题和“什么是最好的编程语言”一样,不同的架构师会有不同的观点。在 2018 年上半年的时候,我参与过一次雷达峰会,对其中一位讲师抛出来的观点比较认同(当时没有太大感触,思考完上面的问题后才开始反刍这些观点):1)架构为业务而生;2)架构聚焦于解耦;3)架构意味着沟通与协作;4)架构需要为时间买单(可以理解为架构的进化)。
我们可以先看几个流行的架构图来体会一下。
Kubernetes 的架构图:
相信每个了解云技术栈的开发者都见过上面的 Kubernetes 架构图,至少听过其中部分组件的名称。这张图很清楚地描述了 Kubernetes 包含的各个组件及其协同运作的方式,这不仅仅给 Kubernetes 项目的开发者一些开发方向的指引,同时也让 Kubernetes 的使用者能够方便地讨论各种问题。
Istio 架构图:
业界提到 Service Mesh 的时候必提 Istio,它的架构如上图所示。可以注意到在 Istio 的架构中,所有的流量都通过 Proxy 进行接管,而 Proxy 是作为一个独立的进程与业务进程运行在同一个实例中(多指 Kubernetes 里的 Pod),那么对这个 Sidecar 就有比较多的要求了,比如要轻量级、高效、便于配置部署等等。由架构图我们也可以反推得出,在微服务化改造的过程中,应该控制自己业务的复杂度不能拆的太细碎,否则边界成本会变得非常大。
VXLAN虚拟网络架构图:
这是我之前的一篇博客的示例图,描述了 VXLAN 的虚拟网络架构,这张图让很多讨论变得十分容易。
架构设计,往往要求开发者拥有宏观的视角,在实践经验不足、业务了解不够全面的情况下,是谈不上做架构的。不过,大部分开发者虽然做不了大的架构,但是可以尝试做一些微小的架构设计,从而建立自己的信心,然后 1)努力刻苦锻炼自己的实战经验(下苦功夫了解所在技术栈里的框架细节、依赖库细节、中间件细节,等等),2)同时积极主动地了解、思考尽可能多的业务细节。如此坚持下去,成为牛 x 哄哄的架构师指日可待。
领域驱动设计(DDD)是一种实用的架构实践方式,它是一个成体系的方法论,这本书 详细地介绍了这个实践。文本无法通过一个小节的文字详述它,仅通过它的两个前提和两个实践方法先大体了解一下它的概念。
DDD 的两个前提:1)在⼤大多数软件项⽬目中,主要的焦点应该是领域和领域逻辑; 2)复杂的领域设计应该基于模型。这两个前提条件把领域驱动所关注的点变成了模型的创建,因此这本书 很大篇幅的内容都是在讲模型相关的内容。
DDD 的两个实践:1)迭代开发;2)开发⼈人员与领域专家具有密切的关系 。第一条侧重技术上的持续性,第二条侧重业务上的理解。
从小就认定了“好好学习”的道理,所以一直非常努力刻苦地对待学业,不过那时候除了有一个好成绩外并未感觉到对自己的影响,甚至在硕士学位结业的时候我还在怀疑自己刻苦那么多年的意义。参加了工作后,一切与钱挂钩,那种努力却看不见成长的感觉挺折磨人的,这一度让我感到迷茫,并且持续了好久好久。终于有一天,就好像从量变到了质变(我印象中是读瑞·达利欧的《原则》这本书那段时期,那段时期发生比较多的事情),一切都渐渐变得清晰明朗。我发现很多工作中需要的知识已经在课堂上学习过,生活中的很多道理也已经在课堂上学习过。我知道了自己所知道的,从而加以运用;同时也意识到自己所不知道的,从而有的放矢地学习精进自己的知识储备。
本文简单介绍了 Clean-Architecture 的思想,并通过几个示例介绍了架构原理及其应用实践,最后尝试着解答了职场新人对架构的一些疑问,并给出了一些精进才能的建议。最后小结部分感慨了一下自己的职业生涯,给自己的未来定了一个基调——向着另一个更高的未知层冲刺。
原文链接: https://jingwei.link/2018/12/3 ... .html