架构思维指用架构的眼光和观点来看待事物,主要包括:

  • 理解软件架构和软件设计的区别,知道与开发团队合作,并让架构发挥作用。
  • 拥有技术广度的同时,保持一定的技术深度,看到别人看不到的解决方案和可能性。
  • 理解、分析、协调各种解决方案和技术之间的权衡。
  • 理解业务驱动的重要性,以及如何将其转化为架构。

架构与设计

软件架构和软件设计的区别往往是一个令人困惑的问题。架构在哪里结束,设计在哪里开始?架构师与开发人员的职责分别是什么?

下图是传统的架构师和开发的关系,架构师分析业务需求,提取和定义架构特性,选择架构风格,以及创建组件,然后交给开发团队,开发团队为每个组件创建类、用户界面,以及开发和测试源码。

这样的架构很少能够成功,因为单箭头穿过架构师和开发人员,意味着架构师的想法和决定很少传到开发团队,而开发团队碰到的架构问题也很少回到架构师那里———这样的模式是脱节的。

想要架构发挥作用,必须打破架构师和开发人员之间的物理和虚拟的障碍,形成一种双向关系。这种模式不仅有利于架构师和开发之间的双向沟通,而且可以让架构师为团队中的开发人员提供指导和辅导。

下图展示了一种双向沟通关系。

与老派的瀑布流程静态且僵化的软件架构不同,当今系统的架构在项目的每一次迭代都会发生变化和发展,架构师和开发团队之间的紧密合作是任何软件项目成功的关键。

技术广度

如果说开发人员必须具备很好的技术深度才能完成工作,那么架构师必须具备大量的技术广度来思考问题。

下图代表知识金字塔,包括三类知识:

  • 你知道的东西(Stuff you know):日常工作中使用的技术、框架、语言和工具;
  • 你知道你不知道的东西(Stuff you know you don’t know):略知一二但没有深入理解或没有专业知识的东西,例如:你可能听过 Clojure,但是不知道怎么使用这种语言进行编码;
  • 你不知道你不知道的东西(Stuff you don’t know you don’t know):你不知道这些东西的存在,是知识三角中最大的一部分;

对开发人员来说,最重要的是顶部的部分。

随着开发人员向架构师角色的过渡,知识的性质发生了变化。架构师的很大一部分价值如何使用技术解决特定问题。例如,作为一名架构师,知道针对特定问题存在五种解决方案比只在一种解决方案上拥有单一的专业知识更有利。

对架构师来说,金字塔最重要的部分是顶部和中间部分。

对于架构师来说,明智的做法是牺牲一些很难学到(hard-won)的专业知识,利用这段时间来拓宽自己的广度。这也是一种取舍。

如下图,“你知道的东西”变小了,只保留一些技术深度(渗透下来的绿色),用来换取技术广度。

知识金字塔说明了架构师和开发人员的不同。

开发人员用他们的整个职业生涯来磨练专业知识,过渡到架构师的角色意味着这种观点的转变。这对许多人来说很难,常导致两个问题:

  • 试图在每个领域都保持专业性,导致任何一个领域都不成功,把工作做得很粗糙;
  • 错误地以为自己陈旧的知识仍然是前沿的,经常在大公司看到这种情况;

向架构师角色过渡的开发人员必须改变他们看待知识获取的方式,平衡关于深度与广度的知识组合是每个开发人员在整个职业生涯中应该考虑的问题。

分析权衡

架构就是你没法用 Google 搜索的东西。

架构中的一切都是权衡。

每个架构问题的答案都包含了“这取决于……”,你没法在 Google 搜索是 REST 还是消息传递更好,是微服务好还是单体架构更好?因为它确实取决于,取决于部署环境、业务、公司文化、预算、时间、开发人员的技能组合以及其他几十个因素。

架构之所以这么难,因为每个人的环境、情况和问题都不一样。

在架构中没有正确或错误的答案,只有权衡。

考虑一个拍卖系统,有以下两种数据消费模式。

图 6: 发布-订阅(pub-sub)消息传递。

图 7:队列,点对点消息传递。

发布-订阅模型的优势:

  • 假如我们要增加一个“竞价历史”新服务,则完全不需要对现有系统进行任何修改;而在队列模型中,我们可能需要修改生产者添加一个队列;
  • 解耦:生产者不需要知道数据有哪些服务在使用、如何去使用;而在队列模型中,生产者需要知道是什么类型的数据,发送给谁。

**架构师的思维需要看到方案的好处和坏处。**队列模型的优势:

  • 任何人都能访问发布-订阅模型的数据,存在数据访问和安全问题。
  • 发布-订阅模型只能接受相同格式的数据,假设新的“竞价历史”服务需要当前的售价以及竞价,但其他服务原本没有这些信息,在这种情况下需要修改数据格式,并且会影响使用该数据的所有其他服务。在队列模型中,这将是一个单独的通道,因此是一个单独的格式,不影响任何其他服务。
  • 发布-订阅模型不支持监控某个主题的消息数量,导致不支持自动缩放。在队列中很容易知道哪个队列消息量大,独立地自动伸缩。请注意,这种权衡是特定于技术的,高级消息队列协议(Advanced Message Queuing Protocol,AMQP)可以支持负载均衡和监控。

鉴于这种权衡分析,现在哪个是更好的选择?答案是什么呢? 这就要看情况了!

理解业务

架构思维就是要理解系统成功所需的业务因素,并将这些需求转化为架构特性(如可扩展性、性能和可用性)。

这是一项具有挑战性的任务,要求架构师具有一定程度的业务领域知识,并与关键业务利益相关者建立健康的协作关系。

平衡架构和编码

架构师面临的困难任务之一是如何平衡架构和编码。

每个架构师都应该进行编码,并且能够保持一定的技术深度(参见“技术广度”)。虽然这看起来似乎是一个简单的任务,但有时却相当难以完成。

架构师需要避免瓶颈陷阱。当架构师掌握项目关键路径内的代码(通常是底层框架代码)的所有权,并成为团队的瓶颈时,就会出现瓶颈陷阱**。架构师不是全职开发人员,需要在开发人员(编写和测试代码)和架构师(画图、参加会议,以及参加更多的会议)之间取得平衡。**

避免瓶颈陷阱的方法:将关键路径和框架代码委托给开发团队中的其他人,然后集中精力在一到三次迭代后对一个业务功能进行编码。

架构师如何才能保持亲力亲为并保持一定的技术深度呢?有四种基本方法可以让架构师在工作中练习,而不必“在家练习编码”(尽管也建议在家里练习编码):

  • 经常做 POC(proof-of-concept),通过考虑实现细节来验证架构决策。例如,如果架构师在两种缓存解决方案中无法抉择,那么可以每种缓存开发一个实例,并进行对比。
  • 处理一些技术债务或架构问题,让开发团队腾出时间来处理关键的功能开发。这些问题通常是低优先级的,一般不会影响迭代。还可以在迭代中修复 bug,在帮助开发团队的同时也保持了编码,还可以找出代码库可能存在的问题和弱点。
  • 通过创建简单的命令行工具和分析工具来帮助开发团队自动化完成日常任务,寻找开发团队执行的重复性任务,并将这个过程自动化。开发团队会感谢自动化。
  • 经常做 code review。虽然并不是实际写代码,但至少参与了源代码的编写。此外,做 code review 还能确保代码符合架构的要求,帮助和指导开发