Salesforce 反模式(二)

原文:annas-archive.org/md5/0b2a0f4d4219209f43dce3a5bbbeb4ca

译者:飞龙

协议:CC BY-NC-SA 4.0

第六章:保持集成清晰

本章探讨了与其他系统集成相关的反模式,这是现代 Salesforce 实施中的一个关键方面。本章的第一部分讨论了集成架构和集成模式中的反模式,第二部分探讨了接口设计和使用中的潜在陷阱,第三部分集中讨论了集成风格的问题。像往常一样,我们通过总结关键要点来结束本章。

在本章中,我们将涵盖以下主要主题:

  • 如何避免滥用技术,避免让系统架构过于复杂

  • 何时适合,何时不适合为集成创建自定义服务

  • 如何避免在设计接口时的常见失败

  • 如何良好地使用基于事件的集成

  • 如何正确地使用集成模式

  • AI 如何影响集成模式

完成本章后,你将对如何更好地选择集成模式和结构化集成架构有一个清晰的理解,通过学习各种可能出错的方式来避免这些问题。随着 Salesforce 的不断发展,理解这些集成反模式对于从事该平台工作的架构师和开发人员来说变得越来越重要。

搞乱集成架构

本节介绍了两种反模式,它们以不同的方式可能会在你的集成架构中造成混乱。我们将首先讨论如何避免错误地使用中间件。

名义上的中间件(MINO)

使用中间件来创建点对点连接,而不是利用其扩展功能

示例

PumpCo 是一家大型 B2B 公司,专注于为工业生产制造泵。它在 30 多个市场运营,历史上在 IT 系统上的投入较少,并且在销售上主要使用手工流程,这些流程在不同国家和产品线之间存在显著差异。

在过去的一年里,他们开始实施 Salesforce Sales Cloud 和 CPQ,以推动全球销售流程的标准化。他们过去在 IT 平台上的一项重大投资是 SAP,基本上,SAP 目前管理着公司所有关键业务。

Michelle 在 Salesforce 实施的早期阶段作为集成架构师加入。集成路线图非常雄心勃勃,因为业务希望看到所有相关数据和流程能够在 Salesforce/SAP 边界上无缝运作。从根本上讲,他们希望能够在 Salesforce 中直接访问所有相关的后台数据和流程,而不需要切换上下文。

一旦完成初步的映射,就有 75 个离散的集成点,涵盖从定价和物流到人力资源等各个方面,需要实现这些集成点,才能提供业务所期望的完整体验。然而,好消息是,许多集成点可以分为相似的领域,例如客户订单接口

来自 Salesforce 和 SAP 方面的架构师讨论了多种替代架构和实现方法,目的是创建少量稳定的接口,以满足大多数用例的需求,但不幸的是,进展缓慢,利益相关者和架构师之间没有真正达成一致。有许多潜在的解决方案和几种可能完成任务的技术,而各方愿意妥协的意愿较低。

双方最终同意让中间件团队来管理这个过程。PumpCo 刚刚购买了一个新的中间件平台,团队正在寻找机会开始工作。

中间件团队将向 Salesforce 暴露服务,并将调用转换为 SAP。任何 API 的修改也将是它的责任。因此,两个平台团队无需就方法达成一致,可以独立工作。

随着项目的推进,米歇尔统计了 Salesforce 调用中间件的接口数量。她数了 45 个。虽然比最初的 75 个少,但随着项目的推进,范围也有所缩小。

这是 PumpCo 集成架构的示意图:

https://github.com/OpenDocCN/freelearn-devops-pt3-zh/raw/master/docs/slfc-anti-ptn/img/B30991_06_01.jpg

图 6.1 – PumpCo 集成架构

从她所看到的,许多这些中间件接口几乎只是简单地将 Salesforce 的调用转发给 SAP,然后再返回。她在想,这真的是最好的方法吗?但这已不再是她的问题。

然而,随着时间的推移,随着 Salesforce 的使用量增加,集成开始出现问题。错误率较高,性能问题,维护变得越来越复杂。总体而言,集成导致了平台上的大多数技术问题。

一名顾问被请来评估情况,并建议对集成架构进行合理化,因为当前的设置实际上包含了通过中间件连接的 45 个日益定制的点对点连接。这种设置带来了很大的失败潜力,且通常很难理解。

米歇尔被要求参与重新设计过程,在几周的设计工作后,他们最终得出了一个与初期项目实施过程中所做的某个迭代方案相差无几的提案。当一位高级利益相关者直接询问为什么一开始不做这个时,没有人能够给出令人信服的回答。

问题

MINO 反模式试图通过引入中间件来减少创建良好集成架构的复杂性。然而,它的做法未能充分利用中间件平台的能力,而是通过中间件重新创建了本应出现在点对点场景中的流。

这种情况通常出现在具有复杂系统景观、系统间有许多接口和接触点的组织中。然而,在这些组织中,通常缺乏协调不同部门之间的技术治理,从而导致集成架构的混乱。

MINO 反模式的另一个常见特征是关键平台上存在过时且不灵活的系统 API,并且很难达成一致的标准表示法来表示这些关键平台上的核心业务实体,这使得无法就通用接口或 API 达成一致。

提出的解决方案

MINO 提出的解决方案仅仅是引入一个中间件平台,而没有过多关注如何使用它。通过引入现代中间件平台,至少可以部分掩盖遗留系统的复杂性和不灵活性,从而取得良好的初步结果。

也就是说,MINO 表面上看似正确,但如果中间件的实现只是以新的形式复制现有的混乱,那么收获相对较小。并不是完全没有收获;你仍然可能获得一些基本的中间件能力,如更好的错误日志记录、重试机制或更易于使用的协议转换。

另一个,往往更具影响力的原因是,这种反模式使得核心平台的团队不必直接处理彼此之间的关系。如果你在 CRM 方面工作,你的视角通常会与在 ERP 方面工作的视角非常不同,尤其是在关键集成的情况下。

MINO 允许不同的团队只需与共同的中间件团队打交道,后者则负责管理其余部分。不幸的是,这通常会导致架构只停留在基础层面。

结果

MINO 的结果往往是将你的系统景观变成比之前更加混乱的“意大利面条”式的架构。毕竟,现在中间件处于核心位置,因此你可以减少对集成细节的关注。

这种忽视通常会带来以下后果:

  • 难以理解的集成架构,存在过多的单独接口和点对点连接,尽管这些连接通过中间件进行调解

  • 维护成本增加,因为复杂度仍然很高,而且现在涉及更多的团队

  • 缺乏技术治理,以及潜在的对这种治理必要性缺乏认知

  • 集成中的错误率增加,以及由于团队试图跨平台追踪错误而导致的修复时间相应增加

  • 性能下降,因为存在更复杂的流程,跨越多个平台

总体而言,如果你只是让中间件充当点对点连接的代理,可能完全不使用中间件更好。

更好的解决方案

MINO 反模式教给我们的是,没有捷径可以走来正确建立集成架构。你必须仔细考虑系统之间的连接和依赖关系,当前及未来的业务需求,主数据的分布情况,关键平台所具备的核心功能,以及如何构建接口和模式,以最佳方式支持这些元素。

以下图展示了一些常见的中间件功能:

https://github.com/OpenDocCN/freelearn-devops-pt3-zh/raw/master/docs/slfc-anti-ptn/img/B30991_06_02.jpg

图 6.2 – 常见的中间件功能

考虑到这一点,你可以选择适合的工具来完成任务,这很可能是一个中间件工具。然而,在你尚未思考清楚将支持哪些跨业务的接口、为不同场景支持哪些集成模式、并确定如何在不同团队之间进行技术治理之前,不能急于选择任何工具,不论它看起来多么酷。接下来我们将讨论下一个反模式——服务膨胀综合症。

服务膨胀综合症

服务膨胀综合症是一种反模式,指的是在没有充分的理由或考虑替代方案的情况下,创建过多的自定义服务。

示例

OmniCo 始终将自己定位为技术领导者,并在多个多元化的服务领域中部署了许多前沿的软件平台。该公司是面向服务架构SOA)的早期采纳者,并结合事件驱动架构EDA)在高速数据和流程中取得了巨大优势。

OmniCo 现在正在实施 Salesforce,作为其旧 Siebel CRM 系统的替代品,后者曾作为许多其他系统的集成中心。Siebel CRM 系统被高度定制以适应 OmniCo 的流程,公司期望新的 Salesforce 系统也能如此。虽然实施伙伴提出了保持标准功能的合理论点,但这与 OmniCo 历史上的做法相悖,且他们并不打算在 CRM 项目中改变这种做法。

下面是旧的 Siebel 设置:

https://github.com/OpenDocCN/freelearn-devops-pt3-zh/raw/master/docs/slfc-anti-ptn/img/B30991_06_03.jpg

图 6.3 – OmniCo 的旧 Siebel 设置

对于负责实施项目集成部分的咨询经理 Erhat 来说,这引发了很多焦虑。他正受到来自 OmniCo 的多位高级利益相关者的压力,要求构建一系列能够融入 OmniCo SOA 的特殊业务服务。

Erhat 曾尝试在纯净的 Salesforce 平台上构建定制的 API,虽然最终成功,但过程既不简单也不快。事实上,考虑到提到的定制服务数量,他对于在时间、预算和具备必要技能的人员限制下的基本可行性存有疑虑。

经过一些反对意见后,他同利益相关者达成一致意见,使用类似于旧 Siebel 系统中用于订单管理的接口来交付两项关键服务,这需要大量时间来在不同模式上重新设计。

这些服务已经交付,但在测试过程中证明非常困难,部分原因是服务的测试协议不完整,部分原因是复杂性异常高。

当头两项服务接近完成时,OmniCo 的企业架构委员会召开了一次危机会议。他们刚刚意识到在新的 Salesforce 设置中,并不是所有由 Siebel 提供的业务服务都将可用。在董事会的几位成员看来,这将从根本上破坏一系列业务流程,因为其他系统需要大幅改变它们的集成方法,或者转向某些步骤的手动处理。

Erhat 对 OmniCo 的流程不太了解,因此无法就案件的优点进行辩论。董事会成员向他提供了另外 13 项服务的定义,涵盖了从潜在客户到现金流程的不同部分,并且这些服务在之前的 Siebel 设置中是可用的。以下是集成的示意图:

https://github.com/OpenDocCN/freelearn-devops-pt3-zh/raw/master/docs/slfc-anti-ptn/img/B30991_06_04.jpg

图 6.4 – OmniCo Salesforce 集成的示意图,不包括 ESB

Erhat 实际上只能在实际层面上进行反对,他这样做了,认为这些服务超出了范围,不包括在定价内,并且他没有团队来提供解决方案。OmniCo 有些不满,并且进行了一些升级会议。然而,最终告诉 Erhat 不要担心——他们会以其他方式解决这个问题。

结果是引入了一个由各种承包商组成的团队,他们将快速构建这些服务,与主要的咨询合作伙伴的团队并肩作战。Erhat 只能等待和观察,看承包商们遇到不可避免的技术复杂性。他在项目上线前离开,留下一些不愉快的味道。

十二个月后,他再次回到了 OmniCo。他被引入作为该公司 Salesforce API 的专家,这些 API 显得非常容易出错且维护成本高昂。

OmniCo 正在寻找建立此类系统的原因以及如何修复它的理由。他们还在考虑不同的方法,比如改变集成模式或引入一些中间件。Erhat 深吸一口气,开始规划分析工作。

问题

服务扩展综合症所构成的问题是如何将 Salesforce 融入现有的企业架构中,同时又要满足这些架构中已经存在的对关键系统能力的期望。这可能是一个 SOA,正如我们例子中所示,或者是一个不同的组织原则,但通常来说,要求关键平台提供非常具体的功能。

这种反模式在各种平台中都很常见,因为它可能影响任何新的集成平台。在过去,这种情况更为常见,因为组织们忙于构建 SOA,而往往没有深入考虑具体服务的组织结构。

这种反模式通常源于对微服务架构的误解,或者是希望通过定制服务解决每个集成挑战的愿望。

今天,这种情况最常见于老旧系统被替换时,所需的接口与内建系统 API 的标准功能不完全匹配。虽然 Salesforce 提供了广泛的 API,但它们非常依赖于数据模型,而许多集成架构是基于不同的原则构建的,例如粗粒度的业务服务,而这些原则与 Salesforce 的数据模型完全不对齐。

提出的解决方案

服务扩展综合症处理的是在集成过程中如何应对这个问题,倡导为每个集成需求不必要地创建新的定制服务。这种方法忽视了利用现有服务或标准 API 的潜力,而这些现有服务或 API 足以满足这些需求,且不会增加不必要的复杂性。

这是另一个反模式,尽管它看起来似乎合乎逻辑,因为毕竟,你是在直接交付业务价值,并且有时符合跨公司技术治理论坛的预期。因此,你可能会在很大压力下走这条路,明知这样做会在长期内对平台造成损害。

因为平台上具备相关能力,而企业环境中又有这种需求,反抗这种反模式有时几乎是不可能的。这一点尤其正确,因为这些成本通常是随着时间的推移才逐渐累积的。

结果

你最先会遇到的服务扩展综合症问题是复杂性和构建成本的增加。尽管在 Salesforce 上创建定制服务是可行的,有时也是正确的选择,但它们很难做到完美。Salesforce 本身并不是一个 API 平台,这也是它几年前收购 MuleSoft 的重要原因之一。

随着时间的推移,复杂性增加将导致维护成本上升,而且不仅仅是 Salesforce 的成本。使用这些扩展服务的各个团队也可能面临重新工作和升级其连接的持续成本。

在 DevOps 环境下,服务过度繁杂会给 CI/CD 管道带来显著挑战,增加的复杂性使得自动化和编排变得更加困难。这种复杂性可能导致更频繁的部署失败,因为众多服务之间的相互作用是不可预测的。此外,潜在问题的增多会延长恢复时间,因为团队必须遍历更多组件以诊断和解决故障。因此,组织可能会发现更难实现 DevOps 旨在提供的速度和可靠性,最终影响软件交付的整体效率。

有时,自定义服务是正确的选择,且其好处可以超越初始构建和维护的成本。但对于我们示例中的 15 个自定义服务来说,这种情况几乎是不存在的。如果你认为你需要这些服务,那么你可能需要重新考虑你的方法。

更好的解决方案

第一个建议是,首先查看标准的集成模式,看看你是否能找到合适的标准技术。也许你可以使用标准的 API,也许你可以使用批处理过程,也许你可以发布事件并让其他系统订阅它们。

你应该广泛地考虑,而不是立刻跳到自定义接口,尽管这看起来是一个好的初步选择。危险在于,你可能会选择看起来光鲜的解决方案,却没有意识到这个决策在长期内的实际成本。

如果你确实决定需要大量的自定义 API —— 在某些情况下这可以被证明是合理的 —— 你应该选择一个专为此目的构建的平台来实施。对于 Salesforce,MuleSoft 是经典的选择,但市场上也有其他可以填补这个空缺的解决方案。

为了增强我们的服务产品,我们可以采取逐步推进的方法:

  1. 识别核心业务能力。

  2. 映射现有的服务和 API。

  3. 识别我们服务中的空白。

  4. 在选择自定义服务之前,考虑标准化解决方案。

此外,我们还可以考虑实施一个强大的 API 管理策略,以促进服务的重用并避免不必要的服务创建。

在 DevOps 环境下,服务过度繁杂可能导致 CI/CD 管道中的复杂性增加,发布管理变得更加困难。因此,采用更为规范的服务创建方法至关重要,因为这与 DevOps 的简化和自动化原则更为契合。这确保了流程的流畅性并提升了整体运营效率。

总体而言,如果盲目地构建服务,你会冒着使你的 Salesforce 界面和集成环境过于复杂的风险。像往常一样,考虑实际的利弊权衡,并基于真实的优缺点做出决策。接下来,我们将进入下一部分,讨论与接口设计相关的反模式。

不当的接口设计

在本节中,我们将探讨影响集成设计的两个常见反模式。在具体层面上,第一个是繁重接口,着眼于接口设计中的问题,而第二个是频繁通信集成,着眼于接口使用中的问题。

繁重接口

当一个接口开始处理太多任务时,你会遇到一系列问题。

示例

Joe 是一个集成架构师,供职于一家专门从事复杂实现的小型 Salesforce 合作伙伴公司,通常需要大量代码或其他类型的定制。他刚刚开始与 RealCo 签订的新合同,RealCo 是一家主要的房地产投资公司,Salesforce 是其整个业务中主要的互动系统。

他最初承包的工作包括为访问估值信息构建一个定制接口,供 RealCo 的合作伙伴在进行交易时使用。信息存储在 RealCo 的 Salesforce 组织中,需要实时可用。

Joe 在 RealCo 的中间件平台上设置了组成接口的 API,并协调对几个不同的 Salesforce 标准 API 和一个自定义 API 的调用,作为实现的一部分。然而,接近新接口上线时,一大堆新的用例掉到了他的桌子上。

这些不仅包括对估值 API 的扩展,例如获取历史估值和趋势数据,还包括完全不同类别的物业数据,包括通过平台事件进行的实时更新、使用变更数据捕获CDC)的数据流变化、建筑结构信息、从各种评估中获取的关键指标访问,以及从 RealCo 合作伙伴进行看房时收集的反馈洞察。

Joe 稍微反驳了一下客户,说如果他早知道会有这么多新的功能进来,他可能会以不同的方式构建 API,可能会做一些在当前上线中不是最优的处理来包含这些功能。

RealCo 的经理专心地听 Joe 讲话,但最终表示,决定是继续增加额外的功能。RealCo 意识到潜在的弊端,但它可以接受这些问题。

在上线前一天,同样的事情再次发生。这一次,信息不仅包括更多与物业相关的信息,还包括完全不同类别的信息,如与物业所在区域相关的人口统计和细分数据,如下图所示:

https://github.com/OpenDocCN/freelearn-devops-pt3-zh/raw/master/docs/slfc-anti-ptn/img/B30991_06_05.jpg

图 6.5 – RealCo PropertyService 视图

没有办法在一天内完成这项工作,RealCo 虽然不情愿,但还是接受了这个事实。然而,它希望 Joe 提供一个计划,尽快将其包含进去。鉴于巨大的压力,Joe 只是扩展了当前的接口,而这个接口现在变得庞大,涉及到几十个 Salesforce 服务,包括标准和自定义服务。

幸运的是,初始上线和随后的更新都相对顺利。RealCo 合作伙伴组织的团队对接口的复杂性抱怨了一些,并报告了若干 bug。但它仍然能够正常工作,合作伙伴们可以继续处理接口所需驱动的各种应用程序。

变更请求的轰炸仍在继续。而且这些变更总是特别紧急,且对于某个合作伙伴的关键用例来说是必须的。更糟糕的是,越来越多的团队依赖于这个接口,这使得升级变得越来越困难。

即使有良好的 API 版本管理,版本之间的变化仍然让合作伙伴团队感到相当吃力,他们大声抱怨频繁的版本变化和 API 实现中逐渐出现的高错误率。

最后的压垮骆驼的稻草出现在新版本发布前发现了一个关键性 bug。Joe 被告知需要优先发布新功能,于是他将一个热修复与新版本一起发布,这实际上强制所有主要合作伙伴进行升级。

然而,事实证明新 API 版本中存在其他破坏性的 bug,这意味着关键合作伙伴失去了访问关键功能的权限,直到 Joe 能够控制住局面,至少一周的时间。

召开了一次升级会议,合作伙伴们可以在会上提出他们的各种投诉。Joe 尽力解释当前情况的历史背景和原因,但不幸的是,复杂的细节在嘈杂的讨论中被淹没了。

Joe 被告知他的合同不会续签,另外一个顾问将被引入来重构和重组接口。他松了一口气,开始期待下一个工作机会。

问题

“胖接口”所带来的问题本质上是接口结构的问题——也就是说,如何安排功能,使得那些需要接口提供服务的客户端可以调用它。

注意

最初,这种反模式更多地应用于 面向对象编程OOP)中的接口。然而,它在集成环境中同样适用。

在接口设计上有几种不同的哲学观点。如今,大多数人本能地偏向于微服务,它们是执行一组单一、明确且连贯功能的小型服务。举个例子,一个通知服务,它的唯一作用就是发送通知。

然而,几年前,人们更倾向于使用粗粒度的业务服务,这些服务为业务流程提供了一个入口点——例如,处理订单。这就是与 SOA(面向服务的架构)相关的基础风格,我们之前曾提到过。

然而,使用臃肿接口时,你违反了大多数(如果不是所有)这些哲学中普遍适用的一个基本原则。这个原则叫做接口隔离,要求客户端永远不应被迫依赖它不需要的方法。

提议的解决方案

臃肿接口提议简单地将逻辑继续添加到现有接口中,因为这是最简单的做法。设计良好的隔离接口可能需要更多的工作和仔细思考,而将所有功能放在一个接口中则简化了问题。

此外,你有时可能会说服自己,所有功能确实应该放在一起,因为它们之间有一些间接的共同点,尤其是当你有大量消费者使用你所暴露的功能时,这种情况可能尤其成立。

这种反模式通常只是随着时间推移产生的结果。代码最初做一件事,然后做另一件事,接着做第三件事,最终它什么都做,甚至连狗都带走了。

如果不是因为有许多隐性成本需要考虑,这一切看起来应该是好的。我们接下来将探讨这些问题。

结果

如果你一直在阅读本书,你一定会熟悉臃肿接口反模式的结果。这类似于在多个领域中可能发生的糟糕结构后果。

当你的接口变得臃肿到不可管理的地步——也就是说,它现在包含了太多不同的功能,实际上已经变得无法管理——你可能会看到以下一些或全部后果:

  • 复杂性增加,导致变更成本、周期时间和错误率的提高

  • 维护成本增加,因为错误会带来额外的后果,客户端依赖接口的各种现有部分,且代码库庞大且难以理解

  • 只有某些开发人员能够对臃肿接口进行更改,因为更改接口的互依性和对接口用户的影响需要对整个代码库有深入的了解。

  • 接口中的 bug 可能会影响那些根本不使用失败方法中暴露功能的客户端

  • 大量客户端依赖接口,使得解开现状变得困难

总的来说,尽管这种模式乍一看可能只是一个轻微的代码异味,但如果你在中心位置有一个失败的臃肿接口,它实际上可能会为你的公司范围的集成架构带来严重问题。

更好的解决方案

这种反模式是少数几个可以通过应用良好实践和开发过程中的自律来避免的。如果你严格遵循接口标准,并在添加新功能时始终应用接口隔离原则,这种反模式将永远不会发生。

尽管可能会有诱惑去走捷径,而这些捷径短期内可能不会带来严重后果,但你应该了解长期后果,并应用良好的设计和编程实践。这也是一个架构师或开发人员可能会有很多发言权的领域,因为这是一个技术性太强的领域,大多数业务用户难以真正发表意见。

难点在于,在面临巨大的交付压力时,如何保持所需的纪律性。当然,希望通过在描述中提到的要点,能帮助你抵制“速成思维”的诱惑。

聊天集成

聊天集成是一种反模式,其中集成了任意模式,导致对一个或多个接口发出过多的调用,常常导致性能下降。

示例

WoodCo 是一家有着悠久历史的家具制造商,专门为富裕客户定制高端家具。近年来,由于推出了基于 Salesforce Experience Cloud 并结合 B2B 电商的电商平台,WoodCo 的业务增长迅速,该平台将客户社区与指定负责其项目的家具制造商直接连接起来。

这样,客户和制造商可以直接连接并讨论定制建造的要求。客户还可以在家具的整个生命周期中跟踪其进度。

WoodCo 负责管理项目建设,包括预算,并确保尽可能通过友好协商解决任何冲突。他们在一个旧的项目控制模块中跟踪这些项目,该模块也用于管理他们自己的业务。

这个项目模块最近通过一个定制构建的 REST API 进行了扩展,该 API 建立在传统应用程序之上。供应商专门为 WoodCo 构建了这个 API,花费巨大,但这被认为是毫不犹豫的选择,因为它将直接实现门户与项目控制模块的集成,取代了当前由数据输入人员手动将所有数据重新输入项目控制模块的过程。

Lina 被 WoodCo 聘用,负责数字化项目,其中第一个项目是将电商平台与项目控制模块连接起来。她委托了一家专业的 Salesforce 合作伙伴来主导这一工作。

他们建立了一个轻量级的中间件平台,订阅 Salesforce 的事件并将其转换为新 REST API 格式的 REST 调用。由于 REST API 不支持任何聚合,所以它严格遵循一对一事件调用。

在 Salesforce 方面,事件最初仅在状态更新时触发,或者在输入或更改诸如项目标题之类的重要信息时触发。然而,随着时间的推移,应该扩展到跟踪项目中的活动状态以及制造商与客户之间的沟通。

你可以在这里查看 WoodCo 集成架构的概览:

https://github.com/OpenDocCN/freelearn-devops-pt3-zh/raw/master/docs/slfc-anti-ptn/img/B30991_06_06.jpg

图 6.6 – WoodCo 集成架构

集成成功上线,WoodCo 的每个人都为此欢呼。然而,尚未实现完全的好处,因为活动和客户沟通仍然仅存在于客户门户中,而 WoodCo 员工仍然通过重新输入数据并在多个系统间切换来绕过这个限制。

最终,更新的日子到来了,这次更新将包括完整的同步,大家兴奋地等待着上线。然而,在启动后的几分钟内,项目模块崩溃了。

供应商进行调查并将错误归因于与初始同步相关的可扩展性问题。上线被推迟到周末,并经过多次重启后,初始数据确实得以同步。

星期一到来,大家开始愤怒地使用系统。项目控制模块的慢速问题引发了一些抱怨,但至少集成似乎在工作,并成功传递了关键数据。

然后,在周二早上,一名管理员正在客户门户上运行一些常规批处理作业。几乎立刻,项目控制模块再次崩溃,新的集成被下线以便恢复。

WoodCo 的首席信息官(CIO)召集了一个危机会议。这一问题已经引起了 CEO 的关注,需要采取措施解决。Lina 委托她最有技术才能的下属 Aki 找出根本原因。

此时,两个供应商互相指责失败,并且都不肯采取单方面行动解决问题。因此,Aki 直接深入到技术设置的中间。

他检查了 Salesforce、中间件和项目控制模块的日志文件和代码,几个小时后,他确认找到了根本原因。问题出在一个递归更新规则上,该规则将某些更新(例如更改计费代码)应用于父项目的所有活动。

在新更新之前,这并不重要,因为活动层级的变动并没有进行同步。然而,更新后,每一次这样的变化都会触发 Salesforce 上成百上千个更新事件,每个事件都会触发对项目控制模块的调用。

你可以在这里看到 WoodCo 项目的整体结构:

https://github.com/OpenDocCN/freelearn-devops-pt3-zh/raw/master/docs/slfc-anti-ptn/img/B30991_06_07.jpg

图 6.7 – WoodCo 项目结构

这个遗留系统可能同时处理一到两个这样的更新,同时仍能正常服务用户,但任何超过这个数量的更新都会引发问题——首先是性能下降,最终导致崩溃。当管理员启动批处理作业以重新分配一些项目标识符PIDs)时,这触发了数十个项目及其活动树的更新,在此过程中导致项目控制模块崩溃。

在晚上的会议上,气氛沉重。然而,随着 Aki 解释事情的事实,没人能真正反驳。决定是暂时禁用活动级别,并让 Aki 领导一个团队重新设计集成,以避免过载项目控制模块。

问题

聊天式集成反模式是解决其他集成问题的副产品,出于某些原因,这些问题需要系统之间非常频繁的通信。通常,像我们示例中的问题涉及在两个或更多系统之间转移状态。

它是一个在开发过程中很难发现的反模式,因为它通常只在规模扩大时才会变得成问题。毕竟,在大多数测试场景中,除非是明确的性能测试,否则我们更新的数据不足以真正达到一个有问题的集成调用数量。

问题的实施可能是由于不良的实践,例如在循环中为每个记录单独发出调用,或者可能更为隐蔽,如我们示例中的情况,订阅事件被 1:1 映射到中间件中的 REST 调用。不管是哪种情况,至少是浪费,最坏的情况下是灾难性的。

提出的解决方案

如前所述,聊天式集成往往是解决另一个问题的副产品;因此,它并不完全符合我们的模型。然而,就算我们可以说它提出了一个解决方案,那就是跨系统边界进行尽可能多的调用,以支持业务用例,而不考虑系统的限制。

这通常是出于简化的原因。一旦你开始引入批量处理、排队、系统延迟、调用聚合、限流或你可能考虑的任何其他机制来限制调用其他接口的速率,你也会在实现中引入复杂性。

你可能已经注意到,其他反模式表明,复杂性往往是导致严重负面后果的驱动因素,因此避免它通常看起来是件好事。然而,这是一个让解决方案尽可能简单,但不要 更简单的例子。

在聊天式集成中,你实际上让解决方案变得过于简单,因为它在没有额外复杂性的情况下不能满足基本的功能需求。这可能意味着你需要更多的时间和额外的工具来使解决方案正常工作,但在这种情况下,真的没有捷径可走。

即使使用低代码集成工具,这一点依然成立,这些工具的销售目的是让你的生活变得更简单。如果集成策略错误,集成就无法按预期工作。毕竟,架构就是在权衡中做出选择。

结果

聊天式集成的结果形成了一个谱系:

  • 通常,如果目标系统能够应对大量的调用,并且你也保持在 Salesforce 的限制内,那么不会立即出现后果。

  • 有时你会看到性能下降。这可能是因为在 Salesforce 端,如果你在一定时间内发起了太多异步调用,而在目标端,如果你开始超载它的容量,也可能发生类似问题。

  • 性能下降可能会转化为周期性错误,特别是当你开始遇到超时问题或目标服务器临时过载时。

  • 最终,你有时可能会使目标系统彻底崩溃,导致严重错误。

你可以参考以下图示以获得可视化演示:

https://github.com/OpenDocCN/freelearn-devops-pt3-zh/raw/master/docs/slfc-anti-ptn/img/B30991_06_08.jpg

图 6.8 – 聊天型集成谱系

这并不意味着如果你恰好处于谱系的左侧,就不会存在反模式。它只是意味着目前,你尚未遇到问题。

更好的解决方案

避免聊天型集成反模式的一般建议是理解并在设计时考虑系统的限制。我们并不是在为理论系统创建理论架构。如果我们这样做,我们就会处于学术领域。

当你作为架构师设计集成时,通常是针对一个明确定义的目标环境进行设计。这意味着你应当考虑以下几点:

  • 了解硬性限制,例如系统限制——例如,某一时间段内支持的最大调用次数。

  • 获取目标系统在当前负荷下的实际性能信息

  • 不要在没有考虑性能影响的情况下随意发起调用。

为了缓解这种反模式,组织可以利用 Salesforce 的批量 API 来高效处理大量记录,并使用复合 API 在一个请求中发起多个相关调用。这种方法可以最小化独立事务的数量,提升整体性能,同时确保数据完整性并减少潜在错误。

相反,可以使用以下一种或多种策略来确保目标系统能够应对:

  • 批量化:将多个逻辑调用合并到同一消息中。

  • 合并:将多个更新合并为一个调用。

  • 聚合:将多个区域的变化合并为一个调用,涵盖多个领域。

  • 延迟:在性能波动时引入延迟,推迟发送调用。

  • 减少频率:减少更新的发送频率。

  • 缓冲:将调用添加到一个队列中,随着目标系统的容量逐渐排空该队列。

  • 事件:考虑使用 Salesforce 的流式 API,以减少调用次数并实现更加事件驱动的架构。通过利用流式 API,你可以实时监听 Salesforce 记录的变化,使你的应用能够迅速响应数据变化,而无需频繁轮询。这种方法提高了数据处理的效率和响应性,使其成为现代应用的重要集成方案。

总体来说,如果不小心,一个冗长的集成可能会让你的集成环境陷入困境。因此,即使你认为短期内不会遇到问题,也应避免使用这种集成模式。

错误的模式选择

本节中,我们将探讨过于执着于单一集成风格如何通过集成模式偏执症反模式造成严重问题。

集成模式偏执症

集成模式偏执症发生在仅使用单一集成模式,而忽略所有其他模式的情况下,不管该模式是否适合正在考虑的需求。

示例

WineCo 已经使用 Salesforce 技术超过十年,拥有多个核心云服务组织:营销云和商务云。

他们已经开发出了一种基于 Salesforce 的定制方法,包括一系列框架和库,这些框架和库在项目中一致使用。尽管其中许多需要更新,但出于一致性的考虑,它们仍然是首选。

Clare 被一家领先的咨询公司引入,负责领导 WineCo 为其分销商开发的一个新应用程序的构建。该应用程序将包括 WineCo 管理人员与分销商之间的沟通、标准商品的电子商务、返利管理、定制定价逻辑、联合机会管理以及为特殊需求请求报价的功能。

为了提供所需的功能并实现分销商门户所带来的商业价值,Clare 需要确保与多个系统的集成已经到位。

她必须将所有通信都通过中央通知服务进行处理,以确保所有通信都得到了适当的记录并且有正确的页脚。然后,她还需要与现有的返利管理系统进行集成,该系统根据分销商的细分和历史订单计算应支付给分销商的返利。

定价将来自 Salesforce CPQ,但在不同的组织中,因此需要进行 Salesforce 到 Salesforce 的集成。门户网页的内容将来自公司 CMS。然而,也有一些用户和行为跟踪服务需要从 CMS 集成到门户网站中。

最后,ERP 系统需要更新通过分销商门户生成的任何定制报价和标准订单。分销商门户还需要从 ERP 系统获取大量关于分销商的数据,包括他们的现有订单以及关于他们的基础数据。总的来说,虽然在 Salesforce 上的基础构建非常复杂,但集成环境则更加复杂。

提议的架构在下图中展示:

https://github.com/OpenDocCN/freelearn-devops-pt3-zh/raw/master/docs/slfc-anti-ptn/img/B30991_06_09.jpg

图 6.9 – WineCo 的提议集成架构

更加复杂的是 WineCo 的企业集成标准。它规定所有来自 Salesforce 的集成必须使用公司的集成库来实现。那本来是可以的;然而,这个库只支持同步或异步的 REST 调用,极大地限制了集成设计的选择。

Clare 和她的团队不管怎样继续进行。他们提前完成了大部分核心 Salesforce 的构建,但集成部分进展滞后,遇到了一些不同的问题。

第一,返利系统不支持任何形式的批量处理,导致大量调用其 API。系统所有者质疑当前的设置是否能在上线场景中扩展,最终,需要采购四台新服务器,以确保系统能够承受负载。

第二,对 ERP 系统的查询过多,导致响应时间慢,UI 界面等待时间长。现有架构下无法解决此问题,因此决定将其视为培训问题来处理。

第三,CMS 服务从服务器端调用时困难重重,最终作出妥协,通过 JavaScript 包含追踪代码,尽管这需要正式的例外,并且会导致显著的延迟。

最后,通知服务并不适合分销商门户的许多消息需求,导致格式异常的消息,许多情况下很难回复。这也被接受,并被视作一个培训问题来处理。

项目完成并上线,几乎没有太多宣传。内部用户不喜欢新界面,分销商的采用程度也不热烈。Clare 做出最后的论证,建议重新设计基本的集成架构,使其更合适,然后再进行下一个项目。

问题

集成模式的单一主义试图解决一个问题:设计一个好的集成架构是根本上困难的,确定具体集成的正确模式、设计和实施特征也同样困难。

因此,它试图通过专注于一种在许多情况下都有效的方法来简化问题。通过这种方式,你可以定义一个标准的做事方法,而不必在每个具体案例的细节上纠结。

这有几个吸引人的原因:

  • 第一点,标准往往有效。在许多情况下,采用标准化的做事方式是正确的选择。然而,整个集成架构是一个太广泛的目标,难以使用这种方法来解决。

  • 第二,一旦你选择了一个方法,你可以创建支持资产,比如代码库和框架,用于日志记录和错误处理,这些资产能够在不同的集成中使用,这通常是有益的。

  • 第三,你只需要让开发者掌握一项技能。这样可以减少开发复杂度、培训和入职需求。

如果不是因为一个不方便的事实——没有任何单一的集成模式是普遍适用的——这一切本来都很完美。

提出的解决方案

集成模式偏执建议对所有—或者至少几乎所有—在集成架构中所需的具体集成使用单一的集成模式。这可以通过公司标准明确规定,或者通过架构师和开发人员的工作和思维方式隐性体现。无论哪种情况,当这种偏好变得过于强烈时,你就会遇到反模式。

集成模式偏执的目标通常是相当合理的:

  • 通过限制架构师和开发人员需要做出的选择,来减少集成的复杂性。

  • 在企业架构中强制一致性,以避免不良副作用。

  • 通过为开发人员提供明确的前进方向,并支持他们使用相关工具和框架,使开发人员的工作更轻松。

问题在于,并非所有具体集成都能适配某一给定模式。更新速度、可接受的延迟、数据量以及用户体验UX)等特征,意味着长远来看,过度依赖单一的集成模式是有害的。接下来我们将探讨这一点。

结果

集成模式偏执引发的问题归结为技术不匹配。这是我们在其他反模式中也看到的情况——例如“金锤法则”。虽然在特定情况下可能有一些积极影响,但总体来看,你可能会看到以下一些后果:

  • 你的集成环境由于需要多种变通方法来适应所使用的集成模式的局限性,反而变得更复杂,而不是如预期那样减少复杂性。

  • 一些集成可能由于技术不匹配而无法在预期的质量参数内运行。这可能意味着周期性错误、性能差或类似问题。

  • 这些因素通常意味着需要在持续的基础上承担更高的维护和支持负担,以修正问题。

  • 最终,在某些领域的用户体验(UX)将让终端用户失望,因为该模式无法满足期望。

总的来说,你不会得到预期的好处,反而会陷入一团乱麻。

更好的解决方案

集成模式偏执的解决方案很简单。不要过于专注于单一的集成模式,无论是 RESTful 调用、EDA 还是批量传输。

相反,你可以为应用开发人员和架构师提供明确的指导,告诉他们在什么情况下哪些模式是合适的。在其他条件相同的情况下,偏好是可以的,但在实践中,很少有事情是完全相同的。

以下是 Salesforce 集成模式的概述:

https://github.com/OpenDocCN/freelearn-devops-pt3-zh/raw/master/docs/slfc-anti-ptn/img/B30991_06_10.jpg

图 6.10 – Salesforce 集成模式概览

对选择集成模式持一定保守态度是有道理的。这可以带来一些好处,比如采用一致的方法,利用标准框架和库。

你还可以使用中间件在系统之间创建一定的集成共性,尽管这只是将复杂性转移到了另一个平台。然而,当关键时刻来临时,如果某种方法是适合你的集成需求的,那么你应该使用它。

事件地狱

当基于事件的架构出现问题时,会导致这种反模式,涉及到可扩展性 和控制的失败。

示例

SalesCo 是一家中型公司,专注于定制制造设备,已经使用 Salesforce 作为他们的 CRM 多年。他们的实施是自然增长的,从基本的潜在客户和机会管理开始,逐渐扩展到包括用于管理复杂产品配置、报价和订单履行的自定义对象。

随着业务的增长,SalesCo 的领导层决定现代化他们的系统集成方法。他们听说了 EDA 的好处,并希望利用 Salesforce 的事件功能来创建一个更加灵活和集成的系统架构。

Sarah,SalesCo 的高级 Salesforce 开发人员,负责实施这种新的事件驱动方法。她对使用平台事件解耦不同的过程并创建更灵活的系统充满了期待。

Sarah 首先通过识别可以受益于事件驱动方法的关键业务流程来开始。她为销售过程的各个阶段、产品配置更新、报价生成和订单履行创建了平台事件。目的是让系统的不同部分对这些事件做出反应,而不是有紧密耦合的同步流程。

例如,当销售代表将一个机会标记为Closed Won时,系统会触发一个OpportunityClosedEvent。这个事件会触发多个操作:

  1. 订单履行团队将收到通知,开始处理订单。

  2. 财务系统将会收到通知以生成发票。

  3. 库存管理系统将会预留所需的产品。

  4. 客户成功团队将会被提醒开始客户入职。

类似地,当产品配置更新时,系统会发出ProductConfigChangedEvent,触发报价的重新计算、相关机会的更新以及通知相关销售代表。

最初,这种方法似乎运作良好。系统变得更加灵活,不同的团队可以更加独立地工作。在这种成功的鼓励下,Sarah 和她的团队继续添加更多的事件和事件驱动的流程。

然而,随着事件和事件处理程序数量的增加,问题开始显现:

  • 调试变得越来越困难。当问题发生时,很难追踪导致问题的具体事件和处理器的顺序。

  • 性能开始下降。随着每个事件触发多个处理器,一些处理器又会触发额外的事件,系统开始变慢,尤其是在高峰使用时段。

  • 数据不一致开始出现。随着多个进程基于事件更新相关记录,维护数据完整性变得困难。

  • 开发速度下降。随着事件驱动系统的复杂化,即使是小的变动也需要仔细考虑可能对整个系统产生的连锁反应。

  • 新成员的入职变得具有挑战性,因为理解完整的系统行为需要了解分布在代码库各个部分的众多事件及其处理器。

尽管存在这些问题,SalesCo 团队仍然不愿意放弃他们的事件驱动方法。他们已经在这个架构上投入了大量时间和资源,许多流程现在都依赖于它。Sarah 发现自己处于一个困难的境地,试图维护和扩展一个变得庞大且难以管理的系统。

问题

事件地狱反模式发生在系统过度依赖事件进行组件间通信时,导致代码库变得复杂且难以维护。这个反模式在那些采用事件驱动架构(EDA)但没有充分理解其影响或没有为其使用制定适当指南的系统中尤为普遍。

在 Salesforce 环境中,事件地狱通常表现为过度使用平台事件、流媒体 API 和基于触发器的自动化。虽然这些技术为构建响应性强且解耦的系统提供了强大的能力,但其误用可能导致一张错综复杂的事件发出和处理器网络,这会掩盖系统的行为,并使其维护变得具有挑战性。

事件地狱的关键特征包括以下几点:

  • 过度使用事件:事件被用于几乎所有的组件间通信,即使是那些不需要事件驱动设计复杂性的简单同步操作。

  • 复杂的事件流:随着事件和处理器数量的增加,控制流变得越来越难以跟踪。一个单一的用户操作可能触发一连串的事件,这使得很难预测或理解任何给定操作的全部影响。

  • 缺乏明确的责任划分:在事件地狱的场景中,通常难以明确哪个组件或过程对特定的数据或功能负责。多个组件可能会发出或响应相同的事件,从而导致对某些操作发生位置的混淆。

  • 调试难题:在事件地狱场景中跟踪执行路径非常具有挑战性。当问题出现时,开发人员可能需要在多个组件中的众多事件处理程序之间筛选,以理解发生了什么。

  • 性能问题:事件的不断发布和处理可能导致性能下降,尤其是在交易量较大的系统中。

  • 数据不一致:由于多个进程基于事件更新相关记录,维护数据一致性变得越来越困难。

  • 测试挑战:事件地狱使单元测试尤其困难,因为组件通常依赖于复杂的事件交互,而这些交互在隔离环境中很难模拟或模拟。

在 Salesforce 生态系统中,事件地狱尤其成问题,因为平台的限制条件。过多的事件发布和处理会迅速消耗 CPU 时间、SOQL 查询限制和 DML 操作,从而导致系统超时和故障。

提议的解决方案

事件地狱反模式通常作为解决实际架构问题的提议解决方案出现。它承诺通过利用 EDA 的强大功能,提供一个高度解耦、响应迅速且可扩展的系统。这种方法的吸引力很强,特别是在 Salesforce 生态系统中,平台事件和流式 API 提供了强大的能力,用于构建事件驱动的系统。

该方法的支持者认为,通过使用事件进行大多数组件间的通信,可以实现以下目标:

  • 松散耦合:组件只需要知道它们发布或消费的事件,而不需要知道系统中其他组件的情况

  • 可扩展性:事件驱动的系统理论上可以通过增加更多的事件消费者来处理增加的负载

  • 适应性:可以通过创建新的事件消费者来添加新功能,而无需修改现有代码

  • 实时响应性:事件允许对系统状态变化做出即时反应

  • 集成简化:事件可以作为集成各种系统和服务的通用语言

在 Salesforce 上下文中,提议的解决方案通常涉及以下内容:

  • 使用平台事件进行大多数对象间和进程间的通信

  • 实现众多 Apex 触发器以响应记录更改发布事件

  • 创建多个 Apex 类来订阅和处理各种事件

  • 利用流程生成器或 Flow 响应事件并更新记录

  • 主要通过事件发布和消费来集成外部系统

这种方法似乎解决了许多常见的架构挑战。它似乎减少了系统不同部分之间的直接依赖,允许轻松扩展功能,并提供了一个明确的实时更新和集成机制。

然而,正如我们在下一节中将看到的,这种解决方案在被不加区分地应用时往往会带来比解决更多问题。

结果

当事件地狱反模式占据主导时,系统的结果将是:尽管它承诺提供灵活性和解耦,系统却变得越来越脆弱、难以理解,并且难以维护。在 Salesforce 实现中,事件地狱的后果可能是严重的:

  • 系统稳定性下降:随着事件和处理器的网络不断增长,系统变得更加容易出现意外行为。系统中某一部分的微小变化可能会产生深远且不可预见的后果,导致更多的 bug 和系统不稳定。

  • 性能下降:事件的不断发布和处理可能对系统资源造成重大压力。在 Salesforce 中,尤其是在高负载情况下,这很快会导致治理限制异常。用户可能会体验到响应时间变慢和更频繁的超时错误。

  • 调试噩梦:当问题发生时,追踪根本原因变得极其困难。开发者必须追踪复杂的事件发布和处理链,这些链通常分布在多个对象和类中。这大大增加了解决问题所需的时间和精力。

  • 数据一致性问题:由于多个进程基于事件更新相关记录,保持数据一致性成为一大挑战。当多个事件处理器试图同时更新相同的记录时,可能会发生竞态条件,导致数据冲突和一致性问题。

  • 降低的开发者生产力:随着系统复杂性的增加,即使是小的变更或功能添加,也需要仔细考虑它们在整个事件驱动架构中的潜在波及效应。这减慢了开发进度,并增加了每次变更的风险。

  • 入职困难:新团队成员很难理解系统的行为,因为逻辑分布在众多事件处理器中,而不是集中在更传统的服务层或控制器中。

  • 测试挑战:编写全面的单元测试变得极其困难,因为各个组件与事件系统紧密耦合。集成测试变得更加重要,但也更难配置和维护。

  • 扩展性问题:具有讽刺意味的是,尽管事件驱动架构(EDA)通常因其潜在的可扩展性优势而被采用,但事件地狱可能导致相反的结果。随着事件量的增加,系统可能难以跟上,导致事件积压和处理延迟。

  • 增加的运营成本:事件地狱引入的复杂性通常需要更强大的(且更昂贵的)计算资源来保持可接受的性能水平。这也可能需要更复杂的监控和警报系统,以跟踪事件流并识别问题。

  • 可见性有限:理解系统当前状态变得更具挑战性,因为重要的业务逻辑和数据转换作为事件的副作用而不是通过更可见和可追溯的直接操作进行。

  • 集成复杂性:虽然事件可以简化集成的某些方面,但事件混乱可能会使系统之间的清晰契约难以维护。对事件结构或处理逻辑的更改可能会对集成系统产生意外影响。

  • 治理挑战:在受管制行业中,事件混乱可能会使提供清晰的审计跟踪和证明合规性变得困难,因为重现导致特定系统状态的操作顺序可能很难。

在 Salesforce 环境中,这些问题通常会因平台特定限制而加剧。例如,无法控制触发器执行顺序可能导致事件发布者和处理程序之间的竞争条件。类似地,复杂事件驱动场景中可能很快超出平台的治理限制,导致运行时错误和事务处理不完整。

更好的解决方案

要避免陷入事件混乱反模式,同时仍然利用 Salesforce 中事件驱动架构的好处,请考虑以下策略:

  • 保留事件用于真正的异步或解耦操作。并非每个状态更改或业务流程都需要基于事件驱动。对于简单的线性流程,请使用直接方法调用或同步操作。

  • 在 Salesforce 组织中建立明确定义的领域,并主要用于跨领域通信的事件。在一个领域内,更倾向于更直接的交互形式。

  • 在设计事件结构时要考虑周全。使用版本化事件,并且每个事件中仅包含必要的信息。这可以帮助管理系统演化并减少事件生产者和消费者之间的耦合。

  • 对于需要完整状态变更历史记录的复杂领域,请考虑实施事件溯源。这种模式可以提供更好的可追溯性,并使系统状态推理更加容易。

  • 使用平台事件触发器来集中事件处理逻辑,与拥有多个独立处理程序类相比,这样做可以更容易地管理和调试。

  • 使用断路器模式防止事件处理在高负载情况下或经历下游系统故障时压倒系统。

  • 对于复杂领域,请考虑使用**命令查询职责分离(CQRS)**来分离读写模型。这可以简化您的事件处理逻辑并提高性能。

  • 接受在某些情况下,最终一致性是足够的事实。这可以帮助简化您的事件处理逻辑并提高系统性能。

  • 为事件处理实施一致的错误处理和死信队列。这可以帮助更快地识别和解决问题。

  • 保持清晰、最新的事件模式、生产者和消费者文档。考虑使用工具生成事件流的可视化表示。

  • 使用 Salesforce 的事件监控功能,并考虑实施额外的日志记录以跟踪事件的发布和消费。这有助于识别性能问题并协助调试。

  • 在实现复杂业务流程之前,使用事件风暴会议与团队共同建模。这有助于识别适当的边界和事件使用。

  • 对于某些场景,其他集成模式(如请求-响应或发布-订阅)可能比纯事件驱动方法更为合适。

  • 对于可能接近治理限制的复杂事件处理,考虑使用 Queueable Apex 将处理分解为可管理的块。

  • 使用 Salesforce 的平台缓存存储频繁访问的数据,这些数据源自事件,从而减少重复复杂事件处理的需求。

  • 使用功能标志逐步推出事件驱动的功能,并在生产环境中出现问题时快速禁用有问题的事件流程。

通过应用这些策略,您可以在 Salesforce 中创建一个更易维护且高效的事件驱动系统,避免事件地狱的陷阱,同时仍能收获反应性、解耦架构的好处。记住,目标是将事件作为您架构工具包中的强大工具,而不是将其作为应对所有集成和通信挑战的万灵药。

我们现在稍作偏离,探讨新兴人工智能技术对集成反模式的普遍影响。

人工智能对集成的影响

随着人工智能的不断发展并渗透到软件开发和系统集成的各个方面,必须考虑其带来的潜在好处与风险。本节探讨了人工智能如何影响集成实践,可能引发新的反模式,同时也提供了避免现有反模式的机会。

随着人工智能技术的广泛应用,集成领域正处于重要转型的边缘。虽然人工智能驱动的集成前景令人振奋,但我们需要以批判的眼光看待这一新前沿。与任何技术进步一样,人工智能的引入可能会导致新的反模式,从而可能破坏它们本应带来的效率。

可能出现的一个潜在反模式是我们可能称之为AI 过度依赖综合症。当组织过度依赖 AI 驱动的集成工具,忽视人类监督和领域专业知识时,就会发生这种情况。例如,考虑一种情境,一家公司实施了一个 AI 驱动的集成平台,承诺自动映射数据字段并优化 Salesforce 与其遗留 ERP 系统之间的数据流。初期结果令人印象深刻,他们可能会减少集成团队的人员,并完全依赖 AI 系统。然而,AI 可能无法理解复杂的业务规则和数据关系,从而导致库存管理和订单处理中的关键错误。这种过度依赖可能会导致人类专业知识和背景的流失、由于误解业务逻辑而产生的系统性错误的可能性,以及在排查和解决复杂集成问题时的困难。

另一个我们可能会看到的潜在反模式是黑箱集成。当用于集成的 AI 模型变得如此复杂,以至于人类开发者和架构师无法理解时,就会出现这种情况。假设一家公司采用一个复杂的机器学习模型来管理 Salesforce 与多个外部系统之间的实时数据同步。该模型会根据数据模式不断演化。随着时间的推移,集成行为可能变得不可预测,团队可能会很难解释或控制某些数据转换。缺乏透明度和可审计性可能会导致在遵守数据法规方面遇到困难,并增加在关键业务流程中出现意外行为的风险。

我们还可能会遇到我们所说的训练数据偏见放大现象。当用于集成的 AI 模型在有偏见或不完整的数据集上进行训练时,可能会导致结果失真,并可能引发歧视性后果。例如,一家金融服务公司可能会使用 AI 模型将 Salesforce 中的客户数据与其信用评分系统进行集成。如果该模型主要在城市地区的历史数据上进行训练,它可能无法准确评估乡村客户的信用 worthiness,导致不公平的贷款拒绝。这可能会导致现有偏见的延续和放大、潜在的法律和道德问题,以及对 AI 驱动的集成系统的信任破坏。

尽管这些潜在的反模式描绘了一幅警示图景,但需要注意的是,AI 也为缓解现有的集成反模式提供了显著的机会。例如,AI 可以通过分析使用模式并建议最优的接口结构,帮助防止臃肿接口反模式。它还可以通过根据实时系统行为和需求,建议最合适的集成模式,从而解决集成模式狂热的问题。此外,AI 模型可以通过预测潜在的性能瓶颈并提出优化建议,帮助防止多余的集成

为了在集成中利用 AI 的好处并避免潜在的陷阱,采用平衡的方法至关重要。这可能涉及将 AI 推荐与人工专业知识结合,用于关键集成决策,优先选择能提供明确决策解释的 AI 模型和工具,实施强大的监控系统来跟踪 AI 驱动的集成性能,确保 AI 模型在多样化和具有代表性的训练数据集上进行训练,以最小化偏差,并定期审计 AI 驱动的集成系统。

随着 AI 继续重塑集成领域,Salesforce 架构师和开发人员必须保持对其带来的机会和风险的了解。AI 在集成领域的旅程刚刚开始,随着技术的演进,新的反模式和解决方案可能会不断出现。保持灵活、批判性思维,并时刻保持信息更新,将是驾驭这一既激动人心又充满挑战的领域的关键。

我们现在已经完成了本章中的模式内容,将继续讨论关键要点。

了解关键要点

在本节中,我们将稍微抽象一下特定的模式,而是试图提取您在日常工作中作为 Salesforce 架构师或为 CTA 评审委员会准备时可以使用的更广泛的学习要点。

在架构 Salesforce 解决方案时,您应注意以下几点:

  • 中间件可以是创建秩序并改善系统结构的绝佳方式。然而,您也可以以某些方式使用它,导致弊大于利。

  • 如果您所做的仅仅是用中间件通过等效的点对点流替代直接连接,您可能已经进入了反模式的领域。

  • 在某些情况下,自定义服务可以是 Salesforce 组织的一个极好的补充。然而,它们会带来相当大的复杂性。

  • 您不应因为看似是业务需求的定制服务而冲动地添加大量服务。相反,您应该退一步,从大局来看需求,看看有哪些选项可以实现所需的特定集成流。

  • 如果您正在构建自定义接口,无论是在 Salesforce 上还是在您的中间件平台上,都应确保有适当的治理措施,以避免最终产生一个做所有事情的臃肿接口。

  • 如果可能的话,避免过于频繁的集成调用。

  • 如果你确实需要高频率的状态传输,考虑使用像 CDC 这样的专用技术。

  • 一般来说,设计集成时必须明确考虑系统的限制。例如,不要假设一个旧的 ERP 系统能够处理无限次的调用。Salesforce 当然也有明确的限制。

  • 保持灵活的集成架构方法。不要对某一种风格过于执着并用它处理所有事情。仅仅因为事件驱动的微服务很流行,并不意味着它适合每个场景。考虑参考 Salesforce 的集成模式指南,帮助你选择合适的集成模式。

  • 给出清晰的指导,帮助你团队成员和外部合作伙伴选择集成模式。不要认为他们能自行做出正确的决策。

在准备 CTA 审查委员会时,你应该注意以下几点:

  • 几乎每个场景都会有中间件的需求。你应该了解常见平台(如 MuleSoft)的关键能力,并能够智能地讨论它们如何融入系统架构。

  • 尽管你可能不会在场景中看到足够的集成,形成类似 MINO 模式的问题,但仍然值得思考中间件为你正在传递的每个集成流程所带来的具体价值。

  • 不要一味地通过中间件处理所有的集成——往往有一些例外情况需要不同的处理方式。

  • 建议定制 Web 服务是一项重要的定制内容,需要强有力的理由才能在审查委员会架构中包含。

  • 如果你需要定制接口,那么在大多数情况下,你应该通过中间件来构建和暴露接口。

  • 虽然在审查委员会中你不太可能遇到一个接口臃肿的情况,但仍然值得考虑如何构建你的集成接口,以及它是否平衡。

  • 你需要考虑你所建议的设计可能带来的性能影响。通常情况下,场景会有高频率的要求,如果以明显的方式指定这些要求,可能会导致类似于多次集成模式的性能问题。

  • 准备讨论如何在 Salesforce 环境中应用 DevOps 实践来管理和部署复杂的集成。

  • 审查 CTA 审查委员会的关键目标,并准备好阐明你的经验如何与这些目标对接。

  • 熟悉与你项目相关的最新 Salesforce 功能和最佳实践。

  • 确保所有的支持文档和资料准备齐全,能够顺利展示。

  • 你可能会被问到 Salesforce 平台的集成限制,因此值得事先记住这些限制,便于在委员会中作答。

您应该彻底掌握 Salesforce 平台上所有常见的集成模式。这包括关于何时选择哪种模式的决策指导。在工作中,您可能需要多种模式,并且应该能够清晰地阐明您为何做出这样的选择。

我们现在已经讲解完本章节的内容,可以继续进行。然而,首先我们将总结一下我们的学习内容。

总结

在本章节中,我们回顾了五种不同的反模式,这些反模式在不同方面可能导致集成架构失败。值得时刻牢记这些反模式。

集成领域极为复杂,且在多个层面上都可能出错。从选择错误的集成模式或误用中间件,到具体实现的技术细节,反模式可能会在项目层面,甚至企业架构层面,造成严重问题。

这种复杂性强调了为何经验丰富的架构师在处理集成时总是保持谨慎。集成是项目失败的最常见原因之一,无论是在 Salesforce 上,还是在一般情况下。

值得重申的是,本章节是唯一一个所有反模式不仅适用于 Salesforce,而且适用于所有企业软件系统的章节。学习了这些内容之后,您应该能够稍微更好地准备迎接集成领域中即将遇到的挑战。

在已经讲解了集成领域之后,我们将继续讨论适用于您部署过程和治理的反模式。

第三部分:流程和沟通反模式

本部分将教您如何识别和缓解与流程、治理和沟通相关的反模式。

本部分包含以下章节:

  • 第七章避免开发生命周期偏离轨道

  • 第八章无误译的沟通

  • 第九章结论

第七章:防止开发生命周期脱轨

在本章中,我们将探讨现代 DevOps 实践,特别是持续集成和持续部署CI/CD),如何与软件开发中的各种反模式相关。我们将首先识别显著的过程级反模式,然后讨论 CI/CD 如何影响软件打包。最后,我们将探讨与测试相关的常见反模式。在本章末尾,我们将总结与现实应用和 CTA 复习委员会考试相关的关键要点。

在本章中,我们将讨论以下主要内容:

  • 如何避免在项目交付中犯大方向性错误,例如如何结构化发布和处理关键权衡问题

  • 如何避免以可能对组织有利但在架构上存在问题的方式来构建您的包

  • 如何避免在面临交付压力时妥协代码和部署质量的陷阱

完成本章后,您将理解常见错误如何影响开发生命周期和相关活动,并掌握一些工具,帮助您避免这些问题。

过程对齐错误

在本节中,我们将讨论两种反模式,它们以不同方式使开发生命周期脱轨。首先,我们将探讨大爆炸发布如何在许多情况下导致灾难性结果。其次,我们将讨论项目分配主义——这种错误的信念认为可以避免做出重要的权衡。

大爆炸发布

大爆炸发布反模式将所有功能的发布集中在项目的最终单一事件中。

示例

RollerCo 是一家主要生产滑轮鞋和滑板的制造商,正在经历一场以创建一个数字化驱动的业务为中心的重大业务转型,以更好地满足当今买家的需求。尽管这场转型并非最终目标,但作为过程中一部分,计划了几个系统替换项目,旨在提供更大的 IT 灵活性。

Anandh 正在领导一个项目,该项目旨在替换 RollerCo 使用了 15 年的老旧自主开发 CRM 系统。该系统将被 Salesforce Sales Cloud 和 Service Cloud 的组合所替代,但由于老旧系统的高度定制化,已经证明无法使 Salesforce 设计保持接近标准。

高度定制化的另一个后果是,整个系统将需要作为一个整体上线。在全面上线之前,无法发布更小的最小可行产品MVP)增量,因为那样会使客户支持人员的工作过于复杂。

在项目启动后不久,Anandh 被告知董事会已批准升级企业资源规划ERP)到 SAP S/4HANA。由于 CRM 和 ERP 在多个流程中紧密耦合,这意味着 Anandh 不仅需要应对增加的集成积压,而且两个系统的上线计划也需要协调,以确保它们能同时上线。

很快就发现,ERP 升级带来的额外复杂性意味着原始的 Salesforce 实施计划必须推迟。特别是,集成的复杂性超出了任何人的预期。

首席信息官(CIO)在与一位可信的供应商代表会面后宣布,为了解决 CRM/ERP 集成问题,RollerCo 将投资建设一个新的战略中间件平台。这将替代现有的中间件,并与整体的 CRM/ERP 上线时间表同步上线。

当 Anandh 和他的团队忙于重新设计所有集成以适应新的中间件平台时,又有一个新发现。负责 RollerCo 网络商店的团队发现,让它与新的 CRM/ERP 设置兼容几乎是不可能的。

这需要更改应用程序数据层的基本架构,而当初构建该架构的开发人员已经不在公司。其他人无法弄明白如何操作,因此一个新的电子商务应用程序也被加入到整体项目积压中。为了方便起见,时间表与整体 CRM/ERP 上线时间表对齐:

https://github.com/OpenDocCN/freelearn-devops-pt3-zh/raw/master/docs/slfc-anti-ptn/img/B30991_07_01.jpg

图 7.1 – RollerCo 的新平台

该项目遭遇了不断的延迟。尽管有些领域比其他领域受影响更大,但没有一个主要平台在实施阶段表现得很好。三年过去了,初步版本终于接近完成。

RollerCo 已建立了一个复杂的部署流水线和切换计划,以处理多系统的同时上线,所有这些都计划在公司淡季的一个周末进行。上线前的测试花费了超过三个月的时间,并且需要进行一些范围缩减和紧急修复。

即便如此,参与该项目的人员也不敢明确说出系统会按预期运行。各种可变因素实在是太多了。

上线周末一开始表现不错,所有必要的数据迁移活动顺利完成。然而,一旦真实的业务用户进入系统,各种问题开始浮现。

到了周日晚,问题的数量已经达到一种让继续推进显得过于冒险的程度。虽然到目前为止没有任何单一问题是致命的,但由于小问题引起的整体干扰已经相当严重。在一个深夜电话会议中,指导委员会决定回滚并推迟上线。

后果是显著的。毕竟,项目已经有三年的时间来完成工作。然而,很快就变得清楚,问题无法在几周内解决。仍然有很多工作需要完成。

团队们将在接下来的六个月里共同寻找解决方案。在这段时间里,他们专注于缩小范围并简化功能,以便让推出过程更容易管理。

最终,包含 CRM、ERP、中间件和电子商务的综合平台上线。然而,它上线时带着一大堆已知问题和解决方法,而且其范围大大缩小,远低于最初的设计。

问题

大爆炸发布是一种反模式,通常尝试解决在发布过程中如何处理复杂依赖关系的问题。这些依赖关系可能存在于系统之间或系统内部。它最常出现在没有强有力的数字化转型领导的地方,而且现有的领导层往往高度规避风险。

依赖关系通常与某些业务流程相关,这些流程有着长期以来以某种方式进行的惯例,这意味着大量的功能必须作为一个整体进行部署。有时候,像我们在这个例子中所见的那样,这甚至可能导致系统级别的巨大依赖关系。

解构现有的业务流程并提出过渡架构(在部分解决方案存在的情况下,满足完成工作的需求)可能相当困难,像功能的最小可行产品(MVP)子集那样可以独立提供价值也同样困难。大爆炸发布通过简单地将一切推迟到未来的一个大事件来避免这些问题。

提议的解决方案

大爆炸发布反模式建议在漫长的交付过程中,最后进行一次大的发布,涵盖所有相关功能。这可能意味着几年积累的工作同时上线,而没有任何中间的反馈。

这种解决方案对于交付团队和客户来说,因各种原因可能非常有吸引力:

  • 它将整个系统简化为一个单一的部署单位,可以作为一个整体进行管理。

  • 它简化了规划过程,因为你不需要为多个发布、部分数据迁移和共存场景做规划。这意味着整体架构也被简化,因为不需要为项目的范围设计过渡架构。

  • 你还避免了在什么时候包含哪些内容、可以满足哪些业务需求以及何时满足的艰难决策。

  • 对于交付团队和客户来说,这很容易理解。

  • 你成功地将问题推迟了,把它变成了以后再处理的事情。在某些情况下,到时候可能会有其他人来做这件事。

因此,你可以理解为什么——即使在小范围发布和 DevOps 思维已经成为主流范式的今天——许多项目仍然最终以大爆炸的方式进行部署。不幸的是,这通常不会顺利进行。

结果

Big-Bang 发布反模式的根本问题在于,你往往无意间承担了大量的风险。技术风险不会随着部署组件数量的增加而线性增长。相反,由于组件间连接和依赖关系的超线性增长,风险会以更快的速度增加。

简而言之,如果你只部署一个组件,你需要处理的风险仅限于该组件的故障。如果你部署了两个互联的组件,那么你就需要应对最多四种故障模式:

  • 组件 1 独立故障

  • 组件 2 独立故障

  • 组件 1 故障并触发组件 2 的次级故障

  • 组件 2 故障并触发组件 1 的次级故障

这四种故障模式可能会表现出独特的症状,根本原因可能并不明显。试想一下,如果你同时部署 20 个组件,并且它们之间有大量的相互连接,你将面临多少潜在的故障模式。

在软件开发中,流水线就像是代码的工厂装配线,每个步骤会自动流向下一个。就像汽车在不同的工位进行组装、测试和质量控制一样,代码也会经历构建、测试和部署的各个阶段。DevOps(开发和运维结合)是一套将软件开发和 IT 运维团队结合起来的实践,旨在加速、更可靠地交付软件。可以把它看作是打破了编写代码的人员与维护这些代码运行的系统之间的传统壁垒。

现代 DevOps 实践高度强调自动化测试和部署流水线,它们充当着防范“爆炸式”发布(一次性发布多个更改)风险的安全网。当开发人员修改代码时,这些更改会自动触发一系列的测试——单元测试检查单个组件,集成测试验证不同部分的协作,系统测试确保整个应用程序功能正常。这种被称为持续集成的自动化流程,帮助团队及早发现和修复问题,避免问题影响整个系统。持续交付会将这些经过验证的更改自动准备好发布,确保每次更改都能随时部署。

CI/CD 框架的实施将传统的、少量大规模发布的方法转变为一系列更小、更易于管理的更新。团队不再将数十个更改积累到一个重大发布中(这可能很冒险,就像试图同时更改发动机的多个部件一样),而是可以在每个更新准备好并经过验证后立即部署。这个增量方法使得识别和修复问题变得更加容易——如果出现问题,团队可以迅速定位到是哪个具体的更改导致了问题,并修复它或回滚这个更改,而不是一次性撤销多个更新。结果是更稳定的软件系统,因为团队可以监控每个小更改的影响,并在问题成为大问题之前解决它们。

由于大规模部署的故障模式非常多,这意味着测试变成了一个巨大的任务,通常你可能测试数周,仍然无法确定是否已经测试了所有重要的案例。调试错误也变得更加困难,因为追踪各个组件之间可能的连锁反应比仅仅找出单个组件中的错误要困难得多。

相同的困难也适用于推出和回滚任何需要完成的切换任务。在“大爆炸”场景下,甚至培训和变更管理也变得更加困难。

总的来说,发布越大,失败的风险越大。如果你不是赌徒,应该避免走这条路。

更好的解决方案

如果大规模发布是问题,那么小规模发布显然是解决方案。从风险管理的角度来看,每次发布的理想功能量是一个单独的特性或一个单独的用户故事。这正是持续交付CD)的前提,正如许多领先的 DevOps 导向的组织所实践的那样。

然而,我们必须承认,并非所有组织都具备规模或技术成熟度来采用允许每次只交付一个功能的纯 DevOps 配置。然而,如果你追求小规模发布的理想,至少你将开始减轻这些问题。

小规模发布具有以下特点:

  • 风险更小

  • 更容易测试

  • 更容易调试

  • 更容易在发现错误后进行修复

  • 更容易推出和回滚

  • 更快地向业务用户交付价值

  • 促进并增加系统的采纳

  • 使变更管理更容易控制

总体来说,一旦完成了必要的技术和业务流程工作以启用小规模发布,那么几乎没有——如果有的话——缺点。

一般来说,旨在提高韧性将有助于避免本章中提到的问题。一个好的起点是使用完善架构框架:architect.salesforce.com/well-architected/adaptable/resilient

项目派系主义

Project Pieism 未能处理关键架构权衡,而是坚称你可以既享有它又能够使用它。

示例

ConglomoCo 是一家大型多元化企业集团,拥有许多业务单元BU),有些与业务领域相关,有些与地理位置相关。大多数业务单元在运营和信息技术基础设施方面相当独立。此外,业务单元负责人相对于总部HQ)员工拥有更多权力,因为他们实际上是自己业务的主宰。

当 ConglomoCo 的 CIO 决定推动 Salesforce 的全球推广时,他们因此遇到了多个业务部门负责人强烈的抵制,这些部门有自己的 CRM 策略,并不希望总部插手。然而,作为新倡议的一部分,首席执行官(CEO)和首席财务官(CFO)要求提供全球销售漏斗的汇总视图,而 CIO 正是借此来推动他们的 Salesforce 战略。

金,作为 ConglomoCo 总部的高级 IT 项目经理,因此被赋予了推动 Salesforce Sales Cloud 和 CPQ 全球推广的责任。首席信息官(CIO)希望借此机会在各个业务单元之间标准化核心销售流程,并简化销售数据的报告。

因此,在与他的架构师进行沟通后,金提出了基于单一组织和标准流程的计划。业务单元内部将有一些本地化的变化,但这些变化的范围将被限制在一定程度上。

当金开始向利益相关者展示这个计划时,他发现这显然不是他们所期望的。各个业务单元(BU)有各自独立的流程、用户体验(UX)期望、本地集成以及他们希望新系统能满足的报告需求。

在一场高级领导研讨会上,许多问题浮出水面,并在最高层达成了妥协。新系统必须能够满足独立的销售流程、自动化、本地集成,并且能够为每个业务单元(BU)提供一定程度的用户体验(UX)定制:

https://github.com/OpenDocCN/freelearn-devops-pt3-zh/raw/master/docs/slfc-anti-ptn/img/B30991_07_02.jpg

图 7.2 – ConglomoCo 组织

然而,所有这些仍然必须在同一个 Salesforce 组织内进行,并利用相同的数据模型,以简化跨业务单元(BU)的报告。可以理解,这将导致更加定制化的实施,并带来成本上的影响,但首席信息官(CIO)仍然希望实施尽可能接近标准化。

实施过程漫长且缓慢。必然地,它包含了许多与不同业务单元相关的独立工作流。每个工作流似乎都有其复杂性,工作流之间的协调是一个持续且艰难的挑战。可以说,随着实施的推进,人员的疲劳感逐渐增加,大家对未来系统的期望也有所下降,更加看待它为一种必要的“恶”而非推动积极变革的工具。

金与业务部门进行谈判,并成功使两个较小的领域以试点方式上线。这些领域上线时并没有太大宣传,且存在许多漏洞。然而,比这些漏洞更糟糕的是,低采纳率。各业务单元的销售人员似乎尽一切可能避免将数据录入系统,而即使录入,数据质量也很低。

鉴于初期结果不理想,后续的推广被暂停。相反,一家管理咨询公司被请来调查为何采用情况如此差劲,并探讨如何改进。

问题

项目派系主义是一种反模式,其根本原因在于避免在实施系统时做出艰难的权衡。这可能是因为政治上的困难或项目领导力不足,但始终涉及未能承认一个需要决策的关键权衡。

从某种意义上来说,大多数软件架构中的工程问题,乃至一般问题,都涉及在一系列权衡之间找到平衡。然而,这些权衡往往令人不舒服,且往往无法取悦所有利益相关方。

因此,很多项目在没有做出必要的权衡的情况下继续进行,抱有后来可能找到解决方案的希望,或干脆闭眼不看事实。在任何情况下,这都是一种反模式。

提议的解决方案

项目派系主义建议,将一个或多个重要的权衡视为解决方案的一部分,认为这个权衡并不存在,你实际上不需要做出妥协,甚至可以既得到自己的“蛋糕”又能“吃掉”它。有时,这种做法通过忽视权衡或把它扫到地毯下完成;有时则是承认了权衡,但通过特殊请求来暗示这个情况是特殊的,因此这个权衡不适用。

这个位置显然很有吸引力。当在实施项目中需要做出关键权衡时,你可能不得不让一个或多个利益相关方失望。如果这些利益相关方在你的组织中很有权力,这可能并不是一件容易或愉快的事。你甚至可能发现自己由于公司政治被迫陷入项目派系主义(Project Pieism)的困境。

然而,即使是你组织中最有权力的高管,也无法改变软件架构的基本事实。总是存在权衡。每当在技术项目中出现你认为不需要做出权衡的情况时,你应该感到担忧。

结果

项目派系主义的结果是,你试图忽视的权衡最终会回归。根据墨菲定律,这通常会发生在项目生命周期中最不方便的时候,并对项目造成重大损害。

当然,具体的损害将取决于你忽视的权衡。在我们之前的例子中,我们忽视了全球与本地流程的优先级之间的权衡,以及标准功能与定制化之间的权衡。

ConglomoCo 曾试图建立一个具有全球流程的标准化系统,同时兼顾所有相关的本地变更。这导致了一个没人愿意使用的系统,因为它无法很好地满足任何人的需求。

其他权衡会产生不同的后果,但如果你未能做出关于推动架构的关键权衡的重要决策,你可以预见到不利的后果。

更好的解决方案

朝着更少的妥协未来迈进的方式,就是公开承认需要做出的权衡,并与利益相关者建设性地讨论选项。通常,确实有办法让利益相关者获得更多他们都想要的东西,但可能会以额外的成本或更长的时间线为代价。

让这个参与过程正式化的一种方式是,在项目早期建立良好的架构治理,并在架构论坛和业务论坛上讨论关键的架构权衡,以确保考虑到所有的视角。在我们的例子中,一个称职的架构委员会可能会指出,在 ConglomoCo 的情境中,根本无法让单一的组织策略有效运作。

作为架构师,我们需要对业务保持诚实,明确什么是可行的,什么是不可能的。我们是那些在技术方面了解可能性的专业人士,我们不应该假装我们最喜欢的技术能够超越必须做出艰难选择的现实。坚定立场,保持建设性,提供选项,且不忽视重要的权衡。

不频繁的检查

不频繁的检查是一个反模式,指的是开发者长时间在隔离的环境下工作,而没有将他们的更改集成到主代码库中,这会导致显著的集成挑战、减少可视性,并可能导致 项目延误

示例

CloudTech,一家快速增长的科技公司,一直在开发定制的 Salesforce 解决方案,以管理其复杂的合作伙伴生态系统。该项目涉及多个团队,分别负责解决方案的不同方面,包括合作伙伴入驻、认证管理和收入分成计算。

高级开发者莎拉被指派构建收入分成计算引擎,这是一个关键组件,需要与系统的多个部分进行接口。鉴于计算的复杂性和涉及的众多业务规则,她决定在与主代码库集成之前,先完成整个功能。

项目经理汤姆对这种方法感到满意,因为他相信这能让莎拉完全专注于正确完成复杂的计算,而不会被集成问题分心。团队的技术负责人马库斯对长时间的隔离期表示了一些担忧,但最终同意了,考虑到莎拉的经验以及该组件的重要性。

Sarah 花了六周时间工作在计算引擎上。在此期间,她取得了显著进展,并在站会期间定期向团队更新她的工作。然而,她将所有更改保留在本地开发环境中,认为这是最安全的做法,直到功能完成并经过彻底测试。

与此同时,其他团队成员继续他们的工作。合作伙伴入驻团队对数据模型进行了一些更改。认证团队添加了新的验证规则,这些规则影响合作伙伴状态。集成团队修改了计算引擎需要交互的几个 API。

当 Sarah 最终完成计算引擎并准备将其与主代码库集成时,出现了几个问题。合作伙伴入驻团队对数据模型所做的更改与 Sarah 对架构结构的假设发生了冲突。新的验证规则影响了合作伙伴状态的确定,而这正是计算引擎的关键输入。修改后的 API 需要不同的参数和返回结构,而这与 Sarah 代码的预期不符。

团队现在面临危机。冲刺截止日期临近,但集成 Sarah 的代码将需要大量重构。代码审查过程变得令人不堪重负,因为团队成员难以理解和验证庞大的变更集。在测试过程中发现了几个关键的 bug,但由于变更之间的相互关联,修复变得复杂。

在额外的三周密集工作后,解决了集成问题,功能最终合并到了主代码库。然而,延迟影响了其他依赖的功能,项目时间表需要调整。团队还发现,Sarah 的一些工作在她孤立工作期间与其他团队成员已经实现的解决方案重复。

问题

不频繁检查的反模式出现在开发人员长时间独立工作且不将更改合并到主代码库的情况下。这种模式通常出现在涉及复杂功能或关键组件的场景中,团队认为隔离可以带来更好的集中和更少的干扰。

反模式通过开发人员在数周或数月内没有合并代码而表现出来,导致大规模、单一的变更集,难以审查和测试。这种做法限制了开发进度的可见性,并与不断变化的代码库和团队决策之间隔离开来。

虽然这种做法对复杂功能来说似乎是合乎逻辑的,但它从根本上误解了软件开发的协作性质以及持续集成(CI)的重要性。

提议的解决方案

不频繁检查合并方法认为,复杂的特性最好独立开发。支持者认为,开发者可以完全专注于他们的任务,而不必担心集成问题,保持代码“干净”,并在特性准备好之前不受持续变化的影响。他们相信,在特性完成后,测试会更为彻底,代码审查也会在检查完整功能时更有意义。通过将功能视为单一工作单元,项目管理看起来会更简单。

这个解决方案看起来很有吸引力,因为它承诺通过避免持续集成(CI)的开销并处理代码库中持续的变化,来减少复杂性。它建议开发者能够完全专注于特定功能,避免外部干扰,从而提高质量。

结果

不频繁检查合并反模式会导致几个显著的问题。集成成为一个重大挑战,最终与主代码库集成时会出现大量的合并冲突。通常需要进行显著的重构,以适应在隔离期间所做的更改,并且集成错误和 bug 的风险也会增加。

在整个开发过程中,可见性受损。团队对实际开发进展的了解有限,难以及早识别潜在问题,降低了做出明智项目决策的能力。

随着团队成员独立工作,合作问题随之而来。知识共享和同行学习受限,关于设计决策和实现方法的反馈也会延迟。这通常会导致重复劳动,因为不同的团队成员在解决类似问题时,彼此并不了解对方的工作。

质量影响变得明显,代码审查可能会错过关键问题。由于大型变更集,全面测试变得困难,并且由于复杂的集成场景,bug 更有可能漏网。

项目延期是常见的,因为初步时间表中没有考虑到延长的集成周期。这会导致一系列的延迟,影响相关特性,并增加了解决冲突和问题所需的时间。

技术债务通过架构不一致的原因积累,因为开发过程中的分歧导致团队发现重复的解决方案和不一致的方法,同时很难维持代码历史记录并理解更改的理由。

更好的解决方案

为了避免不频繁检查合并反模式,团队应当实施真正的持续集成(CI)。这意味着要建立自动化的构建和测试流程,要求开发者每天至少集成一次更改,设置集成问题的监控和警报,并使用功能开关在主代码库中管理不完整的功能。

复杂的功能需要拆解成更小、更易管理的部分。团队应计划增量开发,明确集成点,尽早识别依赖关系,并主动管理它们。每个组件的明确验收标准有助于保持关注,同时允许定期集成。

明确的集成政策至关重要。团队应定义集成之间的最大可接受时间,以及变更集大小的指南。代码评审流程应鼓励频繁的小规模评审,并应制定功能切换使用的标准。

在开发过程中,必须优先考虑沟通与可视化,定期进行设计评审,并在复杂功能上进行结对编程。团队应保持最新的架构决策文档,并定期进行团队同步会议,讨论技术挑战。

现代开发实践在防止这种反模式中起着至关重要的作用。基于主干的开发最小化了长期存在的分支,而全面的自动化测试有助于及早发现问题。功能标志有效地管理不完整的功能,适当的监控和可观察性确保团队能够快速识别和解决问题。

团队文化是成功的基础。组织应鼓励知识共享与协作,同时促进集体代码所有权。应支持持续学习和改进,团队应为早期反馈创造一个安全的环境。

避免这种反模式的关键是认识到软件开发本质上是协作性和迭代性的。成功的关键不在于避免集成挑战,而在于通过频繁集成和清晰沟通,使这些挑战足够小,能够有效管理。通过实施这些解决方案,团队可以保持高质量,同时避免孤立开发的陷阱。

解开流水线

本节将介绍与如何为基于包的开发构建包结构相关的一个关键 DevOps 反模式。

使用包创建孤岛

使用包创建孤岛是根据团队结构将 Salesforce 项目的包划分,而不考虑架构问题

示例

MillCo 是一家生产 CNC 铣床的公司,拥有遍布欧洲和北美的子公司,正在为其 B2B 销售实施 Salesforce。这包括 Sales Cloud、CPQ 和 B2B Commerce。

Abigail 是 MillCo 的 CRM 技术负责人,在加入 MillCo 之前,她曾在另一家 B2B 制造公司领导过一个 CRM 实施项目。她的主要职责是确保来自三个不同供应商的技术交付在实现新系统的不同元素时具有一致性和高质量。

在项目启动时,Abigail 邀请了三个供应商团队以及内部相关方,并多次强调,虽然每个人都为不同的公司工作,但大家应当把自己看作是一个团队的一部分。MillCo 希望大家在同一页面上,共同朝着一个共同目标努力。

事实证明,这一切都是徒劳的。一旦工作正式开始,三家供应商很快就互相对立。Abigail 发现很难让他们达成任何共同的方法和标准。

尽管她可以强制执行某些规定,但她没有团队支持,如果供应商不配合,她所能做的也有限。她将问题上报,但被要求找到一个能够让工作按计划继续进行的解决方案。

她决定的解决方案是将每个供应商隔离在独立的软件包中。这样,供应商可以独立开发,除了他们的工作在平台的关键元素上直接冲突的情况。Abigail 决定亲自监控并调解这些争端:

https://github.com/OpenDocCN/freelearn-devops-pt3-zh/raw/master/docs/slfc-anti-ptn/img/B30991_07_03.jpg

图 7.3 – 软件包结构

她最终将大部分时间都花在了调解这些跨供应商冲突上。这也意味着她几乎没有时间去调查供应商在那些不涉及争议领域中使用的通用方法。

然而,最终,系统被构建完成。由于每个供应商都只在自己的环境中工作,偶尔才将代码部署到经过薄弱测试的集成环境中,因此准备进行用户验收测试UAT)的第一步是将所有软件包部署到一个共享环境中,并测试基本流程。每个软件包都在自己的环境中经过了彻底测试,但尚未对跨软件包进行系统性测试。

即使在测试结果开始出来之前,情况也开始恶化。事实证明,供应商之间存在不兼容的系统和软件包设置——例如,CPQ 管理的软件包上就存在这种情况。这意味着部署被迫停滞,直到找到解决方法。

当测试人员真正开始工作时,情况变得更加糟糕。软件包之间存在许多细微的不兼容问题。例如,对于公共字段的解释和使用存在差异,不同的软件包使用相同目的的重复字段,以及部分重叠范围的自定义对象和冗余数据的创建。此外,三个供应商之间在自动化模式上也存在很大差异,尽管这是 Abigail 在项目初期已经指定了标准的领域。

总的来说,差异太大,无法迅速协调一致,项目不得不后退。Abigail 的上司谈判延长了时间表,以便重构软件包并使其统一。虽然她对延期感到高兴,但 Abigail 并不喜欢为了让供应商真正完成这项工作而进行的拉锯战。

问题

有时候,你可能希望让团队独立工作,而不必依赖或协调其他团队。在 Salesforce 的上下文中,这可能是因为各个团队在不同的云环境中工作,来自不同的供应商,或代表着你组织内不同的部门或业务单元(BU)。

这完全可以理解,因为协调问题确实很难解决。然而,当这种情况成为将 Salesforce 平台划分为包的基础时,它就变成了一种 DevOps 反模式。

提议的解决方案

使用包来创建孤岛的提议解决方案是,给每个团队分配自己的包来工作,反映出它们将要处理的内容。这避免了协调问题,但也带来了一系列其他问题。

这意味着你根据组织需求而非架构来结构化你的项目包设置。一开始看起来这可能是个不错的主意,显然也能短期内满足各个团队的需求,但不幸的是,这也意味着潜在的隐藏冲突很可能会存在,并且可能会保持隐蔽很长时间。

结果

使用包来创建孤岛的可能结果是,你将会遇到隐藏的冲突,直到包集成时才会显现出来。

这些冲突包括以下情况:

  • 数据模型的不同使用——例如,字段和对象

  • 安全模型中的问题,当使用了冲突的配置时

  • 冲突的流程、验证规则或其他业务逻辑

  • 偏离最佳实践,例如,在同一对象上有多个触发器

  • 在同一对象上使用不同的自动化模式

  • 关于系统设置的冲突假设

  • 在不同的包中复制的功能,经常只是部分重叠

这可能会导致严重问题,而且重构起来会非常麻烦,既昂贵又耗时。

更好的解决方案

通常来说,包设计应当被非常重视。基于包的开发是大多数大规模 Salesforce 项目的正确选择,部分原因是它比其他替代方案更具可扩展性。

为了避免陷入使用包创建孤岛的反模式,请遵循以下准则:

  • 在设计包结构时要考虑架构。例如,在典型的按服务线拆分的架构中,你可以将公共功能放在一个“Common”包中,所有其他包都依赖于该包,然后为每个服务线创建包含相关组件的单独包。你还可以有跨服务线的高层次包,处理诸如常见集成之类的内容,并且可以将交叉功能拆分到单独的包中,尽管这可能有些难以管理。重点是,你应该确保干净地管理依赖关系,并避免潜在的冲突重叠。

  • 小心处理依赖关系;分层方法可以有效地确保依赖关系仅朝一个方向流动。

  • 在需要时,让团队跨包工作。

  • 考虑让特定团队拥有特定的包,而其他团队如果需要任何东西,则向它们请求工作。

  • 通过技术治理论坛进行协调——例如,架构委员会。

在现代 DevOps 工作流中,利用如 Salesforce CLI 这样的工具对于有效的源代码跟踪和版本控制至关重要。Salesforce CLI 简化了集成过程,使开发人员能够轻松管理和部署跨环境的变更。通过利用源跟踪功能,团队可以确保开发过程中的一致性和准确性,增强协作并减少错误。这种方法使得元数据和代码变更的高效管理成为可能,与敏捷开发的最佳实践保持一致。

Salesforce DX 解锁包是 Salesforce 生态系统中现代开发工作流的关键组成部分。它们使开发人员能够创建模块化和可重用的组件,促进代码组织并改善团队协作。通过有效管理包版本和依赖关系,团队可以简化其 CI/CD 流程。解锁包还支持更细粒度的源代码跟踪方法,允许团队在不影响整个代码库的情况下,专注于不同的功能。通过使用解锁包,组织可以提升其开发实践,使其更加灵活,能够快速响应业务需求的变化。

一般来说,你不想把包设计误认为其他东西。构建你的包结构时,确保它适合你的架构并且对开发人员可行。

无测试的测试

测试是任何大型软件项目中的关键活动。在本节中,我们将看到,试图避免编写必要的单元测试可能会在中长期内引发重大问题。

虚拟单元测试

虚拟单元测试反模式通过编写虚拟测试绕过 Salesforce 内置的单元测试要求,这些虚拟测试优化了覆盖率,但 什么都不做

示例

TruckCo 是一家初创的汽车公司,专注于构建下一代电动卡车。它更看重自己是科技公司而非制造公司,因此在顶级解决方案上的投资相当重,以保持技术领先。

一般来说,TruckCo 倾向于进行重度定制和高强度的敏捷项目,工作时间长且时间紧迫。TruckCo 目前在 Salesforce 上构建的供应链应用程序也不例外。

该应用程序将把他们的 B2B 商务门户与订单管理和供应链后端系统集成。它将实现来自备件供应商的 准时JIT)订购,并且通常会显著缩短 报价到收款QTC)过程,特别是在备件订单方面。

为了实现这些目标,TruckCo 计划将六个关键的后台系统与 Salesforce 集成,构建一个为其特殊流程优化的定制用户界面UI),并构建一套跨平台的、支持 AI 的自动化系统,以提高订购过程的效率。

由于这个应用程序预计将是一个以代码为主、开发驱动的项目,TruckCo 决定将一支 Java 开发团队从固定员工中调过来参与,认为 Apex 与他们的背景足够接近,能够边做边学。Yana 是项目中唯一的传统 Salesforce 专家,她的角色是引导其他团队成员了解 Salesforce 的工作方式。

团队负责人 Matt 有点特立独行,其他团队成员也是如此。虽然他们使用单元测试,但并不总是坚持使用,通常更倾向于让用户报告错误,然后再修复它们。在 TruckCo 内部,虽然没有明确说明,但存在着强烈的偏好:即使这意味着发布一个有缺陷且不完整的产品,也要按时发布。

来自 Java 背景的开发人员很快开始对 Salesforce 强制要求的 75%单元测试覆盖率感到不满,而这一规定已被 Salesforce 部署工具所内置。Yana 在和团队其他成员共进午餐时,偶然提到了一些通过创建虚拟测试来欺骗 Salesforce 单元测试计算的方法。

尽管她开玩笑提到过此事,但令她懊恼的是,几天后,她发现虚拟单元测试开始出现在代码库中。当她向 Matt 提出这个问题时,他只是耸耸肩,表示他们已经落后于进度,因此没有时间全力编写测试代码。

然而,Yana 并没有气馁,在下次项目会议上,她正式提出了这个问题。她引用了 Salesforce 的指导方针,并得到了公司内部 Salesforce 架构师的支持。

项目赞助人承诺会派人调查这个问题。不幸的是,Yana 之后再也没有听到任何相关信息。似乎 Matt 曾表示,如果需要追溯性地编写完整的单元测试,将会导致项目出现重大延迟。按照 TruckCo 一贯的运营方式,这被视为不可接受,因此虚拟单元测试的问题被忽略了。

因此,随着项目进度的进一步落后,实践的加速也在持续。接近上线时,几乎每一个新的单元测试都是虚拟的。虽然自动扫描工具显示出令人印象深刻的 90%覆盖率,Yana 怀疑实际覆盖率是否高于 10%。

在上线前几周,来自业务利益相关者的一系列最后时刻的变更被提出。Yana 看不出有任何办法将这些变更纳入项目中,但 Matt 同意按时交付这些变更。

最后一段是来回变更的繁忙时期,测试人员发现了许多错误,接着是修复,这通常导致更多的回归问题。这种情况一直持续到实际的用户验收测试期间,又发现了大量问题。然而,没有人决定停止上线,并且在指定的日期,供应链应用程序正式上线。

当用户开始在应用程序上进行登记时,在主要流程中发现了几个严重的错误。这些错误出现在距离上线仅几周之前已经测试并且正常工作的区域,并且也是用户培训的一部分。

应用程序必须下线,并且召开了一次升级会议。在这里,应用程序的基本健全性和质量受到了严重质疑,并且达成了一个新的计划来研究质量问题并设计一种修复它们的方式,以便应用程序可以重新上线。

问题

虚拟单元测试旨在解决一个非常简单的问题:如何绕过 Salesforce 生产部署中严格的 75%单元测试限制?长期运行的 Salesforce 项目通常发现,无论是特定部署还是总体而言,它们都处于这一限制之下。

许多团队发现这种限制很烦人。特别是在开发人员从其他技术平台转移到 Salesforce 时,这一点尤为明显,在压力之下,或者在做一些“简单”的事情时。

提议的解决方案

提议的解决方案是创建虚拟单元测试,仅仅优化代码覆盖率,而不真正测试任何东西。这是少数几个接近糟糕实践的反模式之一。你可以在以下代码片段中看到一个虚拟测试的示例:

@isTest
class dummyTest{
  static testMethod void notRealTest(){
    //assume A is a class with two methods
    A aInstance = new A();
    aInstance.methodA();
    aInstance.methodB();
    //nothing is done to test anything
  }
}

然而,这是一种可能会引诱到否认严肃 Salesforce 从业者有时可能会参与的行为。当你在压力下要达到冲刺目标或部署期限时,写一堆单元测试只是为了提高覆盖率,看起来可能是在浪费时间。

但显然,这种态度未能认识到单元测试提供的真正价值以及覆盖率强制执行的原因:没有良好单元测试的代码比有这些测试的代码更加脆弱且容易回归。因此,即使在压力之下,跳过它们也是一个真正糟糕的主意。

结果

这种模式往往导致千刀万剐。虽然你可能短期内不会感受到不良影响,但是过段时间后,你将没有任何真正可靠的单元测试可以依赖。

更糟糕的是,如果你仍然认为你只是在几个地方偷了懒,并且通常可以依赖你的测试,你可能会在心理上产生一种错误的安全感。基本上,你正在欺骗系统,很可能会发布质量低劣的代码。此外,你正在创造大量的技术债务,组织在某个时候必须支付它们。

更好的解决方案

解决这种反模式的方法很简单:构建良好的单元测试,并始终满足最低标准。你绝不能妥协最低要求,否则会导致代码质量和交付质量随时间恶化。

关于构建良好的单元测试,有很多指导意见,所以我们只重复几个基本要点:

  • 单元测试应该测试代码中的单一功能

  • 测试应该在代码之前编写

  • 测试应该以便于重复执行的方式编写

  • 测试应该独立于其他测试

  • 测试不应依赖于组织数据,而应创建自己的测试数据,理想情况下使用测试数据工厂

  • 测试应该简洁

  • 应使用断言来检查是否得到了预期的结果

  • 测试应该同时测试正面和负面情况

  • 测试应该经常运行,最好是自动运行

  • 测试应该易于理解和维护

除了传统的测试方法外,考虑加入现代测试框架,如 ApexMocks、Jest 和 Mocha。这些框架提供了强大的功能,用于单元测试和在各种编程环境中的模拟,促进了更高效、更有效的测试过程。熟悉这些工具可以显著提升你的测试策略,并提高代码质量。

这是一个罕见的反模式,通过遵循良好的实践就可以避免,因此一定要避免这种情况。

DevOps 集成的挑战

随着 Salesforce 平台的日益复杂化,组织推动更快的交付周期,许多团队发现自己在将现代 DevOps 实践融入其架构方法中时遇到困难。虽然 DevOps 的承诺非常吸引人——更快的发布、更高的质量和更可靠的部署——但现实往往未能达到这些期望,尤其是在 Salesforce 生态系统中,传统的开发模式可能与 DevOps 原则发生冲突。

考虑一下 FinTechCo,一家快速增长的金融科技公司,正在将 Salesforce 作为他们新的客户互动平台。像许多组织一样,他们以极大的热情开始了 DevOps 之旅,实施了所有正确的工具——Git 仓库、CI/CD 管道、自动化部署和用于开发的 Salesforce DX。它们的首席架构师 Sarah 精心设置了技术基础设施,相信这将改变他们的交付过程。

然而,随着项目的推进,团队发现,单单拥有 DevOps 工具还远远不够。开发人员仍然直接在沙盒中进行更改,只有在被提醒时才会提交到 Git。自动化测试套件依然稀缺,大多数测试仍然是手动执行的。由于不同团队成员遵循不同的流程,CI/CD 流水线经常中断。环境间的集成问题也日益严重——一个开发人员的临时组织中能正常工作的功能,在另一个开发人员的组织中就会失败,而那些通过所有自动化测试的变更,有时会在集成环境中导致功能故障。

这种情况在 Salesforce 生态系统中频繁发生,许多组织在实施 DevOps 工具时并没有充分接受所需的文化和架构变化。挑战不在于工具本身,而在于团队在开发和部署方式上所需的根本转变。团队常常发现自己处于短期内需要交付功能与长期内需要建立可持续交付实践之间的矛盾之中。

这种情况通常是逐渐恶化的。团队开始为紧急修复绕过 DevOps 流程,直接在更高级的环境中进行更改。环境状态变得不一致,跟踪变更也变得越来越困难。最初偶尔偏离流程的情况变成了常态,破坏了 DevOps 本应带来的好处。

在 FinTechCo 公司,这个问题在一次关键的部署过程中达到了高潮,该部署在计划的发布窗口期间反复失败。团队发现,各个环境中的不同组件有不同的版本,而且没有人能自信地说出哪个版本应该被视为正确的。发布不得不推迟,团队需要手动协调这些差异——这正是 DevOps 应该避免的情况。

根本原因通常在于将 DevOps 视为一种技术转型,而非架构和组织层面的转型。团队实施工具时,并未重新设计其开发流程和解决方案架构,以支持现代交付实践。这在理想流程与团队日常面临的实际现实之间制造了脱节。

在 Salesforce 中成功实现 DevOps 需要从根本上重新思考架构方法。这意味着要考虑如何打包和部署元数据,如何管理环境,如何自动化测试,以及如何跟踪和版本化变更。这意味着要做出支持持续交付的架构决策——例如,设计可独立部署的功能,并从一开始就在开发过程中构建自动化测试。

组织需要认识到,DevOps 不仅仅是加快部署——它还意味着在开发过程中构建质量和可靠性。这可能意味着做出架构上的权衡,例如在如何进行更改的灵活性上做出牺牲,以换取更可靠的部署。这也可能意味着重新设计功能,以支持部分部署,而不是要求全部或无部署。

前进的路径通常是从小做起,逐步扩展。成功的组织通常不会试图一夜之间完成全面转型,而是从一个团队或项目开始,允许实践逐渐成熟后再扩展。这种方法可以让团队在适当管理风险的同时学习和适应,也为展示成功提供了机会,从而为更广泛的采纳争取组织支持。

最重要的是,组织需要认识到,DevOps 转型是一段旅程,而非一个终点。它需要持续的改进承诺、从失败中学习的意愿,以及在团队发展新技能和习惯时的耐心。目标不是完美的 DevOps 实施,而是构建一种可持续的交付方法,平衡速度与可靠性。

成功来自于将架构决策与交付实践对齐,构建强大的自动化测试方法,围绕开发过程建立明确的治理框架,并投资于团队培训和文化变革。这意味着在标准化与灵活性之间做出艰难的选择,决定在哪些方面强制执行流程,在哪些方面允许偏差,以及如何平衡短期交付需求与长期可持续性。

通过将 DevOps 视为一种架构挑战,而不仅仅是工具挑战,组织可以避免表面化采用的常见陷阱,并建立真正支持其业务需求的交付实践。这需要仔细思考架构决策如何影响交付能力,以及交付实践如何影响架构选择。只有同时处理这两个方面,组织才能在其 Salesforce 实施中实现现代 DevOps 实践的真正好处。

了解要点

在本节中,我们将从具体的模式中提取一些更广泛的学习要点,帮助您在日常工作中作为 Salesforce 架构师使用,或者为准备 CTA 审查委员会考试做好准备。

在设计 Salesforce 解决方案时,您应该注意以下几点:

  • 不要把所有的鸡蛋放在一个篮子里。在可能的情况下计划较小的发布,以降低风险并获得反馈。

  • 面对将功能拆分成更小模块时可能出现的艰难决定。不要仅仅接受“从第一天开始必须包含所有内容”的说法。

  • 总是在项目时间线的早期阶段就面对关键的架构权衡。这些问题通常不会随着时间推移变得更容易处理。

  • 清楚和公开地沟通需要做出的权衡和各种选择的选项。试图取悦每个人并掩盖问题是灾难的开始。

  • 不要让团队竞争或组织内部的信息孤岛来决定你的开发模型,无论是基于包的开发还是其他方式。

    相反,确保你的开发模型与你追求的架构一致,并相应地组织组件和包。

  • 集成现代化的 DevOps 实践,包括 CI/CD 流水线、自动化测试和版本控制,以提升交付质量。

  • 在 Salesforce 中,单元测试是一个必须。不要因为压力而妥协。

  • 编写高质量的单元测试将确保你拥有更高的代码质量和更少的回归问题。

在准备 CTA 审查委员会考试时,你应该注意以下事项:

  • 面对复杂的大型场景时,更倾向于敏捷的、多版本发布的流程,而不是单一的大爆炸式发布。

  • 然而,有些情况似乎更适合瀑布/大爆炸式的方法。这可能是理事会最佳实践和现实之间差异的一个领域。在当今快速发展的技术景观中,对于 CTAs 来说,理解 DevOps 和现代开发实践日益关键。这种知识不仅增强了开发与运维团队之间的协作,还使 CTAs 能够更好地支持组织实施敏捷方法、CI 和持续交付,从而推动创新和效率。

  • 你应该非常清楚你所做出的权衡,并将其包含在你的理由中。

  • 如果你不能做出合适的选择,几乎可以肯定会在问答环节中使你的解决方案崩溃。

  • 基于包的开发是 Salesforce 项目的新兴开发模型,但这并不意味着它适合你的场景。如果适合,对一个良好的包结构有所了解将可能给你带来额外的赞誉。

  • 知晓单元测试的最低限度以及它们何时适用,以便在被问及时能够作答。

  • 同时,准备好回答关于什么是好的单元测试以及如何利用它们提升代码质量的一般性问题。

现在我们已经完成了本章的内容,并准备进入下一章。但首先,我们将总结我们的学习。

总结

在本章中,我们看到了开发生命周期如何受到不同抽象层次的反模式影响的示例。在最高层次上,你如何处理关键的权衡以及如何结构化你的发布对项目的潜在成功有着巨大影响。

然而,我们也看到技术元素,比如你如何组织你的包和是否编写了良好的单元测试,可以成为项目成功或失败的重要因素。这意味着你必须掌握所有这些层次,才能在这个领域成为成功的架构师。

对于许多架构师来说,相较于解决方案架构或硬核技术领域,这个领域可能被视为优先级较低。然而,对这些问题的忽视,可能会导致严重的项目失败,就像一个设计糟糕的解决方案一样容易。

话虽如此,我们现在将继续讨论最后一个领域——即沟通——并看看我们如何通过错误的沟通方式弄乱我们的 Salesforce 项目。

第八章:无误传达的沟通

这一章节在结论之前,将讨论围绕如何向不同受众传达架构的反模式,结合新的变更管理部分的见解。第一部分描述了与信息控制相关的反模式。接着,我们将探讨几个与沟通清晰度相关的反模式。第三部分,我们将分析一个特别针对你创建架构文档方式的反模式。最后,我们将讨论如何避免低估变更管理带来的挑战。正如我们一直在做的那样,我们将在章节结束时总结我们的关键收获。

本章将涵盖以下主要内容:

  • 过度沟通在某些情况下可能比沟通不足更糟,特别是当与通才观众沟通时

  • 为了避免做出决策而故意保持模糊,可能会对项目造成严重损害

  • 人们似乎无法理解你所说的内容,往往是你需要解决的潜在问题的一个症状

  • 为什么在记录技术规范时偏离标准几乎总是个坏主意

  • 高效的变更管理实践对于成功的架构实现至关重要

完成本章节后,你将更好地理解技术沟通如何出错。更重要的是,你将掌握一系列具体的方法,帮助你避免常见的技术沟通陷阱。

沟通过多

本节将探讨在技术环境中沟通过多时会发生什么。为此,我们将首先探讨一个直接来自认知心理学的反模式:认知负荷。

认知负荷

认知负荷发生在所呈现的信息量变得过于庞大,以至于接收者难以承受,进而影响行动。

示例

LilacCo,全球领先的香薰蜡烛生产商,面临着严重的集成问题。它最近购买了 MuleSoft 平台,但使用率很低,大多数集成仍通过遗留中间件或点对点方式进行。

马丁是一位技术架构师,负责为 LilacCo 提出解决方案,以解决其面临的各种问题。这些问题包括许多集成的高延迟和慢速性能、糟糕的日志记录和监控、冗长且容易出错的开发周期,以及无法为几个关键遗留系统创建新集成。

马丁深思熟虑后得出结论:系统地迁移到 MuleSoft、实施更多事件驱动和异步集成、为老旧遗留系统编写一些关键适配器 API,并提供一个清晰的错误处理和日志记录模式供所有团队使用,将能解决问题。

这不是一个简单的修复方案。马丁制作了一份幻灯片和配套的报告,报告有数百页。材料中包含了许多技术图表,尽管他尽力进行了适当的总结,但他觉得这些材料只能简化到某个程度,否则就会失去所要表达的核心内容。

马丁向董事会展示了他的最新模型。不幸的是,提问的过程中,大家并没有真正理解他试图传达的信息。人们停留在一些相对不重要的细节上,无法抓住整体计划的核心。

他收到了反馈,指出他提出的模型过于复杂,需要找到一种更简化的方案。马丁感到非常恼火。他已经觉得自己提出的计划是最简化的了。各个元素彼此依赖,去除任何一个都会影响整体方案。

马丁试图与他最熟悉的董事会成员安排一对一的谈话,以便重新向他们阐述自己的关键观点。即便在这种更为亲密的环境中,马丁也发现很难传达自己的观点。关键内容似乎总是在沟通过程中丢失了。

接着,马丁被告知,一个新的集成平台供应商已经向董事会展示了他们的方案,大家对他们带来的新方法感到非常兴奋。马丁被要求提供反馈,他以详细而有深度的反驳形式给出了反馈。他总结道,尽管这个新平台确实有一些令人兴奋的功能,但并没有解决 LilacCo 面临的根本问题。

然而,马丁的反馈并没有起到太大作用。供应商提议进行一次免费的概念验证POC),以增强他们软件能力的信任,董事会接受了这一提议。马丁没有被要求加入 POC 团队。

六周后,POC 以轰动性的成功告终。在这段时间里,团队能够展示出所需的所有功能。当然,这一切都只是试点阶段,且仍有许多复杂性,但董事会通过团队提供的演示感到非常有信心,认为新的软件将能提供所需的功能。

马丁询问是否可以查看 POC 的具体细节以及实际演示了哪些内容,但他的请求被默默忽视。随后,供应商提交了一份正式提案,提案被接受,新项目即将启动,以实施新的集成平台。

问题

认知负荷是心理学中的一个术语,指的是当我们的脑海中充满了过多信息或选择,以至于我们无法采取正常情况下应该采取的行动。在技术沟通中,通过在呈现架构选项时提供过多的信息来创造认知负荷,是一个非常常见的反模式。

这尤其发生在我们向非技术性受众传达信息时。对于技术性受众,我们可以在很大程度上依赖对图表格式、标准做法、良好实践、架构模式等的理解。

这可以减少此类受众的认知复杂性,尽管即使是经验丰富的从业者,复杂的架构也仍然可能很难理解。然而,当你试图向普通受众传达这些信息时,就不能依赖这些支持,因此,传达关键权衡和许多动态部分的任务可能非常困难。

提出的解决方案

认知过载本身并不是解决方案。导致认知过载的原因是认为你需要在展示中包含一定的细节,才能对受众公平或在主题上做到全面。

我个人认为,许多有才华的架构师会因为一种知识上的诚实感而陷入这种反模式。他们已经考虑了许多选择,并且对他们所提议的解决方案的利弊、正反观点都有所了解。

因此,他们会觉得在推荐自己选择的解决方案时,单纯地坚持一个高度简化的版本是不诚实的。在业务利益相关者是最终决策者的情况下——即使是在看似架构的决策中,这种情况也常常发生——几乎不可避免地会导致认知过载。

结果

显而易见的结果是沟通失败。你的主要建议和支持点在一堆受众无法处理的信息泥潭中迷失了。

这意味着你会失去受众的注意力,最终也失去了影响他们做出你希望的决策的能力。认知过载会导致无动于衷,因此最可能的结果是你所提议的内容无法产生任何效果,因为它没有被吸收。

这也为其他竞争者提供了机会来传递不同的信息,正如我们在示例中所看到的那样。在我们这个行业中,不幸的是,往往是最有利的营销信息推动了技术的采用,而不是从技术角度来看最优的选择。

更好的解决方案

有效的沟通不是几句话就能教会的。然而,你应该记住的是,简化复杂的信息使其足够容易理解对于受众来说非常重要。

一般来说,做以下几点:

  • 根据受众及其理解程度来结构化信息。

  • 除非你确实知道受众了解你所提议的基本内容,否则不要假设他们已经知道。

  • 关注一个主要信息;不要在主信息旁边加入太多附加信息。

  • 不要包括你在过程中考虑过的所有额外的考虑事项和选项。

  • 使用图片、图形、表格等来帮助传递信息。

  • 如果有人想深入了解某个领域,请准备好备份材料,但不要事先包含这些内容。

总体而言,你应该小心对观众提出要求。他们有很多事情要处理,有限的时间来参与你所说的内容。确保那段时间是有价值的。

以多种方式不清晰

在本节中,我们将探讨两种反模式,它们通过不同的方式探讨技术沟通中有意或无意的模糊性。我们首先探讨一种反模式,它试图出于战术目的利用模糊性,但最终造成了不利影响。

模糊的解决方案

模糊的解决方案提议通过模糊的语言和表现形式将冲突或不确定的决策隐藏起来,从而推迟作出决策的必要性。

示例

GrillCo,一家专注于户外烹饪设备的主要在线零售商,在其订单管理过程中面临重大问题。经常出现意外的缺货情况,交付时长和费用计算错误,且税务未能 consistently 正确应用。

这并非完全是 IT 问题,实际上,已经确定了许多流程改进的领域。然而,作为更广泛的订单管理转型的一部分,GrillCo 管理层还决定需要为订单管理过程引入一个新的软件平台。

然而,关于该选择哪种软件及如何实施,存在几种不同的意见。有些人支持将其集成到 Salesforce CRM 中,使用现成的订单管理模块。其他人则倾向于与一个专注于零售的供应商合作。最后,IT 部门则更倾向于自己实现该功能,使用他们已经建立的微服务架构。

Rainer 负责订单管理实施的技术项目管理。他试图促进不同提案之间的讨论,但问题在于似乎没有人知道该由谁来做出决策。

与此同时,还有许多其他较小的技术任务需要处理,因此 Rainer 专注于这些任务,将新的订单管理系统作为图表、演示和文档中的通用功能。他认为最终会找到解决方案,因此没有必要激起波澜。

然而,随着其他方面的转型推进,资深利益相关者们开始更加迫切地关注这个问题。由于他未能通过与人交谈达成共识,他提议进行正式的供应商选择,制定明确的标准,并将其作为决策过程。

然而,当他开始为选择过程做准备时,他做出了一个惊人的发现。两个团队分别根据自己对需求的理解,已经分别实施了完全不同的订单管理软件试点。

  • 第一个问题出现在 IT 部门,几位开发人员已经开始开发新软件原型,展示他们的微服务平台有多么灵活和强大。尽管它具备一些不错的功能,但在 Rainer 的评估中,它并没有真正满足业务的实际需求。

  • 第二个试点更进一步,已经在基于现有电商解决方案的数据的模拟订单场景中运行。它基于一个来自小型零售导向软件供应商的标准软件,该供应商正在大力投资进行必要的适应以满足 GrillCo 的需求。然而,Rainer 再次评估认为,距离这个解决方案真正适用还需要做很多工作。

一场戏剧性的会议随之而来,CIO 和 IT 团队站在一方,COO 和供应链团队站在另一方,双方各自支持其中一个解决方案。会议以僵局结束,决定引入一名独立顾问来评估这两个方案并提出建议。

GrillCo 请来了一位在订单管理解决方案领域享有盛誉并备受尊敬的专家,他花了几周时间审查试点软件。专家的评估令人堪忧。

两个试点方案都没有提供 GrillCo 所需的能力水平。他建议放弃这两个方案,而是重新回到市场寻找更合适的解决方案。Rainer 对技术供应商选择过程的演示进行了修改,并开始着手工作。

问题

一些决策是很难做出的。这可能是因为政治原因——也就是说,不想通过一个不受强大利益相关者或团队喜欢的决策去得罪他们。也可能是因为缺少信息,这些信息只有在过程的后期才能出现,因此现在做决策变得更加复杂。

避免做出有争议决策的艺术,即通过推迟决策来回避问题,是模糊解决方案反模式所涉及的核心问题。虽然花时间收集更多具体信息以显著提高决策质量是合理的,但如果过度推迟决策,无论是出于政治原因还是对决策错误的普遍恐惧,这都会成为反模式。

提议的解决方案

模糊解决方案反模式提出通过将困难决策隐藏在模糊性背后以应对问题。这可以通过诸如能力模型、将决策推迟到独立的决策过程,或者仅仅列出多个备选方案(例如,在图表和文档中)来轻松实现。

在很多情况下,这可能是一个非常有吸引力的选项;例如,你可能知道某些高级利益相关者偏爱某种方法,而你已经确定这种方法不可行。通过掩盖模糊性,你可能希望推迟直到项目进展到无法改变的阶段,再让这一点变得明朗。

你也许还在悄悄地希望,随着项目的进展和更多信息的出现,决策会变得更加容易;要么某些选项将无法激活,要么答案会变得显而易见。

也就是说,你希望通过无限期推迟,避免处理一个充满高度不确定性或冲突的情况。这是非常人类的行为,但不幸的是,这是一个糟糕的架构实践。

结果

当然,最终你必须面对你一直回避的问题。如果你运气好,决策现在会变得容易,因为大部分选择已经被排除。但这其实并不是好事。

很少会出现可以最快实现的选项也是最优解决方案的情况。因此,你拖延处理问题几乎总会导致比早点做出决策更糟糕的解决方案。

在决策不必要时保持选项开放是有其道理的,但如果你保持得太久,会对解决方案产生不利影响。而且,在关键的架构决策上保持选项开放过久通常是有问题的。

如果你运气不好,决策依然不会明显;你仍然必须面对不确定性和冲突,但现在它们会因为你等待所带来的额外时间压力而加剧。这对于你个人和项目来说,都是一个更糟糕的结果。

更好的解决方案

首先,不要把决策推迟到最后期限过期。如果你没有必要的信息,制定一个清晰的计划,设定一个明确的获取信息的最后期限。然后,规划一个决策过程,无论其他情况如何,都将在那个时间点做出决策。

如果决策在政治上不受欢迎,试着让你在组织内的支持者在你做出并传达决策时站在你这边。总有风险因为政治原因做出错误的决策。

然而,即使是错误的决策也总比在某个时刻没有做出决策要好。至少你会有所进展,并且能够更早开始减轻错误决策的后果。

当需要做出决策时,在文档和演示中明确标出,以便利益相关者意识到决策即将做出。即使可以模糊处理,也不要躲在模糊的背后。

如果你无法通过共识做出决策,看看是否能够让利益相关者同意一个正式的决策过程。通常,人们发现自己更容易接受一个正式过程的结果,而不是某个人的个人意见。

土拨鼠日

土拨鼠日反模式发生在即使经过多次反复解释后,人们仍然不断地问同样的问题。

示例

Rolf 正在为 MediCo 领导一个本地 Salesforce 实施项目,MediCo 是一家医疗器械制造商,业务遍及大部分欧洲市场。Salesforce 实施方案由巴黎总部的员工定义,计划按原样推广到其他国家的子公司。

Rolf 被赋予了将该系统推广到德国子公司的责任。德国分公司是 MediCo 的新业务,去年才被收购。因此,它还没有完全融入 MediCo 的标准流程或 IT 基础设施。Salesforce 实施被视为改进这一状况的一种方式。

当他向德国团队展示法国和其他国家现有的 Salesforce 实施方案时,他遭遇了一连串的问题。团队想深入探讨一些非常具体的流程问题,Rolf 无法回答这些问题,因为他不了解德国业务的详细情况。

他收集了大量问题,并尽力以书面形式回答这些问题。然而,他很快感觉自己像是在玩打地鼠游戏。每当他似乎回答了一个问题,另一个相似但略有不同的问题就会从其他员工那里冒出来。

Rolf 开始整理所有问题,并准备了清晰简明的答案。由于困惑程度很高,他无法在实施过程中取得实质性进展,因此决定再尝试一次。

他再次召集德国团队,向团队成员介绍新 Salesforce 系统的要点,并尽可能系统地解答到目前为止提出的所有问题。然而,他再次遇到了更多困惑的目光和那些他认为已经回答过一遍的问题。

感到沮丧,几乎准备放弃时,Rolf 决定打电话给公司的一位老导师,他知道这位导师了解德国子公司现状。她告诉 Rolf,问题可能根本不在于他的沟通技巧。

德国子公司员工更喜欢按自己的方式做事,并且反感总部的强加。Salesforce 只是表达这种反对的借口。即使这个系统是自切面包以来最完美的东西,德国团队依然会原则性地反对它。

在掌握了新知识后,Rolf 决定制定一个新计划。他大胆决定公开问题。他又做了一次演示,明确表示自己知道反对的真正原因,并且他并不打算解决所有的顾虑,而是邀请团队参与其中,看看是否能找到让新系统“自我”的方法。

虽然系统本身已经是现状,并且总部不打算批准许多本地的变化,但德国运营如何决定采用并将其融入到自身流程中仍然悬而未决。罗尔夫将实施过程开放给德国团队,并欢迎他们提出如何最好使用新 CRM 的建议。渐渐地,部分人开始参与,虽然时间表需要调整几次,但最终,采用是成功的。

问题

有时,人们似乎根本不理解你在说什么。无论你多么努力地解释一个观点,或是解释了多少遍,似乎都无法让你的观点传达出去。

“土拨鼠日”反模式,得名于同名电影,描述了这种情况——你似乎无法把某个信息传达足够多次,以至于它产生任何影响。

这意味着你觉得自己一直在往墙上撞头,却没有留下丝毫痕迹。通常,这是因为你并没有真正处理正在发生的根本问题。

提出的解决方案

当你陷入“土拨鼠日”反模式时,你通过大量重复自己来回应那些似乎永无止境的、关于相同问题的提问。你可能用不同的语言或不同的方式重复自己,但你始终是在重申相同的信息。

有时,它让生活感觉像是无休止的重复,仿佛你根本没有任何进展。你开始质疑自己的理智,也开始质疑那些持续质疑你的人们的理智。

这通常是因为你并没有真正关注问题出现的根本原因。通常,当同样的人问你同样的问题超过几次时,某种形式的抵抗在发挥作用。

也许,人们觉得一个不好的决策是在他们不知情的情况下做出的,而他们正在试图拆解这个决策。也许他们担心你提出的方向会给他们带来不好的个人后果。

人们可能会有许多理由抵制你的信息,而这些理由与信息的呈现方式或沟通方式无关。在这种情况下,问题变得更多的是关于变更管理,而不是沟通。如果你是一个实践中的架构师,意识到这一现象并能抓住它是一个关键的软技能。

结果

“土拨鼠日”反模式的结果在个人层面和项目层面都会带来显著的负面影响:

  • 首先,你无法通过你尝试传达的信息达到任何目标,而这些信息通常需要被你所沟通的受众接受。

  • 这会让你感到沮丧,因为你不断思考如何更好地与受众沟通你的信息,但却始终失败。

  • 它让你沟通的对象感到沮丧,因为他们觉得你没有倾听他们真正的关切。

  • 同时,项目通常会停滞不前,关键领域的进展可能因沟通障碍而被阻碍。

总体而言,这种反模式可能对你的项目和你个人造成严重的压力。

更好的解决方案

第一步是认识到问题的存在,并且要明白问题不在于你找到一种更好的方式来表达相同的内容。

一般来说,你应该做以下几点:

  • 一旦你开始听到类似的问题不断以略微不同的方式重复出现,暂停一下并退后一步。

  • 与利益相关者和盟友合作,弄清楚你所面临的抵触背后真正的原因。

  • 如果你发现有些问题背后的原因不仅仅是理解上的困难,积极寻找一种替代方法,而不妥协你的核心目标。

  • 然后,应用良好的变革管理实践,帮助推动所需的转型。

你不能总是满足人们的所有需求,但你可以找到一种方法来承认他们的真实关切,并对他们的反馈保持开放态度。

画出过于创意的图表

本节探讨了当你尝试用过度创意来传达技术信息,而不是依赖于社区内的既定实践时,会发生什么情况。我们通过查看非标准文档的反模式来阐述这一点。

非标准文档

非标准文档 指的是一种反模式,其中团队以独特的格式编写技术文档,而不是依赖标准的做法。

示例

SafeCo 是一家为设施管理提供安全解决方案的领先供应商,目前处于新的 Salesforce 实施的愿景规划阶段。它正在尝试通过技术彻底转型其业务,并已将 Salesforce 作为解决方案的一部分。

SafeCo 的战略经理秦正在主导愿景规划工作,并得到一家在设计思维方面有独特优势的外部咨询公司的支持。他们举办了一系列极具吸引力的研讨会,最终得出了新战略技术平台的愿景和关键需求。

研讨会的成果以大量富有表现力的图画和临时图表形式记录下来,许多图表结合了流程设计、数据模型和用户体验原型的元素。参与研讨会的高级管理人员对成果非常满意,甚至决定将这些成果包含在将发送给潜在供应商的提案请求RFP)材料中。

SafeCo 从三家供应商中筛选出符合要求的公司,这些公司在其 RFP 响应中明确提到了研讨会的成果。经过最终展示后,SafeCo 选择了全球最大的 Salesforce 合作伙伴之一,根据研讨会成果中所陈述的要求执行实施。

然而,一旦供应商动员起来并且项目进入正式的探索阶段,问题就变得明显了。SafeCo 认为在提供的文档中显而易见的许多功能和需求,并没有包含在供应商的估算中。

SafeCo 向供应商施压,指出 RFP 中提供的文档。然而,供应商对文档的解释提出异议,且证明无法明确展示争议中的许多要点的意图。

一度,SafeCo 考虑重新寻找供应商,但该供应商是唯一一个能够在其所需时间表内提供所需技能组合的公司。高级管理层不愿在项目截止日期上妥协,因此重新进行采购似乎不可行。

因此,唯一需要做的就是就供应商未包含的附加功能进行协商。在一番争执后,达成了一个妥协方案,最终没有一方完全满意。

项目的价格上涨,但没有达到供应商期望的程度。此外,供应商坚持要求对项目中将要实现的需求进行更正式的文档记录,这削弱了原计划中的一些灵活性。达成妥协后,项目终于可以启动。

问题

非标准文档反模式所解决的问题是如何最好地传达复杂的需求、架构、设计以及技术系统的一般期望。这涉及到如何在面对非专业受众时与技术概念进行沟通的问题。

通常,在研讨会环境中,高度视觉化且具有吸引力的材料会表现良好,比如定义新系统的愿景或如何利用像 Salesforce 这样的企业软件平台来获得战略优势。在这种情况下,你需要使用与你的受众产生共鸣的格式,建立共同理解。

然而,当沟通需要精准和技术正确时,这种方法可能会让你陷入麻烦。

提出的解决方案

非标准文档提出,最佳的文档是那些对参与编写的关键利益相关者最清晰的文档,无论它可能是什么。这是一个极具诱惑力的立场,因为在许多情况下确实如此。

例如,前述说法在以下情况下成立:

  • 如果你正在尝试就某个愿景或项目达成一致

  • 如果你正在尝试在组织内就某个话题促进相互理解

  • 如果你正在尝试提高对某个问题的普遍认识

在所有这些情况下,完美的文档是能够为受众提供良好效果的文档。然而,当涉及到技术规格、架构和设计时,这不再适用。

结果

普通语言容忍很多模糊性,绝大多数概念的视觉表示也如此。然而,模糊性是技术规格的死敌。

为了减少在编写技术规格时的模糊性,无论是需求、架构、设计,还是一般情况下,我们使用了许多工具。以下是其中的一些:

  • 使用去除日常客套话、始终追求清晰的语言。

  • 指代具有明确定义的共同理解的技术标准。

  • 指代在我们技术社区中常见的模式,并且这些模式很可能被我们交流的接收者理解。

  • 指代在我们技术社区中常见的约定或做事方式,并且这些方式很可能被我们交流的接收者理解。

  • 使用标准格式的文档,这些格式有明确的结构,能够满足我们技术社区成员的常见关注点。

  • 使用我们技术社区成员都能理解的标准格式图表。

所有这些元素有助于减少技术规格中的模糊性,尽管即使在所有这些因素的作用下,仍然存在大量误解的空间,任何有经验的架构师都会告诉你这一点。

这就是为什么有标准的方式,如用户故事或传统的需求规格说明书,用来传达需求,还有标准的图表类型,如系统景观、流程图和数据模型,用来传达技术设计。

如果偏离这些标准,你会增加总的模糊性,这会引发沟通问题,而这种问题可能会很昂贵,因为你的供应商或员工无法准确理解需要做什么。即使在要求和设计明确的情况下,沟通也已经够麻烦的了——不要再增加麻烦。

更好的解决方案。

根据上一节的描述,猜测你应该做什么可能并不难。我们列出以下几点供参考:

  • 编写你的技术规格时,要减少模糊性。最重要的是要追求清晰。

  • 在创建需要共享的技术规格时,尽可能依赖标准的图表类型、材料呈现方式、命名方式等。

  • 遵循在你的技术社区中常见的模式和约定。对于 Salesforce 专业人员来说,这通常意味着遵循 Salesforce 本身使用的方法。

通过这种方式,你可以清晰地与供应商和你雇佣的新技术人员沟通,避免可避免的模糊部分。

记住——与大多数沟通不同,在技术沟通中,你的目标是传达一个准确的观点。这是一个非常难做到的事情,事实证明如此。

对于 Salesforce,具体来说,Salesforce Architects 网站(architect.salesforce.com/diagrams)将帮助你全面了解 Salesforce 目前提供给所有架构师的资源,以避免在记录和展示 Salesforce 解决方案时重新发明轮子。对于有兴趣准备 CTA 考试的读者,这是一个值得记住的好地方。

错误管理变革

在本节中,我们讨论了错误管理变革。错误管理变革可能导致组织遭遇重大挫折,通常是由于沟通不足、培训不充分,或未能将利益相关者纳入过程。常见的陷阱包括低估变革阻力、未能明确目标和期望,以及忽视结构化变革管理计划的重要性。这些错误会导致员工困惑、士气下降,并最终阻碍组织适应能力,导致资源浪费和错失成长机会。领导者必须意识到这些挑战,并实施促进平稳过渡的策略,同时培养一种拥抱变革的文化。

忽视利益相关者的关注

忽视利益相关者的关注是一种反模式,实施团队在推进 Salesforce 开发和定制时忽视或轻视关键利益相关者的意见。虽然这种做法往往源于有效的技术考虑,但最终导致的解决方案未能满足业务需求。

示例

MedSupply 是一家成长中的医疗供应分销商,决定通过实施 Salesforce 来现代化他们的销售运营。公司原有的 CRM 系统已经显得有些陈旧,用户多年来一直抱怨其笨拙的界面和有限的功能。由高级开发人员马库斯领导的 IT 团队对构建一个现代且技术先进的系统感到兴奋。

销售团队有一个复杂的报价到订单流程,涉及多个审批和特定的合规检查。销售运营经理莎拉曾多次尝试与马库斯的团队安排会议,逐步了解他们当前的流程,并详细解释他们的需求。然而,马库斯对在 Salesforce 中复制过于复杂的传统流程有合理的担忧。从他的角度来看,许多现有的流程步骤似乎是旧系统限制的产物,而非真正的业务需求。

在最初的需求收集阶段,莎拉就某些合规检查表达了担忧,这些检查需要在报价发送给客户之前完成。她解释说,当前的流程需要交叉参考多个数据库,以确保他们不会将受限的医疗用品销售给未经授权的设施。马库斯认为,Salesforce 的验证规则和审批流程可以显著简化这些检查,消除他认为当前流程中的冗余步骤。

开发团队利用 Salesforce 的标准报价功能并结合一些定制的审批流程,创建了他们认为优雅的解决方案。他们为能够充分利用平台功能并将定制化保持在最低限度而感到自豪,因为这将使系统更容易维护和升级。当莎拉指出该解决方案没有考虑到他们需要维护所有合规检查的详细审计记录时,马库斯坚称 Salesforce 的标准历史跟踪足够用,并反对建立需要大量维护的定制审计功能。

在用户验收测试(UAT)期间,技术优雅性与业务需求之间的固有矛盾显现出来。销售代表认为新流程繁琐,因为它与他们的工作流程不匹配,尽管他们的一些抱怨源于不熟悉 Salesforce 的界面模式。合规团队发现他们无法在系统中执行所有必要的检查。莎拉在项目会议中提出了这些问题,但 IT 团队看到他们解决方案的优雅性,认为这些问题大多是“对变革的抵触”或“用户培训问题”。

系统按计划上线,尽管销售和合规团队仍有未解决的担忧。在第一周内,出现了两个重大问题。首先,由于系统强制销售代表进入一个与他们需求不匹配的工作流程,导致他们处理报价的时间翻倍。其次,更严重的是,合规团队发现一些报价在未进行完整的监管检查的情况下发送给了客户,因为系统没有强制执行所有必要的验证。

在一次险些将受限物资运送到未经授权的设施的事件后,高层管理介入。公司不得不回滚到旧系统,同时重新评估他们的方案。这个项目花费了超过 150 万美元,但并没有带来任何销售操作上的改进。

问题

忽视利益相关者的意见通常发生在实施团队在 Salesforce 项目中忽视或最小化来自关键利益相关者的有效意见时。然而,这种反模式的根源比简单的忽视更为复杂——它通常源自真正的技术考虑,以及平衡相互竞争的项目目标的挑战。

技术团队通常有充分的理由希望紧密遵循 Salesforce 的标准功能。他们明白,过度定制化的解决方案更难维护,在更新时更容易出现故障,并且从长远来看成本更高。他们常常亲眼见证过当组织通过定制将自己逼入死角,创造出实际上无法维护的系统时所出现的问题。

与此同时,利益相关者通常有合理的需求,这些需求与平台标准相抵触。这些需求可能源自法规要求、既定的业务流程或真正的效率问题。挑战在于区分那些可以通过培训和变革管理来解决的利益相关者偏好与那些真正需要技术适配的基本需求。

这种反模式特别危险,因为双方通常都认为自己在为组织做出正确的长期决策。技术团队推动标准化和可维护性,而业务利益相关者则倡导功能性和熟悉性。如果没有适当的调解,这种紧张关系往往会偏向技术考虑,原因仅仅是技术团队对实施过程有更直接的控制。

提出解决方案

这种反模式表现为一种高效的 Salesforce 实施方法,承诺通过依赖平台的标准功能和实施团队的专业知识,快速交付结果。这个解决方案看起来很有吸引力,因为它解决了关于可维护性和可持续性的非常现实的技术问题。

提出的解决方案通常强调平台最佳实践和标准功能,将利益相关者关于流程适配的关注点视为变革管理问题,而非技术需求。这种方法并非完全错误——许多传统业务流程在迁移到新平台时可以并且应该简化。然而,这种方法往往过于偏向平台纯粹性,忽视了在此过程中有效的业务需求。

这种方法看起来具有吸引力,因为它承诺显著的好处:更快的实施时间、较低的开发成本和更容易的维护。这些好处是实实在在的,但它们需要与强制将业务流程强行适应平台标准所带来的成本相权衡,尤其是在这些标准无法完全满足业务需求的情况下。

结果

当忽视利益相关者的关注时,结果通常对技术实施和业务运营都产生负面影响。用户采纳不仅仅因为对变革的抗拒,更因为系统确实未能支持关键的业务流程。一些用户抱怨可能确实反映了变革管理问题,但其他抱怨则凸显了功能上的实际缺陷,妨碍了业务运营。

技术团队关于干净、可维护实现的愿景常常证明是虚幻的。随着业务需求的不断强化,系统通常会积累一层匆忙的定制和变通,这些问题比经过良好规划的定制解决方案更加混乱。这些紧急修复往往比故意设计的定制解决方案更严重地违反了平台最佳实践。

财务影响不仅仅局限于即时项目成本。虽然定制开发很昂贵,但由于系统不合适所带来的业务中断成本往往更高。然而,同样也存在这样一种情况:过度定制的系统可能变成昂贵的维护负担,几年后可能需要完全替换。

组织影响通常会导致“技术最佳实践”和“业务需求”之间的虚假二分法,这种情况可能会对未来的项目造成毒害。技术团队变得越来越确信业务用户提出了不合理的要求,而业务用户则变得越来越确信技术团队不理解或不关心他们的需求。

更好的解决方案

避免这种反模式需要用更细致的方法替代技术卓越与业务需求之间的虚假二分法,这种方法需要认识到技术和业务的约束都是系统设计中必不可少的考虑因素。

有效的利益相关者沟通并不意味着毫无批判地接受所有利益相关者的要求,而是要创建关于业务需求和技术约束的真正对话。技术团队应解释各种方法的长期维护影响,而业务相关方应澄清哪些需求是真正的业务需求,哪些是基于当前流程的偏好。

技术方法需要在平台最佳实践和业务需求之间取得平衡。团队不应从平台功能或业务流程出发,而是应从理解核心业务目标和约束开始。解决方案应该慎重地将平台能力与业务需求相结合,在真正增加价值的地方合理使用定制开发。

需求收集不仅仅是记录当前的流程或平台功能。团队需要理解为何流程以当前形式存在,区分历史遗留问题和真正的业务需求。这种理解有助于识别出在哪些情况下流程的改变可能比技术定制更好,同时也能凸显出哪些地方确实需要定制。

实施应由业务价值和技术可持续性指导,而非平台的纯粹性或流程的保存。团队应愿意在标准功能无法满足关键需求时进行定制,但也应该在标准功能提供更简洁的解决方案时,愿意对流程变更提出挑战。

有效的治理意味着创建一个平衡的决策过程,既考虑技术问题,也考虑业务问题。这要求技术领导者理解业务影响,业务领导者理解技术影响。定期的检查点应评估技术质量和业务适配性,并在这些目标发生冲突时设有明确的升级路径。

通过遵循这些更好的解决方案,组织可以创建平衡技术卓越与业务需求的 Salesforce 实施方案。关键在于认识到技术最佳实践和业务需求都代表着必须认真平衡的实际约束,而不是相互竞争的优先事项,其中一个必须胜过另一个。

低估变更的影响

低估变更的影响是一个反模式,实施团队未能充分认识和规划 Salesforce 组织中的修改可能对整个生态系统产生的连锁效应,导致广泛的中断和技术债务。

示例

全球制造公司GMC)已将 Salesforce 作为其主要 CRM 平台使用了五年。随着时间推移,其实施系统逐步扩展,包括 Sales Cloud、Service Cloud 以及支持各种业务流程的多个自定义对象。该系统服务于超过 2000 名销售、客户服务和运营团队的用户。

Sarah,一位资深 Salesforce 管理员,收到了销售副总裁看似简单的请求。销售团队希望修改机会阶段字段,以更好地与他们演变后的销售流程对接。此更改涉及添加两个新阶段,并将现有阶段拆分为两个更细化的阶段。

请求看起来足够简单——这只是更新一个已经稳定多年的选择列表字段。Sarah 的初步评估表明,这只是一个小改动,应该能在一天之内实施。她计划在一个相对安静的时间段直接在生产环境中进行更改,认为由于范围有限,没必要进行广泛的测试或沟通。

Sarah 没有充分考虑的是机会阶段字段在 GMC 的 Salesforce 生态系统中是如何深深嵌入的。该字段驱动了许多自动化流程,包括基于阶段变化触发的多个审批工作流、财务使用的复杂预测规则、与其 ERP 系统的集成以启动订单处理、整个组织使用的几十个报告和仪表板、依赖标准机会阶段的多个第三方应用程序,以及基于阶段进展的定制佣金计算。

Sarah 在一个星期二早晨实施了变更。到星期三,问题开始浮现。财务团队发现他们的预测报告显示了不正确的数字,因为新的阶段无法映射到他们已建立的预测类别。财务副总裁非常生气,因为他们正处于季度计划的中期。

销售运营团队发现他们的佣金计算失败,因为逻辑没有考虑到新的阶段。几个销售代表担心这将如何影响他们的佣金支付。他们与 ERP 系统的集成开始抛出错误,因为它未被更新以处理新的阶段值,导致订单在处理中卡住。组织内多个仪表盘显示空白值或不正确的数据,导致大量帮助台工单的涌入。他们使用的第三方销售分析工具停止了正确同步数据,破坏了几个高管仪表盘。

最初看似简单的变更已演变成一个影响多个部门的危机。Sarah 和她的团队接下来的两周都在忙着解决这些问题,需要与财务部门紧急开会重新设计预测规则,紧急更新佣金计算逻辑,与集成团队协调修改 ERP 接口,重建多个报告和仪表盘,并向用户多次沟通问题及解决时间表。此事件促使 IT 治理进行正式审查,GMC 意识到他们需要为 Salesforce 组织建立更强大的变更管理流程。

问题

低估变更影响的反模式发生在团队未能认识到现代 Salesforce 实现之间的相互关联性时。这个反模式尤其危险,因为它通常始于看似简单且局部的变更,但却具有深远的后果。

问题表现在未能映射现代 Salesforce 组织中复杂生态系统的依赖关系,在这些组织中,看似孤立的组件往往通过自动化、集成和报告关系紧密相连。团队通常仅进行提案变更的表面级审查,错过了关键的依赖关系和下游影响。测试往往只关注直接变更的功能,而不是整个受影响的系统和流程链条。团队可能未能识别出所有受变更影响的群体,导致沟通和准备不足。

这种反模式在成熟的 Salesforce 实施中尤为常见,因为原始架构师和开发人员可能已经离开,带走了有关系统依赖关系和设计决策的关键信息。现代 Salesforce 实施的复杂性意味着即使是小的更改也可能在整个组织中产生连锁反应,影响流程、集成和报告,且这些影响可能并不立即显现。

提议的解决方案

导致这种反模式的表面解决方案是将 Salesforce 更改视为孤立的技术修改,可以迅速和直接地实施。这种方法看似有吸引力,因为它承诺能更快地交付请求的更改,减少开销和官僚主义,最小化资源需求,简化变更过程,并减少初期的规划工作。

团队通常通过指出 Salesforce 强大的平台能力和内建的保护机制来为这种方法辩解。他们可能会争辩说,由于 Salesforce 自动处理了许多依赖关系,广泛的影响分析并非必要。在那些有压力要求快速交付、更有资源约束、文档不完整、系统未经严格治理自然生长,或者团队过去曾成功进行类似更改而没有问题的组织中,这种心态尤其具有诱惑力。

这种方法的诱惑在于其表面上的高效性和它为要求更改的利益相关者提供的即时满足感。它看起来像是对业务需求的务实回应,尤其是在团队面临快速交付压力或资源有限时。

结果

当团队陷入低估变更影响的反模式时,后果可能是严重且深远的。即刻的技术问题通常表现为集成和自动化过程中的破坏性更改、数据完整性问题、性能下降、批处理作业和自动化失败以及错误的计算和工作流程。

业务影响可能是毁灭性的,涉及关键业务流程的中断、不准确的报告和预测、由错误计算引发的财务问题、多个部门的生产力丧失以及用户对系统的信任下降。这些即时问题通常会引发长期后果,包括因匆忙修复而积累的技术债务、系统文档的退化、对未来更改的抵触情绪、增加的维护成本以及系统可靠性的下降。

反模式通常会导致恶性循环,其中紧急修复引入额外的计划外更改,可能会导致进一步的问题,进而需要更多匆忙的解决方案。这可能导致每次修复都会引入新问题,系统的整体稳定性和可靠性逐渐下降。

更好的解决方案

为了避免低估变更影响的反模式,组织应当实施一个全面的变更管理方法,从根本上转变变更的评估和实施方式。关键在于将变更管理从反应式转变为主动式。

强大的影响分析流程构成了更好实践的基础。组织需要保持详细的系统文档和依赖关系图,尽可能使用自动化工具识别字段和对象依赖关系。定期的系统审计有助于了解集成点,而全面的测试清单确保在变更实施过程中没有遗漏任何部分。

变更过程本身需要精心结构化。这意味着对于重大修改要实施正式的变更咨询委员会,确立明确的标准来区分重大和次要变更,并要求在批准变更前进行文档化的影响评估。标准化的变更请求模板应当促使考虑依赖关系和潜在的系统影响。

测试策略在避免这种反模式中尤为关键。组织需要维护多个沙箱环境以用于不同的测试目的,并在可能的情况下实施自动化回归测试。对所有受影响的过程进行端到端测试,包括集成测试,应成为任何重大更改的标准程序。

利益相关者管理在成功的变更实施中扮演着至关重要的角色。组织应当清楚了解哪些小组受不同系统组件的影响,并建立清晰的沟通协议来处理系统变更。用户反馈渠道以及可见的变更日历有助于保持透明度和信任。

风险缓解策略需要在变更过程中内建。这包括为所有重大更改制定回滚计划,尽可能分阶段实施更改,在适当的业务窗口期安排更改,并保持对关键问题的应急响应程序。

知识管理在防止这种反模式中变得至关重要。组织需要记录所有系统依赖关系和集成点,保持更新的流程图和系统架构图,并创建一个包含以前更改及其影响的知识库。定期对团队成员进行系统架构和依赖关系的培训,有助于保持对系统复杂性的认知。

需要记住的关键原则是,适当规划和影响分析的成本几乎总是低于从糟糕的变更中恢复的成本。在 Salesforce 生态系统中,变更可能会产生广泛的影响,因此必须保持对系统复杂性及即使是看似微小的修改也可能产生的影响的高度敬畏。避免这种反模式的成功并非来自避免变更,而是来自以适当的谨慎态度和对其潜在影响的尊重来处理变更。

现在,已经讨论了本章的模式,让我们继续讨论关键的要点。

了解关键要点

在这一部分,我们将从具体的模式中进行抽象,转而尝试提取你作为 Salesforce 架构师或在准备 CTA 评审委员会时可以在日常工作中使用的更广泛的学习要点。

在架构 Salesforce 解决方案时,你应该注意以下几点:

  • 在向业务利益相关者呈现你的架构时,不要包含过多的信息。

  • 相反,专注于你的主要信息,并仅包含必要的支持性信息。

  • 不要因为没有包含你在提出解决方案时考虑的所有额外因素而感到不好。如果有人需要更多的细节,他们可以在事后询问。

  • 不要将决定推迟到做决定已经没有意义的时刻,即使做出决定很困难。

  • 如果某个决定具有争议或政治敏感性,推迟到正式的决策流程可以提供前进的途径。

  • 如果你遇到让你的听众似乎无法理解你的情况,你应该开始怀疑是否存在一些潜在的抗拒来源。

  • 在这种情况下,你很可能需要专注于该情况的变更管理方面,才能取得真正的进展。

  • 当需要为技术受众准备文档时,无论是外部受众还是你的内部技术团队,你应该严格遵循你所在技术社区内的公认实践。

  • 对于 Salesforce 专业人士而言,这通常意味着采用 Salesforce 本身传播的最佳实践。

在准备 CTA 评审委员会时,你应该注意以下几点:

  • 在呈现你的解决方案时,要简洁明了。评审官是经验丰富的架构师,因此你可以依赖大量的背景知识。

  • 包括你推荐方案的明确理由,但不要过多纠结于备选方案。

  • 不要包含不必要的额外考虑,专注于你的主要观点。如果有人想要验证你的思路,他们会在问答环节中提出来。

  • 模棱两可对任何人都没有好处。不要呈现不清晰或没有做出重要架构决策的解决方案。

  • 法官们在发现你表达不清楚的地方方面非常有经验,因此,如果你不确定正确的决定是什么,你也应该做出一个决定。

  • 如果评委多次提出相同或几乎相同的问题,他们很可能在暗示你的解决方案中存在某个弱点,你可能需要立即重新考虑。

  • 使用之前成功的 CTA 候选人所采用的标准图表和展示格式。

  • 在模拟考试中反复以相同的方式做事,以培养熟练度和速度。

我们现在已经涵盖了本章的内容,可以继续前进。然而,在此之前,我们将总结一下我们的学习。

总结

在本章中,我们看到沟通如何严重影响我们项目的结果。你可以拥有世界上最好的架构,但如果你未能正确传达它,或者未能处理它在目标受众中引发的阻力,它仍然可能无法取得任何进展。

这对一些更理性派的架构师来说可能是令人沮丧的。事实和实质应该是决定因素才对。但不幸的是,在大多数组织中,更好的沟通技巧往往比更强的技术架构技能在完成任务上更有优势。

好消息是,沟通技巧和所有技能一样,都是可以学习的。作为架构师,想要取得更大的成功,沟通方式并没有特别困难的地方——只是需要一些练习。

我们现在已经涵盖了本书的所有内容,可以进入结论部分,在这里我们将总结我们一起走过的旅程,并展望接下来的方向。

第九章:结论

本结论提供了本书内容的概述,包括前几章的核心收获。接着,解释了如何在自己的工作中使用反模式方法和视角,以提高架构技能。最后,它还提供了如何在这一方向上进一步发展的指引。

本章我们将讨论以下几个主要内容:

  • 本书的关键内容——特别是我们将讨论一些反模式的根本原因

  • 如何在自己的建筑实践中使用反模式来提高你创建的架构质量

  • 如何进一步理解反模式并发展你自己的架构技能

完成本章后,你将能够较好地理解如何进一步发展自己的架构能力,并知道如何将基于反模式的思维整合到你作为架构师的日常实践中。

总结关键内容

本书涵盖了七个不同架构领域的几十种反模式。然而,细心的读者会发现,许多问题及其建议的解决方案在多个看似不同的领域中是相似的。

这表明,从更深层次看,反模式有着相似的根本原因,通常源于更大的组织因素甚至心理因素。我们来看看这些重复出现的原因:

  • 一厢情愿的想法:一些反模式基于某种形式的一厢情愿的想法——也就是说,不愿面对眼前的技术现实。在“Project Pieism”中,它表现为无法面对取舍和不确定性;在“Golden Hammer”中,是过度乐观地相信单一工具;在“Unplanned Growth”中,是认为可以在以后找到解决方案。这也扩展到了新模式,比如AI 架构与常规架构相同,其中团队未能意识到 AI 所面临的独特挑战。在技术架构中,始终要警惕过度乐观的情绪。

  • 系统性盲点:许多反模式源于无法看到整个系统,专注于局部解决方案而忽视整体架构。这包括反模式,如孤立的实体忽视生态系统用包创建孤岛事件地狱。现代 Salesforce 实现的复杂性日益增加,特别是在 AI 集成和 DevOps 实践的背景下,使得这一问题变得更加重要。忽视你所处的整体社会技术系统,肯定会导致反模式的出现。

  • 用实际问题替代简单问题:许多反模式源于希望简化问题。许多架构问题是棘手的,只能提供不完美且高度复杂的解决方案。通常,这对于那些寻求简单易懂答案的利益相关者来说并不完全令人满意,而这种需求的满足往往会导致反模式。例如,安全领域中的合规即安全声明式即安全,就是我们用简单的答案替代复杂现实的两个例子。这也扩展到新的模式,如让我们加点 AI,将复杂的 AI 实施挑战过度简化。

  • 组织约束:另一个常见的反模式根本原因是受到当前组织结构的约束。无论是因为组织内部的孤岛、与供应商的糟糕关系,还是政治游戏,你所处的组织环境有时会导致甚至迫使你走上反模式的道路。这在新的模式中尤为明显,比如忽视利益相关者关切低估变更的影响

  • 技术治理薄弱:缺乏有效的技术治理是另一个常见的反模式原因。当你没有任何架构权威、明确的标准或规范时,通常会出现漂移,从而产生反模式。这包括许多模式,如强耦合系统扩散不受约束的数据同步。DevOps 实践和 AI 能力的日益普及使得强有力的治理变得更加重要。

  • 缺乏纪律性:最终,一些反模式归结为软件开发生命周期中缺乏纪律性。这包括泥球意大利面共享模型臃肿接口虚拟单元测试等模式。新的模式,如不频繁提交代码,也属于这一类。这些在某种程度上是最容易解决的,因为解决方案显而易见,但推动团队走捷径的潜在压力往往更难应对。

解释如何在实践中使用反模式

如果你已经通读了本书,你会遇到大量关于 Salesforce 项目可能出错的模式。我们按架构领域进行结构化,以帮助你理解并提供更多的背景信息。

然而,你可能仍然对如何在日常工作中应用这份新知识库存在一些疑问。我们建议你可以通过两种主要方式,主动利用反模式知识来提升你的架构实践并磨练你的架构技能:

  1. 首先,你可以将其作为架构和设计过程的一部分,建设性地使用。

  2. 其次,你可以将它作为诊断工具的一部分,用来理解其他人设计的架构

建设性地使用反模式

建设性地使用反模式意味着你将基于反模式的思维纳入到你的正常架构过程当中。你可以通过几种方式做到这一点,从简单地拥有一个常见反模式的心理检查清单,来验证你的工作是否符合要求,到系统地检查所有适用于当前架构过程阶段的反模式。

我们建议在这两种极端之间选择一个折衷方案,你可以采取以下步骤:

  1. 在架构过程的开始,基于上一节中提到的六个因素进行评估。对于每个因素,按照标准的 1-5 评分标准评估你的环境,看看它可能对你的工作产生多大影响。

  2. 对于你在评估中评分为 4 或 5 的所有因素,列出在你的环境中可能发生的各种反模式。特别关注与 AI 集成、DevOps 实践和变更管理相关的新挑战。

  3. 对于你选择的那些反模式,在初步设计时以及项目的整个过程中定期进行检查,看看它们是否开始出现。

  4. 如果你开始看到某个反模式的倾向,按照模式描述中更好的解决方案部分的指示,采取主动措施。

诊断性地使用反模式

当你作为架构师进入一个现有环境时,基于反模式进行分析以诊断现有架构的健康状况是一个非常有成效的努力,我们强烈推荐这样做。这个分析不仅有助于你理解当前环境的优缺点,还可以指示出你可能开始重构它的方式。

我们建议你执行以下操作:

  1. 收集来自现有用户和熟悉现有环境的团队成员的信息,特别是那些可能表明存在反模式的非功能性特征。

  2. 根据你收集的信息,列出可能出现在该架构中的潜在反模式,包括与 AI、DevOps 和变更管理相关的新模式。

  3. 对相关技术文档进行彻底检查,确认或驳斥每个反模式的存在。

  4. 根据你的发现,开始考虑潜在的缓解措施,并评估你被带入的工作对环境的影响。

更进一步使用反模式

虽然这本书提供了大量信息,但显然你的架构学习之旅并不会止步于此。我们建议你考虑以下三条前进路径:

  • 更深入地研究反模式文献

  • 扩展你对 Salesforce 架构的知识

  • 扩展你的一般架构知识

对于这些领域,我们已经精选了一系列有用的资源,并将在接下来的章节中进行讲解。

深入反模式文献

有三个资源,我们特别推荐它们来深入理解反模式的概念:

  • 原版书籍是反模式:重构软件、架构和危机中的项目,作者为 Raphael C. Malveau、William J. Brown、Hays W. “Skip” McCormick 和 Thomas J. Mowbray。尽管这本书已经非常过时,但它在正式化和普及反模式概念方面起到了极为重要的作用。书中介绍的多个反模式可以追溯到这本书。

  • 对反模式的整体讨论,无论是通用反模式还是具体反模式,都可以在 WikiWikiWeb 上找到,网址是wiki.c2.com/?Anti-patter

  • DevIQ 拥有一个极好的反模式资源库,讨论了许多在多个平台上常见的反模式,可以在deviq.com/anti-patterns/anti-patterns-overview找到。

接下来,我们将探讨如何将对反模式的知识与对 Salesforce 架构的深入理解结合起来,以取得更好的成果。

扩展你的 Salesforce 架构知识

运用你新获得的 Salesforce 反模式知识的最佳方式之一是将其与对关键 Salesforce 架构领域的深入了解结合起来。我们推荐以下几本书:

  • 首先,我们推荐 Tameem Bahri 的成为 Salesforce 认证技术架构师,适合那些正在准备 CTA 认证或未来有意向的读者。像这本书一样,它按照 CTA 架构领域进行结构化,因此具有很高的互补性。

  • 另一本非常好的 Salesforce 架构书籍是 Mike King 的Salesforce B2C 解决方案架构师手册

  • 对于那些特别关注数据领域的人,我们强烈推荐 Ahsan Zafar 的Salesforce 数据架构与管理

然而,Salesforce 架构只是需要考虑的一个方面。你还应该考虑扩展你的通用架构知识。

扩展你的通用架构知识

尽管反模式很重要,我们也应该努力提升我们对架构的整体理解。以下是一些可以帮助做到这一点的资源:

  • 首先,我们推荐 Saurabh Shrivastava 和 Neelanjali Srivastav 的解决方案架构师手册,这本书很好地介绍了许多通用架构主题。

  • 对于 CRM 及其架构的通用介绍,我们推荐 Max Fatouretchi 的CRM 的艺术

  • 最后,我们推荐 Jeroen Mulder 的多云架构与治理,以获得对日益普及的多云架构场景的良好概述。

我们已经覆盖了本章内容和书籍的要点,接下来将以最终总结结束。

总结

做得好,你成功了!这是本书的最后一章,现在你已经成为一名正式的反模式爱好者。

在这一章中,我们总结了本书的主要内容。特别是,我们分析了六个普遍存在于许多反模式中的根本因素,它们是这些反模式的根源。这些因素为架构师提供了指示标志,帮助他们在特定的架构环境中识别出可能出现的反模式,并了解可以采取哪些措施来缓解这些问题。

为了将这些知识应用于实践中,我们概述了两种将反模式融入架构流程的方法。首先,我们探讨了如何在自己的架构中建设性地运用反模式,其次是如何在检查现有架构时以诊断的方式使用它。

最后,我们探讨了你接下来可能的学习方向,以进一步扩展你的知识。我们概述了你可以采取的三条路径,并给出了一些书籍和其他资源的建议。

反模式是通用架构中最有趣的领域之一,因为它们告诉你事物是如何以可重复的方式出错的。从他人的错误中学习通常比自己犯所有错误要好,我真诚地希望阅读本书能让你更不容易重复这些反模式,并且能在你的环境中识别出他人即将犯的错误。

软件系统至关重要。组织依赖于它们。用户在工作中花费大量时间与它们互动。作为架构师,我们有责任帮助避免那些导致系统无法发挥最佳效能的常见错误。随着人工智能、DevOps 实践的普及以及架构解决方案中对有效变更管理的需求,这一责任变得愈加重要。

通过短时倒谱(Cepstrogram)计算进行时-倒频分析研究(Matlab代码实现)内容概要:本文主要介绍了一项关于短时倒谱(Cepstrogram)计算在时-倒频分析中的研究,并提供了相应的Matlab代码实现。通过短时倒谱分析方法,能够有效提取信号在时间与倒频率域的特征,适用于语音、机械振动、生物医学等领域的信号处理与故障诊断。文中阐述了倒谱分析的基本原理、短时倒谱的计算流程及其在实际工程中的应用价值,展示了如何利用Matlab进行时-倒频图的可视化与分析,帮助研究人员深入理解非平稳信号的周期性成分与谐波结构。; 适合人群:具备一定信号处理基础,熟悉Matlab编程,从事电子信息、机械工程、生物医学或通信等相关领域科研工作的研究生、工程师及科研人员。; 使用场景及目标:①掌握倒谱分析与短时倒谱的基本理论及其与傅里叶变换的关系;②学习如何用Matlab实现Cepstrogram并应用于实际信号的周期性特征提取与故障诊断;③为语音识别、机械设备状态监测、振动信号分析等研究提供技术支持与方法参考; 阅读建议:建议读者结合提供的Matlab代码进行实践操作,先理解倒谱的基本概念再逐步实现短时倒谱分析,注意参数设置如窗长、重叠率等对结果的影响,同时可将该方法与其他时频分析方法(如STFT、小波变换)进行对比,以提升对信号特征的理解能力。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值