几年前,我被问到“你是如何变成一名架构师的?”。基于这个话题,我们讨论了很多,比如必要的技术、经验以及所需要的知识储备等。这一次讨论促使我开始思考要成为一名架构师应该具备和学习的东西有哪些,成为一个优秀的架构师应该具备哪些能力和做哪些事情。为此我查阅资料,走访各位大佬,当然也结合自己的经历,最终我输出了今天这样一篇文章,希望通过阅读此文,你可以从此知道自己的架构师之路该怎么走。
什么是架构师?
在开始具体的细节之前,我们先来理清两个定义。
A software architect is a software expert who makes high-level design choices and dictates technical standards, including software coding standards, tools, and platforms. The leading expert is referred to as the chief architect.
软件架构师是一个软件专家,他(她)负责做出高阶设计选择和输出技术标准,包括软件编码标准、工具和平台(框架)。首席专家(leading expert)也被称为首席架构师(chief architect)。
(来源: Wikipedia: Software Architect)
Software architecture is the fundamental organization of a system, represented by its components, their relationships to each other and to the environment, and the principles that determine the design and evolution of the system.
软件架构是一个系统的基本(基础)组织。包含组件,他们之间的关系以及与周边的关系,设计原则,以及系统演进。
(来源: Handbook of Software Architecture)
架构的级别
架构可以被抽象为几个级别(level)。级别决定了要选择哪些对应的技术。市面上有多种分类方式,我个人喜欢把它分为三个级别:
应用级别(Application Level): 架构最下层级别(lowest level)。只关注一个单一的应用。非常的关注细节,关注底层设计( Very detailed, low level design)。沟通往往只限于开发团队内部。
解决方案级别(Solution Level): 架构的中间级别(mid-level)。关注的是一个或多个应用,从而满足某个业务需求 (业务解决方案)。有点高,但主要还是low-level设计。沟通跨多个开发团队。
企业级别(Enterprise Level): 架构最高级别。关注多个解决方案(solution)。高级(High level), 抽象设计(abstract design), 需要总览全局,总览多个解决方案和多个应用架构师。沟通横跨整个组织。
有时候,架构师是也被戏称为“胶水(粘合剂)”,不同利益相关者之间的胶水,举三个例子:
水平: 业务、开发人员或不同开发团队之间的沟通桥梁。
垂直: 开发人员和管理人员之间的沟通桥梁。
技术: 不同技术或项目(产品)之间的集成桥梁。
软件架构师要做的几个典型活动:
在搞清楚要使用的技术之前,我们先要明白软件架构师要做的几个典型的活动。以下是我梳理的几个典型的活动:
确定和决定要使用的开发技术和平台。
定义开发标准。比如,编码标准,工具,代码review流程,测试方法等。
协助识别和理清业务需求。
设计系统和基于需求做出决策。
记录和沟通架构定义、设计和决策(Document and communicate architectural definitions, design and decisions)。
检查和review架构和代码。比如,检查确定的模式和编码标准的实现是否合理。
与其他的架构师和利益相关者协作。
开发人员的教练和顾问。
细化并把high level的设计具体到low level设计。
注意:架构是一个持续的活动,尤其是在敏捷开发团队中。因此,这些活动得一遍一遍的重复迭代, over and over again。
软件架构师要掌握的重要技能
为了能够支撑上面列出的活动,软件架构师需要一些必备的技能。根据我过往的经历,以及翻阅资料以及与大佬们进行讨论,最后得出了如下软件架构师必备的10个重要技能:设计,决策,简化,代码,文档,沟通,评估,权衡,顾问,营销。
接下来我们一个个说。对于每种技能,我都提出了一些行动或见解,你可以根据这些来改进你的工作。
(1) 设计
什么是好的设计?这个可能是一个非常重要同时又要挑战性的问题。分为理论和实践。就我的经验,二者的结合是最有价值的。
知道基础的设计模式:模式是一个非常重要的工具,是架构师开发可维护系统的重要工具之一。记住,你要想开发出可维护的系统,请记得适当地运用设计模式。通过模式你可以重用那些已经被证明可以解决常见问题的设计思路。去看看GoF(Gang of Four)写的有关设计模式的书吧,尽管这些模式已经20多年了,但依然是现代软件架构的基础。比如Model-View-Controller (MVC) 模式就可以用于多个领域,甚至是一些更新的模式的基础,比如MVVM。
对模式和反模式进一步钻研:如果你已经知道了所有基础的GoF设计模式,接下来可以扩展自己的知识储备去学习更多的软件设计模式,或对你感兴趣的领域进行垂直钻研。我个人比较喜欢Gregor Hohpe写的一本书叫:Enterprise Integration Patterns: Designing, Building, and Deploying Messaging Solutions。这本书主要的内容是系统之间的数据交换(应用集成方面)。
知道质量度量(quality measures):确定和定义架构不是终点。你还需要让你的系统可维护、可靠、适应性好、安全、可测试、可扩展、可重用等。所有这些都满足了,才算是一个好的架构。你可以去百科上去看看有关quality measures的内容。不过理论固然重要,但实战同样重要,甚至更重要。千万不要变成“象牙塔架构师”(http://www.gitshah.com/2011/01/ivory-tower-architect.html)。
尝试并了解不同的技术栈:我认为这是非常重要的,如果你想变成一个更好的架构师的话。尝试去了解新的技术栈,然后学习下这些技术是怎么实现的。不同的新的技术一般是使用不同的设计思路和模式。简单地去看看PPT之类的你可能并不能学到什么,你只有亲自去实践了,才会感受到痛苦和甜蜜。一个架构师不能只是面广,在某些领域还要扎得深。也许hold住所有的技术栈不是最重要的,但你需要在你的某个最重要的领域要有独到和扎实的见解。同时你也学习一下不属于你领域的技术,比如你是Java,那么你也要学习一下JavaScript等前端语言或技术,反之亦然。
分析和了解框架中应用的设计模式:你可以去研究当前任何开源的或正在使用的框架,比如Angular. 你可以学习到在实践中的很多设计模式,比如Observables。尝试去搞懂该模式在这个框架中是如何被使用的,为什么它这么做。如果你真的狂热,也可以看看源码并且搞懂它是如何实现的。
保持好奇并去参加各种技术聚会:在德国,我们有个Java User Group (JUG) 组织,这个组织在每个大点的城市都有。我们会讨论各种topic,从low level的编码到上层的有关架构的主题。我真的热爱这些活动,因为它可以增强你的思维能力和扩大你个人的社交网络。
(2) 决策(决定)
架构师需要能够做决定并且引导项目或整个组织朝着正确的方向迈进。
知道什么是重要的:不要浪费时间在那些不重要的决定或活动上,学会认识什么是重要的。目前看来也没什么书籍教你识别这些。我个人有个原则,每当我要评价一件事是否重要我就会考虑这两个方面:(1) 概念完整性(Conceptional Integrity): 如果你决定以某种方式去做,那么就干,即使有时候会有更优的方案。通常来说,这会使得你有一个直接的全局的概念,使得更容易理解和更容易维护。(2) 统一性(Uniformity):比如如果你有名称的一些约定,当然无论是小写还是大写,至少让每个地方都是用同样的方式,比较统一。
优先级: 有关这方面建议去看一下Weighted Shortest Job First (WSJF) 模型,这个模型被广泛用于敏捷软件开发中。尤其是时间紧迫性( time criticality)和降低风险(risk reduction)对于评估架构决策优先级至关重要。
知道自己的能力: 不要对你不了解的事情做决策和决定。各级干各级的事情,要理清每一层的责任,然后对你所负责的层去做决策。如果有多个架构师,那么你应该遵循目前你所安排的架构级别。作为一个lower level架构师,如果对higher level的架构不满意,可以提建议,而不是做决定。此外,我建议始终与同伴一起检查关键决策。
评估多个选项:应该总是给出多种方案,这样才能进行做出决策和决定。不要只给一个方案,听着感觉就是你没有认真工作一样。另外只有一个方案的时候,也没法做出一个合理的选择,因为只有一个方案。另外就是要定义一些指标和标准,通过这个来衡量哪个方案好,哪个方案不好,最好不要去凭感觉。比如:license花费或成熟度(本文有讲到成熟度模型)。这样才能做出一个更好的决策。
(3) 简化(化繁为简)
记住一个解决问题的原则Occam’s Razor。 这个原则告诉你解决问题要简单。这个原则里有一句话叫:最简单的那个solution往往是最好的。我总结这个原则的核心是:如果你对某个问题有多个假定解决方案,这很有可能就是错的,或者导致没必要的复杂的解决方案。多个假定方案应该被简化到只有一个好的解决方案。别提出来一大堆解决方案,说这个也可以,那个也可以,说明是有问题的。
矫正解决方案:通过对解决方案的矫正,有助于你发现最简单的那个方案,通过从不同的角度和位置去看,往往会得到不错的效果。你可以从上到下的想一遍,然后再从下到上的想一遍。如果你有一个数据流(data flow)或流程,那么你可以先从左往右想一遍,然后从右往左想一遍。与此同时问自己一个问题:“在理想的世界里,你的解决方案会发生什么?” 或:“公司或指定人员会做什么?” 这两个问题会强迫你把解决方案减少到如Occam’s Razor建议的那样。
退一步海阔天空: 经过了激烈而漫长的讨论,通常会得出一个高度复杂的涂鸦。但千万也永远都不应将这个视为最终结果。这时候,你需要后退一步:再次查看全局(抽象级别)。回到最初的本心,还是有意义吗?然后再次在抽象级别上进行遍历并进行重构。做这一步有时候让结论更加清晰,而不至于第二天继续进行方案的讨论。至少我的大脑需要一些时间来处理并提出更好,更优雅,更简单的解决方案。人的脑子是需要时间来思考的。
分解成一个个小问题(Divide and Conquer): 简化问题的一个好办法就是把问题切分成多个小问题然后挨个解决。这让我想起了自己小时候打扫院落的场景,看着偌大一个院子,看着就烦,于是我决定把院子划分成三个小块,然后一个个去打扫,这让我的心理负担减轻了不少。一个个小块打扫完了,最后再整体查看下整个院子还有没有边边角角的地方需要打扫。总览一下全局,然后整个院子就打扫完了。再枯燥的生活,都可以发现一些乐趣。
重构并不可耻: 有时候,你可能一时半会想不到更简单的方案,你不妨就从一个复杂的方案开始做起,先做着,等到之后再进行重构,这时候再去重新思考解决方案。重构并不可耻,但重构之前要注意一件事情:足够的自动化测试以确保你所重构的地方的功能正确和满足利益相关者的需求。学习更多重构的知识,我建议你可以读读《重构、改善既有代码的设计》 “Refactoring. Improving the Design of Existing Code” ,这本书是 Martin Fowler写的。
(4) 代码
即使你是一个企业级别的架构师,就最顶层的那种架构,你依然应该知道开发人员在他们每天的工作中主要做些什么。如果你不能明白某个东西如何实现的,你可能会面临两个主要问题:
(1) 开发人员有可能不会接受你说的。
(2) 你也不会明白开发人员要什么和面临的挑战。
有个辅助项目(Have a side project): 跟进一个辅助项目,可以让你了解到新的技术和工具,以了解到当今和未来的开发方式。Kurt Schneider写的“Experience and Knowledge Management in Software Engineering”(软件工程中经验和知识管理)一书中说经验是所见、情感和假设的结合。看书固然是好事,但这只是书本知识(book knowledge)。只有当你自己尝试去做事情本身,然后你感受到情感和发生情绪,然后有了对事物好坏的判断。你使用技术的时间越长越能做出正确的评判。这有助于你在日常的工作中做出正确的判断。当前有大量的语言和框架,只有你对这些有一定的经验和了解后才能做出正确的决策,从而引导开发人员朝着正确的方向迈进。还是那句话,记住经验的定义:所见、情感和假设。要想有经验就要去动手!
找到正确的事去尝试:你不可能去尝试所有事情。这是不可能的。你需要一个更加结构化的方法。有一个来自ThoughtWorks不错的方法是技术雷达(Technology Radar)。他们把技术、工具、平台、语言和框架分为四类:Adopt,Trial,Assess 和 Hold。Adopt(采用) 意思是 “强烈的感觉到已经可投入到生产中使用了”,Trial(试用) 意思是 “可以先在某个项目中做尝试,在这个项目中做到风险可控”, Assess(调研) 意思是“可以探索下对公司有哪些影响”, Hold(保留) 意思是 “谨慎使用”。通过这种分类,更容易获得新技术的整体情况及其准备情况,以更好地评估下一步要干什么。
(5) 文档
架构文档有时候很重要,但有时候又不重要。重要的文档比如架构决策或编码指导手册。编码开始之前通常需要初始文档,并且需要不断完善。其他文档可以自动生成,因为代码也可以是文档,例如UML类图。
Clean Code:代码是最好的文档,如果你写得足够好。一个好的架构师要有能力分辨出好代码和烂代码。著名的书:“Clean Code”。
如果可能的话,尽可能自动生成文档:手动写文档的坏处不多说,把 Swagger 和 RAML 或者公司内部开发的文档系统快点用起来吧。
文档尽可能少(As much as necessary, as little as possible):文档尽量少。无论您需要写什么文档(例如决策文档),都应尝试一次只关注一件事,并且仅包含关于这件事的必要信息。大量的文档很难阅读和理解。附加信息应放在附录中。特别是对于决策文件,讲一个有说服力的故事更为重要而不是仅仅发表大量的论证。而且,这可以为你和你的同事节省很多时间,因为他们要阅读你的文档。看看你过去输出过的一些文档(源代码,模型,决策文件等),然后问自己以下问题:“是否包含所有必要的信息才能理解它?”,“确实需要哪些信息?可以省略吗?”和“文档中是否有红线?”。一句话,不要废话。
(6) 沟通
不多说,沟通很重要。
学习怎么和别人沟通你的观点: 推荐一本书 “UZMO — Thinking With Your Pen” 。作为架构师你经常参会,甚至主持会议,所以你得学会如何和人们沟通你的想法。
通过演讲宣贯:一开始你可以向你身边的朋友表达,然后范围慢慢扩大,最后向众多人演讲来表述你的观点。如果你对此感到不适,你需要走出舒适区来加强提高这一点。保持耐心,这个可能需要一些时日。(有时候大佬的一句鼓励,会让你释放掉过往的不自信,开始相信即使最差发挥大家都会感觉到还不错。)
确定沟通的人群level:不同的利益相关者有不同的兴趣和视角。不同的人群需要单独的针对某一级别的人群去定向沟通。在沟通之前,请确认你要沟通的人群,比如抽象性、内容、目标、动机等。比如开发人员关注一些解决方案的微小细节,而管理者更倾向怎么省钱。
经常沟通:一个再好的架构没人知道它的价值依然为零。分发对应级别的架构,然后安排会议与开发者、架构师和管理者分享未来的和已经在践行的架构。
要透明:定期的沟通只能部分缓解透明度问题。你需要把决策的原因透明化。特别有的人可能没有参加决策过程的情况下会很难理解决策以及其背后的原因。
随时准备演讲:把常见问题放在一个显眼(易找到)的地方,随时应对人们提出的问题,这样有时候会保护你。
(7) 估算和评估
知道基本的项目管理和原则: 作为架构师你经常会被问到如下问题,多久完成?得花多少钱?需要几个人?用到哪些技术?等。你需要学习一些估算技能。比如敏捷中的估算法等,建议到网上查阅这部分的资料。
评估未知架构(Evaluate “unknown” architecture):作为一个架构师你也要能够去评估架构的适用性,针对目前和将来的适用性。这不是一个简答的事情,但你可以准备一些问题,然后去使用,以下是一些通用的问题:
(1) 设计实践:
这个架构用了哪个模式?有没有被正确的使用?
这个设计遵循红线(red line)了吗?这个设计有没有能够可持续(uncontrolled growth)?
有没有一个清晰的结构和各自领域的单独关注有没有分布合理?
(2) 开发实践:
代码指引手册有没有到位?遵循了吗?
代码版本管理怎么做的?有没有版本化?
部署是怎么分布的?
(3) 质量保障:
自动化测试覆盖率怎么样?
静态代码分析有没有做?分析结果怎么样?交叉检查有没有做?
(4) 安全:
有哪些安全概念到位?
内置安全?
渗透测试或自动安全分析工具是否到位,经常在用吗?
(8) 权衡(balance)
质量是有代价的:早先我谈到过质量和非功能性需求。如果你过度设计架构,则会增加成本,并可能降低开发速度。你需要权衡架构和功能需求。应避免过度设计。
解决矛盾目标:一个典型的矛盾目标的例子就是短期和长期目标。项目往往趋向于构建一个最简单的方案来解决问题而架构师则具有长期的眼光和愿景。一般情况下,最简单的方案往往都不能满足长期目标和愿景。为了避免技术实现步入错误的方向,有两件事情需要考虑:
(1) 开发人员和业务需要明白长期愿景和目标,知道调整成新的解决方案可以带来好处。
(2) 负责预算的管理人员需要知道对财务的影响,没有必要100%站在长期愿景一边。
冲突管理:架构师经常是多个不同背景的团队的粘合剂(胶水)。有时候在不同的level之间的交流会发生冲突,需要你去找到一个平衡的解决方案,这可能会对长期战略的目标造成影响。我的解决之道是Schulze von Thun的四眼模型( “Four-Ears Model” of Schulze von Thun)。基于这个模型,可以帮你搞定一些事情。但这个理论需要多实践几次才能熟练掌握,可以在交流研讨会上多用几次。
(9) 顾问和教练
主动询问,而不是被动等待,而且你需要有预见,预见接下来的几周内会发生什么,然后规划相应的步骤。
有远见:如果你被分配入一个项目,不管是传统的瀑布式方法还是敏捷方法,你总是需要有一个你要完成的中期和长期目标。这不是一个具体的涉及到细节的概念,更多的是一个road-map,可以引导每个人进行工作。由于你不可能一次完成所有事情,它是一个长期持续的过程,我倾向使用成熟度模型(maturity models)。它可以给出一个清晰的结构,这个结构容易落地而且每次都能给出当前进度所处的状态。对于不同的方面,我使用不同的模型。比如,开发实践或持续交付。在成熟度模型中,每个level都有清晰的指标,这些指标都遵循SMART原则,这样就能衡量你是否完成了目标。一个不错的例子就是持续交付,这个你可以看看有关持续交付的文章,其中就用到了成熟度模型来衡量持续交付的水平。
构建实践社区 (CoP:community of practice):在一个有共同兴趣爱好的组织中,交换经验和知识有助于分享想法和统一方法。比如你可以把所有的Java开发和架构师们聚集起来在一个屋子里,每隔三个月,讨论过去和现在面临的挑战并且分享他们是如何解决问题的,他们的一些新的方法论和解决方法。架构师们可以分享、讨论和对齐他们的愿景,开发人员可以分享经验经历,然后相互学习。这样的回合非常有利于公司,也有利于个人自己的发展。因为它有助于建立更强大的网络和传播思想。可以去看看这篇来自SAFe Framework的Communities of Practice,它解释了在敏捷环境中的CoP的概念。
进行公开讨论:造成误解和模棱两可的源头之一就是缺乏沟通。每周花三十分钟的时间来和同伴交换热门主题。这样的讨论可以没有议程,任何事情都可以讨论。也可以尝试总是当场解决小事。对于更复杂的主题则需要专门安排时间。
(10) 营销
你的点子和架构再好,当你讲给别人听的时候,没人响应你,那么说明你可能缺乏一些营销技能。
激励并说服:别人凭什么买你的产品?你需要展示产品的价值和好处 。你可以说出几个核心的点,比如5个点或3个点,你需要包装的好,而且让别人容易理解(这里不是让你过分(虚假)包装,但包装是必要的)。没人喜欢一个整天穿着不整的人。
(1) 原型:为你的idea搞个原型。这样让别人一眼就知道你的产品最终的形态。这里说的产品指的是你的架构。
(2) 小短片:PPT有时候会让人烦躁,有时候你可以祭出一些小短片来表达你的观点和方向。但是还是请不要过度营销,否则未来没人会理你的。
为你的idea坚持到底:人们有时候不喜欢你的观点或他们没时间follow你。如果你真的对你自己的idea有信心,那么你需要有屡战屡败,屡败屡战的心态。这个有时候很有用。架构决策有时候涉及到长期目标,往往没那么容易:开发人员不愿意改,因为他们觉得开发起来复杂。管理者也不喜欢,在他们看来,对短期效益来说成本很高。这时候你要愈挫愈勇。
找到同盟:有时候你需要寻找盟友,使用你的网络。如果你没有网络,那么现在就开始构建你的网络。一开始你可以和你的同伴分享你的idea,如果他们喜欢,那么你可以在向其他人推销的时候,你至少可以说你的观点目前被哪几个人支持。如果他们不喜欢,你可以问问原因,你可以获得更多然后改进idea,或者你的故事没有足够的说服力。下一步你可以找一些具有决定权的盟友,进行公开的讨论。如果你害怕讨论,请尽量克服它,有时候你需要离开你的舒适区。
重复它,相信它:有一项研究表明重复不断的广播一个观点,可以让人们相信这个观点,即使是只有一个人给你广播这个观点 (来源: The Financial Brand)。这也是很多那些西方的新闻报纸重复的发布有关川普的丑闻的奥秘所在,时间久了,人们就会相信川普是个大坏蛋。但这个策略要谨慎使用,毕竟你不是在搞政治,你需要道德。
相信本文会成为你在架构师道路上的一篇工具文,本文从作者的亲身经历以及综合业界大佬们的见解,最终梳理出了成为架构师所必备的技能清单并给出建议,希望此文可以改善你的工作!
备注:文中部分场景结合了一些译者本人的经历。
相关阅读:
Apache的架构师们遵循的30条设计原则
关注一波?