软件架构师 第一部分 基础篇 第四章 识别架构特性

识别架构特性是创建架构或确定现有架构有效性的第一步。 为给定的问题或应用程序识别正确的架构特性(“ -ilities”),不仅要求架构师理解领域问题,而且还与问题域相关利益者合作,从领域角度确定什么是真正重要的。

架构师通过从领域关注点,需求和隐式领域知识中提取出来,至少可以用三种方式揭示了架构特性。我们在这里讨论了前面讨论过的两个隐含特性。

从领域关注点中提取架构特性

架构师必须能够翻译领域问题,以识别正确的架构特性。例如,可伸缩性是最重要的,还是容错性,安全性,还是性能?也许系统需要将所有四个特性组合在一起。理解关键领域目标和领域状况,架构师可以将这些领域关注点转换为“ -ilities”,然后为正确和合理的架构决策奠定基础。

与领域相关方合作定义架构特性的一个技巧是努力使最终清单尽可能短。架构中常见的反模式是尝试设计一种非常的通用架构,该架构支持所有架构特性。架构支持的每一种架构特性使得整个系统的设计变得复杂;在架构师和开发人员甚至开始解决问题域(编写软件的原始动机)之前,支持太多的架构特性导致越来越大的复杂性。不要着迷于特性的数量,而是要保持设计简单的动机。

案例研究:VASA

瓦萨(Vasa)最初是关于过度指定架构特性并最终失败项目的故事。它是1626年至1628年间由一位国王建造的瑞典军舰,他想要有史以来最宏伟的战舰。到目前为止,般要么是运输部队,要么是战舰-瓦萨两者都要兼顾!大多数船只有一个甲板-瓦萨有两个甲板!所有的大炮的大小都是类似船只的两倍。尽管专业的造船者(最终不敢拒绝阿道夫斯国王)感到有些恐惧,但造船者还是完成了建造工作。为了庆祝,这艘船驶入港口,向一侧开炮致敬。不幸的是,由于这只船很重,它翻了并沉到了瑞典海湾的底部。20世纪初期,有人打捞出来了这只船,该船现在位于斯德哥尔摩的一家博物馆中。

许多架构师和领域关键用户希望确定应用程序或系统必须支持的最终架构特性的优先级。尽管这是合乎需要的,但在大多数情况下,这是很蠢的事,不仅会浪费时间,而且还会与主要的关键用户产生很多不必要的挫败感和分歧。所有关键用户很少会就每个特性的优先级达成一致。更好的方法是让关键用户从最终列表中以任意顺序选择前三个最重要的特性。这不仅容易达成共识,而且还引发了关于什么是最重要的讨论,并帮助架构师在做出重要的架构决策时分析了权衡取舍。

大多数架构特性来自于聆听关键领域的关键用户并与他们合作以确定从领域角度来看重要的事情。尽管这似乎是一项简单的活动,但问题是架构师和领域关键用户使用不同的语言。架构师谈论的是可伸缩性,互操作性,容错性,可学习性和可用性。领域关键用户讨论并购,用户满意度,上市时间和竞争优势。发生的是一个“翻译丢失”的问题,在该问题中,架构师和领域关键用户彼此不了解。架构师不知道如何创建一种架构来支持用户满意度,并且领域关键用户也不了解什么是关注的重点,而没有讨论可用性,互操作性,可学习性,和应用程序中的容错能力。庆幸的是,通常可以将领域关注转换为架构特性。表5-1显示了一些更常见的问题域以及支持它们的相应“ -ilities”。

软件架构师 第一部分 基础篇 第四章 识别架构特性_第1张图片

需要注意的重要一件事是敏捷性不等于上市时间。相反,它是敏捷性+可测试性+可部署性。这是许多架构师在转换领域问题时会陷入的陷阱。只关注其中一种配料就像忘了把面粉放进蛋糕糊里。例如,某个领域的关键用户可能会说“由于监管要求,我们必须按时完成日终基金定价。” 效率低下的架构师可能只关注性能,因为这似乎是该领域关注的重点。但是,该架构师将由于多种原因而导致失败。首先,如果系统在需要时不可用,则该系统有多快都没有用。其次,随着领域的增长和更多资金的产生,该系统还必须能够扩展以及时完成日终处理。第三,该系统不仅必须可用,而且还必须可靠,以免在计算日终基金价格时崩溃。第四,如果日终基金定价已完成约85%,并且系统崩溃,会发生什么情况?它必须能够恢复并在价格停止计算的地方重新启动。最后,该系统可能很快,但是否正确计算了基金价格?因此,除了性能之外,架构师还必须同样关注可用性,可伸缩性,可靠性,可恢复性和可审计性。

从需求中提取架构特性

一些架构特性来自需求文档中的明确声明。例如,明确的预期用户数量和规模通常会出现在问题域中。其他方面则来自架构师固有的领域知识,这是领域知识始终对架构师有益的众多原因之一。例如,假设一名架构师设计了一个处理大学生班级注册的应用程序。为了简化计算,假设学校有1,000名学生和10个小时的注册时间。架构师是否应该设计一个假设规模不变的系统,并隐式地假设学生在注册过程中会随着时间的推移平均分配?或者,基于对大学生习惯和倾向的了解,架构师是否应该设计一个系统,在最后10分钟内处理所有1000名试图注册的学生?任何一个了解学生们有多拖延的人都知道这个问题的答案!这样的细节很少会出现在需求文档中,但是它们确实可以为设计决策提供依据。

Katas架构的起源

几年前,著名的架构师Ted Neward发明了KATAS架构,这是一种聪明的方法,它提出了指导初出茅庐的架构师练习从面向领域的描述派生架构特性。来自日本的武术,空手道是一项单独的训练练习,重点在于适当的形式和技巧。

我们如何获得优秀的设计师?当然,伟大的设计师会设计。

弗雷德·布鲁克斯

那么,如果他们的职业生涯只获得最多六次的机会,那么我们应该如何去获得优秀的架构师呢?

为了有抱负的架构师提供课程,Ted创建了第一个架构katas网站,作者Neal和Mark对其进行了修改和更新。kata练习的基本前提为架构师提供了一个用领域术语和其他上下文陈述的问题(可能不会出现在需求中但会影响设计的事物)。小型团队进行45分钟的设计工作,然后向其他小组展示结果,然后由其他小组对谁提出了最佳架构进行投票。真正符合其最初目的的架构套件为有抱负的架构师提供了有用的实验室。

每个kata都有预定义的部分:

描述

系统正在尝试解决的整体领域问题

用户数

系统的预期用户数和/或类型

要求

架构师可能会期望领域用户/领域专家/领域级别要求

几年后,Neal在他的博客上更新了格式,并在每个kata中添加了附加的上下文部分,并增加了重要的注意事项,使练习更加现实。

其他背景

架构师必须考虑的许多问题并未在需求中明确表达,而是通过对问题领域的隐性知识来表达

我们鼓励蓬勃发展的架构师使用该网站进行自己的kata练习。任何人都可以举办一个“午餐会”,一个有抱负的架构师团队可以解决一个问题,并让一个有经验的架构师来评估设计和权衡分析,无论是现场还是事后的简短分析。由于练习是有时间限制的,因此设计不会很复杂。团队成员最好从经验丰富的架构中获得有关遗漏的权衡和替代设计的反馈。

案例研究:Silicon Sandwiches

为了说明几个概念,我们使用了kata架构(有关概念的起源,请参见“ Katas的起源”)。 为了说明架构师如何从需求中获取架构特性,我们介绍了Silicon Sandwiches kata。

描述

#家全国性的三明治店希望能够实现在线订购(除了目前的叫卖服务)。

用户数

#目前几千,也许有一天到百万

要求

 #用户将下订单,然后给他们前往商店拿起三明治的路线(商店必须与包括交通信息在内的多个外部地图服务集成)

 #如果商店提供送货服务,请向驾驶员派发三明治

 #支持移动设备

 #提供全国每日促销/特价

 #提供当地每日促销/特价

 #在线,现场交付时接受付款

其他背景

 #三明治店专营权,每个店主拥有不同的所有者

 #母公司有近期计划向海外扩张

 #公司的目标是雇用廉价的劳动力以使利润最大化

在这种情况下,架构师如何得出架构特性?需求的每个部分都可能对架构的一个或多个方面有所贡献(很多方面不会)。架构师不会在这里设计整个系统——花费大量的精力来编写代码来解决域声明。相反,架构师要寻找影响设计的事物,特别是结构性方面。

首先,将架构特性分为显式特性和隐式特性。

显式特性

明确的架构特性出现在需求规范中,作为必要设计的一部分。例如,购物网站可能希望支持特定数量的并发用户,这是领域分析师在要求中指定的。架构师应考虑需求的每个部分,以了解其是否有助于架构特性。但是首先,架构师应该考虑关于预期指标的域级预测,如kata的“用户”部分所述。

用户数量应该引起架构师的关注,其中第一个细节是用户数量:目前有数千名用户,也许有一天有数百万人(这是一家雄心勃勃的三明治店!)。因此,可扩展性 -处理大量并发用户而不会导致性能严重下降的能力-是最重要的架构特性之一。请注意,问题说明并未明确要求可伸缩性,而是将该要求表示为预期的用户数量。架构师必须经常将领域语言解码为等效的工程设计。

但是,我们可能还需要弹性 -处理突发请求的能力。这两个特性通常看起来是混在一起的,但是它们有不同的约束。可伸缩性看起来如图5-1所示。

5-1。可伸缩性衡量并发用户的性能

 软件架构师 第一部分 基础篇 第四章 识别架构特性_第2张图片

 

另一方面,弹性可衡量流量的爆发,如图5-2所示。

软件架构师 第一部分 基础篇 第四章 识别架构特性_第3张图片

 

5-2弹性系统必须承受大量用户

一些系统是可伸缩的,但不是弹性的。例如,考虑一个旅馆预订系统。没有特殊的销售或活动,用户数量可能会保持一致。相反,考虑音乐会门票预订系统。随着新票的发售,狂热的粉丝将涌入现场,这需要高度的弹性。弹性系统通常还需要可伸缩性:处理突发事件和大量并发用户的能力。

弹性要求未出现在“Silicon Sandwiches”要求中,但架构师应将其确定为重要考虑因素。需求有时会直截了当地指出架构特性,但在问题领域内却有些潜伏。考虑一个三明治店。整天的流量是否一致?还是在进餐时间忍受交通拥挤?几乎可以肯定是后者。因此,好的架构师应该确定这种潜在的架构特性。

架构师应依次考虑所有这些业务需求,以查看架构特性是否存在:

(1)用户将下订单,然后有时间拿起三明治和前往商店的路线(商店必须提供与包含交通信息的外部地图服务集成的选项)。外部映射服务暗示集成点,这可能会影响可靠性等方面。例如,如果开发人员构建的系统依赖于第三方系统,但是调用失败,则会影响调用系统的可靠性。但是,架构师还必须警惕过度指定的架构特性。如果外部交通服务中断了怎么办?Silicon Sandwiches网站是否应该失败,或者在没有交通信息的情况下其效率会降低一点?架构师应始终防止在设计中造成不必要的脆性或脆弱性。

(2)如果商店提供送货服务,请向驾驶员派发三明治。似乎不需要特殊的架构特性来支持此要求。

(3)移动设备的可访问性。

此要求将主要影响应用程序的设计,指向构建便携式Web应用程序或几个本机Web应用程序。考虑到预算的限制和应用程序的简单性,架构师可能会认为构建多个应用程序过于刻薄,因此设计指向了针对移动设备进行了优化的Web应用程序。因此,架构师可能希望为页面加载时间和其他对移动敏感的特性定义一些特定的性能架构特性。注意,架构师不应在这种情况下独自行动,而应与用户体验设计师,领域关键用户以及其他有关方面合作,以审查此类决策。

(4)提供全国性的日常促销/特价。

(5)提供当地每日促销/特价。

这两个要求都指定了促销和特价中的可定制性。请注意,要求1还隐含基于地址的自定义交通信息。基于所有这三个要求,架构师可以将可定制性视为架构特性。例如,微内核架构等架构样式通过定义插件架构,可以很好地支持自定义行为。在这种情况下,默认行为会出现在核心中,并且开发人员根据位置通过插件编写可选的自定义部件。但是,传统设计也可以通过设计模式(例如模板方法)来满足此要求。这个难题在架构中很常见,需要架构师不断权衡各种竞争方案之间的权衡。我们将在“设计与架构和权衡”中详细讨论特定的权衡。

(6)在线,当面或交付时接受付款。

在线支付暗含安全性,但此要求中没有任何一项暗示着安全级别超出了隐含的范围。

(7)三明治店是专营店,每个店都有不同的所有者。

此要求可能会对架构施加成本限制-架构师应检查可行性(应用诸如成本,时间和员工技能集之类的约束),以查看是否需要使用简单或牺牲性架构。

(8)母公司有近期向海外扩张的计划。

这个要求意味着国际化,或国际化。存在许多设计技术来满足此要求,这些技术不需要特殊的结构即可适应。但是,这肯定会推动设计决策。

(9)公司的目标是雇用廉价的劳动力以最大化利润。

这项要求表明可用性将很重要,但是与设计特性相比,它更关注设计。

我们从上述要求得出的第三个架构特性是性能:没有人愿意从性能不佳的三明治店购买,尤其是在高峰时段。但是,性能是一个微妙的概念- 架构师应设计什么的性能?我们将在第6章介绍性能的各种细微差别。

我们还希望结合可伸缩性数字来定义性能数字。换句话说,我们必须建立没有特定规模的性能基准,并确定给定数量的用户可以接受的性能水平。通常,架构特性会相互影响,从而迫使架构师彼此之间进行定义。

隐式特性

需求文档中未指定许多架构特性,但是它们构成了设计的重要方面。系统可能要支持的一个隐式架构特性是可用性:确保用户可以访问三明治站点。可靠性与可用性密切相关:可靠性:确保网站在交互过程中保持正常运行-没有人愿意从继续断开连接的网站上购买产品,从而迫使他们重新登录。

安全似乎是每个系统的隐含特性:没有人愿意创建不安全的软件。但是,可以根据关键程度对其进行优先级排序,这说明了我们定义的内在联系。如果安全性影响设计的某些结构方面并且对应用程序至关重要或很重要,则架构师会将安全性视为架构特性。

对于Silicon Sandwiches,架构师可能会假设付款应由第三方处理。因此,只要开发人员遵循一般的安全习惯(不以纯文本形式传递信用卡号,不存储太多信息等等),那么架构师就不需要任何特殊的结构设计来适应安全性。在应用程序中进行良好的设计就足够了。每个架构特性相互影响,导致架构师过度说明架构特性的共同陷阱,这与未充分说明架构特性一样有害,因为这会使系统设计过于复杂。

Silicon Sandwiches需要支持的最后一个主要架构特性包括需求中的几个细节:可定制性。请注意,问题域的某些部分提供了自定义行为:配方,本地销售和可能在本地被覆盖的指示。因此,架构应支持促进自定义行为的能力。通常,这将属于应用程序的设计。但是,正如我们的定义所指出的那样,部分依赖自定义结构来支持它的问题域进入了架构特性领域。但是,此设计元素对于应用程序的成功并不关键。它是重要的是要注意,选择架构特性时没有正确的答案,只有错误的答案(或者,正如Mark在其著名的引文中提到的那样):

在架构上没有错误的答案,只有昂贵的答案。

设计与架构和权衡

在里面 设计师Silicon Siliconwichs kata可能会将可定制性确定为系统的一部分,但是问题就变成了:架构还是设计?该架构包含一些结构组件,而设计则驻留在该架构内。在Silicon Sandwiches的可定制性案例中,架构师可以选择微内核之类的架构样式,并为定制建立结构化支持。但是,如果架构师出于竞争考虑而选择了另一种样式,则开发人员可以使用“模板方法”设计模式实施自定义,该模式允许父类定义可以在子类中覆盖的工作流。 哪个设计更好?

像所有架构一样,它取决于许多因素。首先,是否有充分的理由(例如性能和耦合)不实施微内核架构?其次,一个设计是否比另一个设计更难获得其他理想的架构特性?第三,在每个设计与模式中支持所有架构特性需要花费多少成本?这种类型的架构折衷分析构成了架构师角色的重要组成部分。

最重要的是,对于架构师而言,与软件系统的开发人员,项目经理,运营团队以及其他共同构建者进行协作至关重要。不应从实现团队中分离出任何架构决策(这会导致可怕的象牙塔架构师反模式)。 对于Silicon Sandwiches,架构师,技术负责人,开发人员和领域分析师应共同决定如何最好地实现可定制性。

架构师设计一种架构,该架构不能在结构上适应可定制性,因此需要设计应用程序本身来支持该行为(请参阅“设计与架构和权衡”)。架构师不应为发现完全正确的一组架构特性而过分强调-开发人员可以通过多种方式实现功能。但是,正确识别重要的结构元素可能有助于简化或更优雅的设计。 架构师必须记住:没有最佳的架构设计,只有最差的权衡取舍。

架构师还必须优先考虑这些架构特性,以尝试找到最简单的必需集合。一旦团队在确定架构特性上走了第一步之后,一个有用的实践就是尝试确定最不重要的一个——如果您必须消除一个,那会是什么?通常,由于许多隐式架构支持普遍成功,因此架构师更倾向于选择显式架构特性。我们定义对成功至关重要的方法,可以帮助架构师确定应用程序是否确实需要每一种架构特性。通过尝试确定最不适用的方法,架构师可以帮助确定关键需求。对于Silicon Sandwiches,我们确定的哪个架构特性最不重要?同样,不存在绝对正确的答案。但是,在这种情况下,解决方案可能会失去可定制性或性能。我们可以消除可定制性作为一种架构特性,并计划将这种行为实现为应用程序设计的一部分。在运营架构的特性中,性能对于成功至关重要。当然,开发人员并不是要构建性能很差的应用,而是要构建一个性能不高于其他特性(如可伸缩性或可用性)的应用程序。

你可能感兴趣的:(软件架构师,其他)