---
schema_version: "1"
id: c5afb8ddc25802f7737d41a424025b3423de21a7adee6ef241320822362bf443
title: 可撰写
collection: architect
version: next
locale: zh-cn
portal_url: https://docs.salesforce.com/architect/next/zh-cn/well-architected/guides/composable.md
canonical_url: https://staging.architect.salesforce.com/docs/architect/zh-cn/well-architected/guide/composable.html
source_site: staging.architect.salesforce.com
content_type: documentation
content_hash: 8bfc5293423191ddcf2b938a613c3ffc00e10e7380f6dcb08f0e6386cbc501ea
products:
  - 精心设计
  - Architect Site Content Repo
updated_at: 2024-07-01T00:00:00Z
---
> 在[这里](/docs/architect/zh-cn/well-architected/guide/contributors)阅读我们的更新计划。

## 导言

可组合解决方案调整快速，稳定性更高。设计为可组合的系统构建在有意义的单元或构建块中，它们可以彼此优雅地操作，并且可以轻松地进出服务。通过将可组合性构建到系统中，您可以通过重构或重组系统的单个单元来引入新功能或消除技术债务。可组合性支持更快、更可预测的交付周期和发布，因为团队可以通过更少的更改专注于构建和交付有意义的功能。

可组合系统使企业能够更快、更稳定地适应 — 无论刺激因素是企业内部因素还是外部因素造成的。可组合性帮助系统更具[弹性](/docs/architect/zh-cn/well-architected/guide/resilient)，并帮助解决方案和架构模式更具[针对性](/docs/architect/zh-cn/well-architected/guide/intentional)。

您可以通过建立三个关键习惯来使您的 Salesforce 解决方案更具可组合性：关注点分离、互操作性和可封装性。下面，您可以通过两种方式看到这些习惯的关系：对于可组合系统中的单个单元，以及可组合系统中的多个单元。

<b>单个可组合单元：</b>

<a href="https://a.sfdcstatic.com/developer-website/prod/images/architect/composable-capabilities.jpeg" target="_blank">
    <img style="border:1px solid #e5e5e5;margin:2rem 0rem;width:50%;" src="https://a.sfdcstatic.com/developer-website/prod/images/architect/composable-capabilities.jpeg" alt="此图显示了可撰写主题如何通过 3 个嵌套卡片相互关联。最里面的卡片是功能单元，下一层是互操作性，外层是可打包性。">
</a>

<b>可组合系统：</b>

<a href="https://a.sfdcstatic.com/developer-website/prod/images/architect/composable-multi-package-capabilities.jpeg" target="_blank">
    <img style="border:1px solid #e5e5e5;margin:2rem 0rem" src="https://a.sfdcstatic.com/developer-website/prod/images/architect/composable-multi-package-capabilities.jpeg" alt="此图显示了可撰写主题如何通过 3 个嵌套卡片相互关联。最里面的卡片是功能单元，下一层是互操作性，外层是可打包性。">
</a>

## 分离问题

*关注点分离*是软件工程和系统架构中的一个基本概念,它要求在一个更大的系统中识别各种关注点,这些关注点可以分为模块单元。要在系统中实现问题的强烈分离，需要为整个系统的应用程序逻辑和功能创建有意义的单元。更小的单元使应用程序交付和维护团队更容易理解如何以及在哪里进行更改，而对更大的系统的中断最少。更小的单元还使得解决[技术债务](/docs/architect/zh-cn/well-architected/guide/intentional#技术债务)时如何以及在哪里集中工作变得更加清晰，并有助于提高系统的整体[可读性](/docs/architect/zh-cn/well-architected/guide/intentional#可读性)。

通过面向业务能力和管理状态，您可以将问题更好地分离到您的 Salesforce 组织中。

### 功能单元

对于 Salesforce 系统，分离问题的最佳方式是应用面向业务的视角来识别和组织系统中的模块化单元（或功能）。这与专注于工程的视图不同，后者根据单位的技术功能来识别单位。分离问题的面向业务的视角需要根据代码和自定义为业务和业务用户提供的服务来组织系统中的代码和自定义。采取这种方法并不意味着忽略系统中冗余或重复技术功能的可能性。相反，这意味着技术服务被清楚地映射到最终对业务透明的组织原则。

面向业务功能有助于确保业务分析和发现团队与交付团队之间的交接尽可能简单。如果应用程序构建者不知道他们的工作单位映射到您的可组合架构中的位置，您会看到一团糟，而不是可组合的应用程序环境。业务所需的最终状态与组织中模块化单元之间的映射不明确，也会增加开发团队或供应商在系统中构建冗余功能的可能性。

请考虑以下事项，以将职能单位定向到业务能力：

- **从要完成的工作开始**。关注用户和业务本身要完成的工作 (JTBD)。JTBD 方法由 Tony Ulwick 倡导，它侧重于理解人们试图通过使用产品或服务实现的“工作”或真正目的。它比用户的角色相关任务或业务流程中的单个步骤更抽象。例如，重复检查和地址验证等任务可能属于“建立客户的单一视图”的更高级别功能。在您清楚了解这些更高级别的业务功能后，您可以开始将系统的一部分映射到它们。
- **面向功能，而不是报告结构**业务部门的内部层次结构不是有意义的功能或要完成的工作的代理。业务的内部层次结构的确对流程和团队结构有重大影响（更不用说预算了）。这些都是重要的后勤考虑。但业务的功能需求在比物流更高的抽象级别上运作。如果您正在创建模块来为报表结构提供服务，而不是为更高级别的功能提供服务，请注意，您可能必须采取额外的步骤来确定该模块与业务功能的关系。
- **迭代**。从与企业合作开始，确定哪些功能可用于最低可行产品 (MVP)。在您确定功能时，开始构建该 MVP。在构建时，确定对您正在创建的功能单元至关重要的流程、元数据和[事件或消息](/docs/architect/zh-cn/well-architected/guide/composable#消息传递和事件)。识别任何具有外部依赖性的进程、元数据和事件或消息。随着更多功能单元的设计,实施 [API 管理](/docs/architect/zh-cn/well-architected/guide/composable#api-管理)和[依赖性管理](/docs/architect/zh-cn/well-architected/guide/composable#依赖性管理)来构建彼此良好协作的单元(而不是构建孤立的单元 ) 。

以下[模式和反模式](/docs/architect/zh-cn/well-architected/guide/composable#关注模式和反模式分离)列表显示了 Salesforce 解决方案中业务功能的正确(和不佳)方向。您可以在构建之前使用这些来验证您的设计，或者确定您的系统需要重构的区域。

要了解有关 Salesforce 可用工具的更多信息，以帮助您更好地定位业务功能，请参阅[相关工具](/docs/architect/zh-cn/well-architected/guide/composable#与可撰写相关的工具)。

### 状态管理

状态管理以整个系统中不同时间点的信息移动为中心。有效的状态管理使应用程序能够以最少的计划外或不确定的结果处理复杂的数据流或交互。在模块化 Salesforce 组织中管理状态意味着为单位内部和单位之间的逻辑流构建清晰的路径，以及为计划外的执行行为构建优雅的路径。通过状态管理，可以从模块化 Salesforce 应用程序单元形成一致的逻辑流。在大多数情况下,这需要[互操作性](/docs/architect/zh-cn/well-architected/guide/composable#交互性)来构建单位之间的信息流。

松耦合单元之间管理状态的困难通常会导致 Salesforce 中的单片应用程序开发。您可以在大型“单层流”中看到这一点，这些“单层流”是为了在单个流中编排复杂的流程而构建的。另一个例子是大型 Apex 类 , 它们通过*意大利面代码* , 或一长串一次性方法来编排复杂的过程。这些类型的应用程序架构使重构和调试变得困难，并增加了新团队成员或供应商的入职时间。它们还降低了交付给企业的应用程序的价值，因为功能不可重复使用。

考虑以下事项，以在模块化 Salesforce 组织中管理状态：

- **决定何时使用有状态与无状态模式。**有状态模式会保留整个执行路径中的信息，而无状态模式不会。在松耦合的系统中，无状态模式使得组件的重构更快，副作用更少。然而，无国籍模式并非适用于所有用例。如果您正在为数据操作构建组件，状态模式有助于整个系统的数据完整性和一致性。如果您的组件满足以下任何条件，请使用有状态模式：
  - 了解放置在更大的执行路径中对于组件的行为至关重要
  - 组件的行为需要根据下游操作的结果进行更改（例如，需要根据下游组件的回滚/错误/成功消息更改执行）
  - 组件需要等待来自外部或下游系统的响应才能完成工作
- **为状态信息创建有意义的类别。**_State_ 是一个模糊的术语，可以应用于 Salesforce 组织内部(及外部)如此广泛而深入的信息，以至于该术语本身几乎没有意义。因此,构建有状态模式的必要第一步是为系统中最重要的有状态执行路径(或各种有状态行为)创建有*意义*的类别。需要考虑的一些类别：
  - 导航和表单
  - 数据库操作
  - 批处理和批量操作
  - 错误
- **从数 [据库事务](/docs/architect/zh-cn/fundamentals/guide/architecture-basics#数据库操作)的角度定义数据相关的状态**。平台的内置行为将限制 Salesforce 中数据的大多数状态注意事项。请勿尝试针对或规避此行为。为它设计并使用它。设计最小化或消除分布式事务逻辑的解决方案。（有关更多详细信息，请参阅[数据处理](/docs/architect/zh-cn/well-architected/guide/automated#数据处理)）。
- **识别功能单元内部(和之间)发生的状态。**当您将功能单元组装成更大的系统时，请注意您何时混合了无状态和有状态的组件行为，并防止可能在处理中产生无限循环或间隙的组合。
- **定义切换**。请考虑组件将使用什么[消息传递或事件](/docs/architect/zh-cn/well-architected/guide/composable#消息传递和事件)模式将状态相关数据传输到系统的另一个部分。确保您正在将事务意识和[处理](/docs/architect/zh-cn/well-architected/guide/automated#数据处理)构建到组件中。请勿在切换中包含任何分布式事务逻辑。
- **创建进程图和状态之间的映射。**进程图详细说明了在不同时间点通过系统移动信息的步骤。状态图显示了信息（状态）的实际变化。使用 [Salesforce 图表](/docs/architect/zh-cn/reference-diagrams/guide/kit-of-parts)形状的元数据页脚部分来捕获流程中每个步骤中不断变化的信息状态。如果您分开进程图和状态图，请确保将它们链接起来。不应将这一概念与在设计和实施期间捕获流程或系统总体状况的当前和未来状态混淆，因为这与在系统中移动的信息无关。

下面的[模式和反模式](/docs/architect/zh-cn/well-architected/guide/composable#关注模式和反模式分离)列表显示了 Salesforce 解决方案中正确(和糟糕)的状态管理。您可以在构建之前使用这些来验证您的设计，或者确定系统中需要重构的地方。

要了解有关用于管理状态的 Salesforce 工具的更多信息，请参见[工具相关可撰写](/docs/architect/zh-cn/well-architected/guide/composable#与可撰写相关的工具)。

### 关注模式和反模式分离

下表显示了在您的组织中要查找（或构建）的模式的选择，以及要避免或针对补救的反模式。

✨ 在[模式和反模式探索](/docs/architect/zh-cn/well-architected-tools/guide/adaptable-separation-of-concerns)器中，发现更多关注分离的模式。

<table>
    <colgroup>
       <col span="1" style="width: 10%;">
       <col span="1" style="width: 45%;">
       <col span="1" style="width: 45%;">
    </colgroup>
    <tbody>
        <tr>
            <th scope="colgroup"></th>
            <th scope="colgroup">模式</th>
            <th scope="colgroup">反模式</th>
        </tr>
        <tr>
            <td rowspan="3"><b>功能单元</b></td>
            <td><b>在设计标准中：</b>
                <br> - 命名约定解决了如何表示功能单元的问题
                <br> - 存在所有当前定义的功能单元（和相关命名约定）的列表
                <br> - 存在提议增加或更改职能单位的标准</td>
            <td><b>在设计标准中：</b>
                <br> - 设计标准不存在或未涉及功能单元和用例
            </td>
        </tr>
        <tr>
            <td><b>在您的文档中：</b>
                <br> - 系统横向图清楚显示组织中的功能单元
                <br> - 所有文档和实施图表都清楚地显示了组件的功能单元
                <br> - 单个组件的文档包含组件的功能单元映射
                <br> - 功能单元中的所有组件均可搜索并易于查找
            </td>
            <td><b>在您的文档中：</b>
                <br> - 组件文档不存在
                <br> - 组件文档描述了组件所属的功能单元，但这是该功能单元定义出现的唯一位置
                <br> - 您无法搜索特定功能单元和/或搜索无助于识别功能单元中的所有组件
            </td>
        </tr>
        <tr>
            <td><b>在您的组织中：</b>
                <br> - 可以快速识别指定元数据的功能单元对齐方式（例如，流、Apex 类或 Lightning 页面）
                <br> - 职能单位使用业务友好术语进行标记
            </td>
            <td><b>在您的组织中：</b>
                <br> - 无法识别任何元数据的功能单元对齐
                <br> - 职能单位信息不一致或不准确
                <br> - 功能单元信息使用对业务用户毫无意义的工程术语进行标记
            </td>
        </tr>
         <tr>
            <td rowspan="4"><b>状态管理</b></td>
            <td><b>在设计标准中：</b>
                <br> - 有状态设计与无状态设计的用例很清楚
                <br> - 存在批准的无国籍通信模式
                <br> - 存在状态通信的批准模式
                <br> - 州/省的清除类别已存在
            </td>
            <td><b>在设计标准中：</b>
                <br> - 设计标准不存在或未处理状态/无国籍模式和用例
            </td>
        </tr>
        <tr>
            <td><b>在您的文档中：</b>
                <br> - 每个处理有状态和/或无状态通信的组件都指示已实施什么模式
                <br> - 可以搜索和查找实施特定有状态/无状态模式的所有组件
                <br> - 进程和交互图表提供有关状态类别和切换的详细信息
            </td>
            <td><b>在您的文档中：</b>
                <br> - 组件文档不存在
                <br> - 组件文档描述了实施的有状态/无状态模式，但这是定义出现的唯一位置
                <br> - 无法搜索特定模式和/或搜索无助于识别使用该模式的所有组件
            </td>
        </tr>
        <tr>
            <td><b>在 Apex 中：</b><br> - 保存点和回滚行为用于所有数据操作</td>
            <td><b>在 Apex 中：</b><br> - 不使用保存点和回滚行为</td>
        </tr>
        <tr>
            <td><b>在流中：</b><br> - 错误路径和使用回滚记录元素</td>
            <td><b>在流中：</b><br> - 未使用回滚记录元素</td>
        </tr>
    </tbody>
</table>

## 交互性

在为互操作性设计的系统中，组件可以交换信息并有效地一起工作。交互性是使模块化系统可组合而不是孤立的关键。在[松散耦合](/docs/architect/zh-cn/well-architected/guide/composable#松耦合)的系统中，交互性可能很难实现。您需要为一致的集成方法建立标准，这些集成方法不会破坏单位之间的独立性和整个系统整体[的关注分离](/docs/architect/zh-cn/well-architected/guide/composable#分离问题)。

交互性也会影响用户体验的质量。您的用户希望在一个区域中创建的数据（例如订单信息）在另一个区域中可用（例如市场营销市场活动），您的构建者希望，如果他们学习如何做某事（例如构建流或验证 API），他们会在继续下一个问题时发现熟悉的技术有效。如果不能设计互操作性，将导致冗余的架构、重复的数据、流程效率低下，并增加开发和支持成本。

您可以通过消息传递和事件以及 API 管理在模块化系统中创建互操作性。

### 消息传递和事件

消息和事件是启用整个系统组件发送和接收信息的两种方式。在它们可以携带的内容方面，事件和消息是相似的。一个关键区别是发件人的行为。发送*消息*的组件通常会将数据发送到特定目的地，并等待收件人的某种响应。相比之下，组件会在事情发生时发出*事件*。没有具体的目的地，也没有响应的预期。这些行为差异支持不同的通信模式。消息支持有状态的通信模式，事件支持无状态的通信模式。（有关此区别的更多信息，请参见[状态管理](/docs/architect/zh-cn/well-architected/guide/composable#状态管理)。）

在消息传递和事件的协议和用例上协调团队非常重要。不明确的标准会导致整个系统的模式混合，从而导致：

- 错误模式应用于特定用例时的性能和可扩展性问题
- 处理不一致，使系统对最终用户不稳定
- 更长的故障排除时间和更复杂的维护流程

在设计消息和事件以在 Salesforce 组织中创建更松散耦合的结构时，请考虑以下事项：

- **识别同步和异步用例**。事件允许在系统中进行松耦合、无状态和异步通信。消息传递允许更紧密的控制、有状态和同步的通信模式。在决定何时使用消息或事件时，您需要决定通信是否需要同步（并可能阻止）还是异步和非阻止。
- **仔细定义数据结构**。组件在它们之间传递的信息结构是保持松散耦合的系统易于管理和一致的重要部分。（有关更多信息，请查看 [API 管理](/docs/architect/zh-cn/well-architected/guide/composable#api-管理)。）设计消息或事件时的一个关键注意事项是信息的结构可能需要更改的频率。一旦消息或事件结构在您的系统中定义和实施，就很难处理更新，特别是如果事件或消息已经被用来向外部系统发送信息。
- **正确大小的消息**。通常，最佳实践是保持消息大小较小。但是，在消息*大小*和消息*量*之间也有平衡作用。系统可以更快地处理更少的数据。处理行为会产生大量额外开销，因为收件人必须解压缩、解释并确定如何处理他们收到的信息。这些步骤可能需要很少的时间来完成，但它们会大规模地累积起来并给系统造成负担。避免设计需要系统中的组件连续处理许多小消息来完成一件工作。要正确调整消息的大小，请考虑为下游组件设计最少的数据，以便成功处理它们发送的信息并采取行动，同时不要假设每个下游组件都能够请求或处理大量的后续消息。
- **设计可扩展性**。松散耦合的组件可以更容易地扩展您的架构。消除跨组件依赖性使团队能够致力于提高任何单个组件的性能或可扩展性，而对其他组件的影响最小。然而,松散耦合的组件也会大规模引入架构的复杂性(特别是在[管理状态](/docs/architect/zh-cn/well-architected/guide/composable#状态管理)方面 ) 。确定出于有效用户体验或数据完整性原因需要更紧密耦合逻辑或依赖性的进程，不要尝试在这些进程中引入基于异步/事件的模式。使用基于同步/消息的模式和适当的错误处理。

以下[模式和反模式](/docs/architect/zh-cn/well-architected/guide/composable#交互模式和反模式)列表显示了 Salesforce 解决方案中正确(和差)的消息传递和事件的外观。您可以在构建之前使用这些来验证您的设计，或者确定系统中需要重构的地方。

要了解有关 Salesforce 消息传递和事件工具的更多信息，请参阅[工具相关可撰写](/docs/architect/zh-cn/well-architected/guide/composable#与可撰写相关的工具)。有关为给定用例选择事件模式或工具的更多信息，请参见[架构师指南](/docs/architect/zh-cn/decision-guides/guide/event-driven#key-takeaways)。

### API 管理

在 Salesforce 解决方案中构建适当的应用程序编程接口 (API) 管理可使系统的单个组件遵循可预测的通信模式。Salesforce 提供用于与 Salesforce 外部系统通信的内置安全 API。（有关 Salesforce 平台 API 的更多信息，请查看[架构基本知识](/docs/architect/zh-cn/fundamentals/guide/architecture-basics#平台-api)。）

Salesforce 解决方案中有效的 API 管理是构建真正可组合架构的关键。它使 Salesforce 组织中的组件能够有效地发送和接收信息。它还使解决方案生成器能够遵循明确的协议，了解他们构建的组件如何与系统中的其他组件通信，并帮助他们尽早发现糟糕的实施。此外，它使解决方案构建者能够更专注于他们正在构建或重构的特定组件，从而提高生产率和质量。

企业级的 API 管理是一个单独的主题，最好使用全面的 API 管理工具来实现。(有关此主题的 MuleSoft 视角的更多信息，请查看[什么是 API 管理](https://www.mulesoft.com/resources/api/what-is-api-management#:~:text=API%20management%20is%20the%20process,create%20are%20consumable%20and%20secure.)。)

在 Salesforce 解决方案中构建 API 管理功能时，请考虑以下事项：

- **将 API 视为通信的可*预测*模式或合同。**输入或输出变量的数据类型、变量名称、应该（或不应该）以给定模式显示的信息 — 这些是有效 API 管理的关键。这些定义应该出现在您的设计标准中，团队应该能够通过您的文档找出这些定义是如何在系统的特定部分实施的。查看将更改从新开发合并到集成环境的困难的一种方式是将它们视为您实施 API 通信不力的证据（或者可能根本没有 API 定义）。
- **请勿将 API 思维限制为仅编码。**在此上下文中定义 API 的是该消息中消息结构和变量的一致性。只要保持一致性，API 就可以在代码以及声明性自定义中实施，例如模块化自动启动（或平台事件触发）流，甚至是流模板。您在代码中与流中定义什么的决策不是基于 API 实施，而是基于可[封装性](/docs/architect/zh-cn/well-architected/guide/composable#可打包性)和可[测试性](/docs/architect/zh-cn/well-architected/guide/resilient#应用程序生命周期管理)。

- **保持生命周期和版本简单**。与应用程序开发的所有部分一样，API 有一个生命周期：定义、构建、测试、部署和维护（包括停用）。Salesforce 平台 API 在一个日历年内发布多个版本，因为平台的发布周期很快。（您可以在 Salesforce [架构基础](/docs/architect/zh-cn/fundamentals/guide/architecture-basics#平台-api)中阅读有关此行为的更多信息。）这意味着平台 API 的生命周期相当复杂，因为需要维护特定 API 的多个版本，可供 Salesforce 客户使用。此复杂性级别适用于 PaaS 用例，但它很可能是平台内解决方案架构不必要的复杂性（请参阅：可[读性反模式](/docs/architect/zh-cn/well-architected/guide/intentional#可读性模式和反模式)）。专注于定义 API 的明确目的（例如，错误处理）和明确的基准定义。目标是每个 API 只有一个版本。
- **使您的 API 可发现、可访问和管理。**[记录 API，](/docs/architect/zh-cn/well-architected/guide/intentional#设计标准)以便潜在消费者可以轻松找到可用的 API。API 需要作为[功能](/docs/architect/zh-cn/well-architected/guide/composable#功能单元)环境的一部分平稳运行。
- **迭代**。专注于一次仅定义和实施一个内部 API。这样，您可以专注于快速迭代 API 定义，为*一个*支持的版本找到正确的形式，并从实施经验中建立最佳实践。

以下[模式和反模式](/docs/architect/zh-cn/well-architected/guide/composable#交互模式和反模式)列表显示了 Salesforce 解决方案中正确(和差)的 API 管理。您可以在构建之前使用这些来验证您的设计，或者确定您的系统需要重构的区域。

要了解有关 Salesforce 可用工具的更多信息，以帮助您建立更好的互操作性，请参阅[相关工具](/docs/architect/zh-cn/well-architected/guide/composable#与可撰写相关的工具)。

### 交互模式和反模式

下表显示了在您的组织中要查找（或构建）的模式的选择，以及要避免或针对补救的反模式。

✨ 在[模式和反模式探索](/docs/architect/zh-cn/well-architected-tools/guide/adaptable-interoperability)器中，发现更多互操作性模式。

<table>
    <colgroup>
       <col span="1" style="width: 10%;">
       <col span="1" style="width: 45%;">
       <col span="1" style="width: 45%;">
    </colgroup>
    <tbody>
        <tr>
            <th scope="colgroup"></th>
            <th scope="colgroup">模式</th>
            <th scope="colgroup">反模式</th>
        </tr>
        <tr>
            <td rowspan="3"><b>消息传递和事件</b></td>
            <td><b>在设计标准中：</b>
                <br> - 对于何时使用同步模式（消息传递）和异步模式（事件），存在明确的标准
                <br> - 事件和消息结构存在明确的标准
            </td>
            <td><b>在设计标准中：</b>
                <br> - 设计标准不存在，或者缺乏同步与异步模式的明确标准，以及消息或事件结构的明确标准
            </td>
        </tr>
        <tr>
            <td><b>在您的组织中：</b>
                <br> - 用于内部系统消息传递的平台事件被清楚地标记
                <br> - Salesforce 流工具引用全系统消息传递或事件服务
                <br> - 一致的消息传递和事件模式出现在流和代码中
            </td>
            <td><b>在您的组织中：</b>
                <br> - 用于内部系统消息传递的平台事件未明确标记或不存在
                <br> - 流和代码中出现不同的消息传递和事件模式策略
            </td>
        </tr>
        <tr>
            <td><b>在 Apex 或 LWC 中：</b>
                <br> - 自定义事件定义的范围有限（代码中未定义系统范围的事件或消息）
                <br> - Apex 中的系统范围消息传递或事件服务以使它们在 Salesforce 流工具中可用的方式注释
            </td>
            <td><b>在 Apex 或 LWC 中：</b>
                <br> - 系统范围的消息和/或事件结构在 Apex 或 JavaScript 中定义
                <br> - Apex 中定义的系统范围事件或消息结构在流等工具中不可用
            </td>
        </tr>
         <tr>
            <td rowspan="3"><b>API 管理</b></td>
            <td><b>在设计标准中：</b>
                <br> - 存在跨组件通信的清除协议（即 API）
                <br> - 协议/API 在生成器可以搜索和查找的逻辑组中概述
                <br> - 协议/API 定义了变量数据类型、变量名称、必填或可选内容，并清楚地描述了何时使用
            </td>
            <td><b>在设计标准中：</b>
                <br> - 设计标准不存在或未定义 API 和用例
            </td>
        </tr>
        <tr>
            <td><b>在您的文档中：</b>
                <br> - 每个组件的文档都清楚地列出了哪些 API/通信协议已经实施
                <br> - 可以搜索特定 API 或协议，并确定实施该协议的组件
            </td>
            <td><b>在您的文档中：</b>
                <br> - 组件文档不存在
                <br> - 组件文档描述了在组件中实施的 API，但这是 API 定义出现的唯一位置
                <br> - 无法搜索特定 API 或协议和/或搜索无助于识别已实施 API 或协议的组件
            </td>
        </tr>
        <tr>
            <td><b>在您的组织中：</b>
                <br> - 内部通信的 API 消息格式和变量使用自定义元数据类型定义
                <br> - 内部通信的 API 消息格式和变量由平台事件定义
                <br> - 代码和声明性自定义引用适当的自定义元数据类型（或平台事件），以便发送或接收信息
            </td>
            <td><b>在您的组织中：</b>
                <br> - 系统组件之间的通信（代码和声明性自定义）是临时的
                <br> - API 专为 Salesforce 与外部系统之间的通信定义
            </td>
        </tr>
    </tbody>
</table>

## 可打包性

在 Salesforce 组织中创建可打包性意味着组织中的功能来自可作为软件包独立可靠地开发和部署的单元。理想情况下，这些单元被定义为[第二代](https://developer.salesforce.com/docs/atlas.en-us.218.0.sfdx_dev.meta/sfdx_dev/sfdx_dev_dev2gp_plan_pkg_types.htm)软件包的类型(解锁软件包或 ISV 受管软件包 ) 。注意：因为架构良好的解决方案专门使用这些软件包类型，所以这里不包括第一代受管软件包。

在 Salesforce 组织中定义[关注分离](/docs/architect/zh-cn/well-architected/guide/composable#分离问题)并创建功能单元是一回事。清晰地解开和管理依赖性是另一回事，可以成功地将这些单元作为软件包工件进行版本化。实现该级别的稳定性和元数据隔离需要相当程度的 DevOps（和架构）成熟度。它还加快了开发时间，改善了应用程序生成器体验，并为发布和发布管理带来了可预测性和控制力。并非每个组织都能够支持定义、维护和开发有效软件包所需的基础架构。但实现可打包性应该是几乎所有 Salesforce 组织的最终目标。

通过关注松耦合和依赖性管理，您可以在 Salesforce 解决方案中构建可打包性。

### 松耦合

在松耦合的系统中，单个部件不会彼此紧密相连。可组合系统的许多优点都来自松耦合。在可封装系统中，实现软件包之间的松耦合（和安装组织）将使您能够拥有定义明确的软件包，并为使用软件包的团队提供更高效的开发周期。

在 Salesforce 平台上，您可以构建[紧密耦合到特定组织](https://developer.salesforce.com/docs/atlas.en-us.sfdx_dev.meta/sfdx_dev/sfdx_dev_unlocked_pkg_org_dependent.htm)的软件包。随着您封装成熟度的进展，此功能有助于定义功能单元并在贵组织中尝试正确[分离关注](/docs/architect/zh-cn/well-architected/guide/composable#分离问题)。但是，如果您选择这种方法，您将不会意识到真正可封装元数据的好处，包括源驱动的开发、使用版本的能力和工件稳定性。相反，您很可能会继续遇到紧耦合系统的缺点，包括：

- 导致停机和性能问题的单点故障
- 部署缓慢、不可预测
- 困难、复杂的调试和故障排除周期
- [规模](/docs/architect/zh-cn/well-architected/guide/reliable#可扩展性)和[绩效](/docs/architect/zh-cn/well-architected/guide/reliable#性能)问题

任何可封装 Salesforce 系统的最终目标是松耦合软件包。

在您将 Salesforce 元数据分为有效软件包时，请考虑以下事项：

- **哪些自定义是数据与元数据**在可打包性方面，Salesforce 平台对数据和元数据的处理方式非常不同。了解贵组织中哪些功能是[元数据或数据](/docs/architect/zh-cn/fundamentals/guide/architecture-basics#元数据与数据)非常重要。您不能将数据包含在任何封装单元中。当您决定从哪里开始将功能抽象到封装单元中时，您的团队将需要决定存储为数据的自定义是应该完全从软件包中排除，还是应该重构到基于元数据的实施中。
- **打包如何影响团队**。Salesforce 打包的一个逻辑现实是,生产和发布软件包版本的大部分工作需要具备 Salesforce CLI 和/或 CI/CD 技术的技能。这意味着低代码和编程自定义都需要时间和关注能够使用软件包相关 DevOps 技术的人员。根据您的团队管理功能交付的方式，软件包采用可能会给组织内的不同团队带来显著的减缓或阻碍。您必须确定团队是否能够通过打包管理功能交付，并制定计划来解决任何技能或人员不足的问题。解决方案可能包括采用成对编程或为开发环境实施 CI/CD 作业。
- **打包将如何改变环境策略**在软件包驱动的开发生命周期中，早期工作应在[临时组织中](https://developer.salesforce.com/docs/atlas.en-us.238.0.sfdx_setup.meta/sfdx_setup/sfdx_setup_next_steps.htm?q=scratch%20org)完成。这些临时源代码驱动的开发环境允许更快、更迭代的周期。它们还支持开发团队进行更精细的环境访问控制，并与生产更好地隔离。软件包对未封装元数据或仅存在于 Sandbox 或生产环境中的数据的依赖性越大，团队就越不可能实际使用临时组织。您可以[在 Sandbox 中启用源跟踪](https://developer.salesforce.com/docs/atlas.en-us.sfdx_dev.meta/sfdx_dev/sfdx_setup_enable_source_tracking_sandboxes.htm)，以允许在非临时组织环境中使用源驱动的开发模式，但您的开发团队不会从临时组织的速度和迭代速度中受益。
- **软件包版本与发布版本的关系**。计划开发软件包版本的频率和阶段。软件包版本请求在 24 小时滚动的基础上受到限制（每个组织）。作为一般最佳实践，只有当您确信软件包内容不需要更改时，才对软件包进行版本化。理想情况下，您将在质量保证流程完成后配置软件包版本。请勿允许开发团队将软件包创建请求的成功或失败用作对软件包边界定义的“测试”。有几种方法可以做到这一点，而无需尝试对软件包工件进行版本化。
- **理想的最终状态应该支持什么**。理想的打包策略允许快速开发和交付受控、稳定的 Salesforce 版本。在整个组织中定义太多的软件包可能会给开发团队带来新的复杂性和瓶颈。过度模块化的组织也会导致发布缓慢和困难。从构建和发布一个有意义软件包的几个版本开始。增量派生跟进软件包。当您的发布节奏很好地服务于您的业务时，停止引入软件包。如果业务需求发生变化或发布质量下降，随着时间的推移，重构软件包。理想的软件包结束状态是主观的。

无论您决定如何定义软件包，您都只能通过有效的[依赖管理](/docs/architect/zh-cn/well-architected/guide/composable#依赖性管理)来成功版本松耦合的软件包。

下面的[模式和反模式](/docs/architect/zh-cn/well-architected/guide/composable#可封装性模式和反模式)列表显示了 Salesforce 打包的正确(和差)松耦合的外观。您可以在构建之前使用这些来验证您的设计，或者确定您的系统需要重构的区域。

要了解有关 Salesforce 工具的更多信息，以帮助您构建更多可打包性，请参阅[工具相关可撰写](/docs/architect/zh-cn/well-architected/guide/composable#与可撰写相关的工具)。

### 依赖性管理

在 Salesforce 解决方案的上下文中，依赖性管理意味着识别和构建软件包中的元数据与这些软件包将被安装到的组织中元数据之间的关系。依赖性管理是开发稳定软件包工件的关键部分。

依赖性与创建完全分离、[松散耦合](/docs/architect/zh-cn/well-architected/guide/composable#松耦合)的功能单元的努力背道而驰。在理想的工程状态下，松散耦合的系统在单元之间没有依赖性。但在现实世界中，消除所有依赖性并不实际。

通常,要使系统[可读](/docs/architect/zh-cn/well-architected/guide/intentional#可读性)和使用业务友好[功能单元](/docs/architect/zh-cn/well-architected/guide/composable#功能单元)之间保持平衡,需要在系统中各单元之间的完美隔离方面进行权衡。更务实地讲,Salesforce Platform 的[标准功能](/docs/architect/zh-cn/well-architected/guide/intentional#标准与自定义功能)提供的核心服务为任何 Salesforce 解决方案创建了关键的净正依赖性。许多内置的可扩展性、性能和安全性优势来自它们与平台集成的深度。在设计可封装的 Salesforce 解决方案时，重要的是要记住软件包依赖性本质上不是坏的。依赖关系管理差*是*不好的。

使用 Salesforce 打包进行有效的依赖性管理意味着开发和维护团队可以：

- 更快地加入新项目，环境访问权限有限
- 快速开发和测试更改
- 了解如何在更小的具体承诺中提供复杂的功能
- 控制发布节奏，减少系统维护/发布中断时段
- 在任何环境中可预测地回滚不利变化

使用 Salesforce 进行依赖性管理的技术非常简单：

- 使用[消息传递和事件](/docs/architect/zh-cn/well-architected/guide/composable#消息传递和事件)处理组件之间有状态或无状态信息的优雅切换。
- 使用自定义元数据类型提供动态运行时信息，并支持依赖注入模式。
- 让 Apex 开发人员使用[抽象或虚拟类](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_classes_extending.htm)。

最后，您需要决定贵组织中允许的声明性和编程性开发的设计模式。最重要的注意事项（在架构上）是定义您想要在哪些方面增加工程复杂性，以便减少依赖性，以及您需要在哪些方面容忍更多依赖性，以简化应用程序生成器工作流。

当您将依赖性管理策略构建到软件包中时，请考虑软件包单元的两个主要组织原则：水平和垂直。

- **水平边界**。在水平模式中，多个软件包可能需要的功能被抽象到水平层中。然后，水平层成为常见功能的来源，并通过声明的依赖关系访问。最小化软件包之间的冗余功能优于最小化依赖性。
- **垂直边界**。垂直模式最大化了系统各部分之间的隔离和松散耦合。共享功能有限，类似的工作可能会跨单位显示。依赖性受到严格限制，以便最大限度地隔离软件包单元。

请注意，这不是一个要么/要么的决定。您可以根据需要混合垂直和水平模式。通常，从软件包开始的最快方法是创建水平服务层。随着软件包采用的规模和复杂性的增长，抽象更多垂直单元将有助于简化复杂的环境设置流程或开发人员入门。

例如，具有两个功能单元（A 和 B）的系统可以使用以垂直、水平和垂直-水平混合模式排列的软件包依赖性来构建。

<a href="https://a.sfdcstatic.com/developer-website/prod/images/architect/composable-vertical-horizontal-slices.jpeg" target="_blank">
    <img style="border:1px solid #e5e5e5;margin:2rem 0rem" src="https://a.sfdcstatic.com/developer-website/prod/images/architect/composable-vertical-horizontal-slices.jpeg" alt="该图显示了两个软件包 A 和 B，它们被构建为没有共享依赖性（垂直切片），被构建为有许多常见的服务（水平）和每个服务的混合（混合）。">
</a>

不论您选择的软件包组织模式如何，请记住一些绝对值：

- **请勿在软件包之间重复元数据。**多个软件包需要的元数据应抽象为一个或多个声明为依赖项的软件包。
- **利用 Salesforce Platform 元数据的内置依赖性。**对于应用程序生成器，Salesforce Platform 提供的内置服务提供了大量可以快速配置的功能。其中许多服务具有内置的依赖性，使它们难以抽象为低级别的功能单元。对于给定的元数据类型，您需要了解它在[内置依赖关系](https://developer.salesforce.com/blogs/2018/06/lets-talk-deployment-and-reasons-why-they-succeed-or-fail)中所处的位置，并使用这种了解来[定义软件包依赖](https://developer.salesforce.com/blogs/2018/06/working-with-modular-development-and-unlocked-packages-part-2)链。不要通过尝试将松散耦合强制纳入具有大量内置依赖性的标准平台功能来开始软件包采用。当您达到更高的功能时，它将增加复杂性（而不是价值）。这也是另一种归入[标准和自定义](/docs/architect/zh-cn/well-architected/guide/intentional#标准与自定义功能)[反模式](/docs/architect/zh-cn/well-architected/guide/intentional#可维护性模式和反模式)的方法。从底部（最低的依赖性）向上封装元数据，并随着时间的推移进行迭代。
- **留意依赖链**。避免创建软件包依赖链，这将要求开发人员在任何时候将他们所做的更改拆分成许多不同的软件包。
- **想想什么对源控制有意义**在源控制中管理软件包有两种基本方法。第一个是单个*monorepo*，软件包隔离在文件夹中。第二个是多个存储库，软件包隔离在自己的存储库中。长期管理每种源策略都很复杂。就开发人员入门而言，垂直边界在多个存储库模式中效率更高。水平边界在单层建筑中更容易理解。同样，随着架构的成熟，您可以混合和匹配策略。

下面的[模式和反模式](/docs/architect/zh-cn/well-architected/guide/composable#可封装性模式和反模式)列表显示了 Salesforce 软件包中正确(和差)的依赖管理是什么样子的。您可以在构建之前使用这些来验证您的设计，或者确定您的系统需要重构的区域。

要了解有关适用于依赖管理的 Salesforce 工具的更多信息，请参阅[工具相关可撰写](/docs/architect/zh-cn/well-architected/guide/composable#与可撰写相关的工具)。

### 可封装性模式和反模式

下表显示了在您的组织中要查找（或构建）的模式的选择，以及要避免或针对补救的反模式。

✨ 在[模式和反模式探索](/docs/architect/zh-cn/well-architected-tools/guide/adaptable-packageability)器中，发现更多可封装性模式。

<table>
    <colgroup>
       <col span="1" style="width: 10%;">
       <col span="1" style="width: 45%;">
       <col span="1" style="width: 45%;">
    </colgroup>
    <tbody>
        <tr>
            <th scope="colgroup"></th>
            <th scope="colgroup">模式</th>
            <th scope="colgroup">反模式</th>
        </tr>
        <tr>
            <td rowspan="5"><b>松耦合</b></td>
            <td><b>在设计标准中：</b>
                <br> - 命名约定解决了如何表示软件包单位的问题
                <br> - 可以搜索并查找所有当前定义的软件包单元（和相关命名约定）的列表
                <br> - 存在建议软件包单元添加或更改的标准
                <br> -（可选）自定义设置的所有批准的用例都清楚地列出（如果有）
            </td>
            <td><b>在设计标准中：</b>
                <br> - 设计标准不存在或未处理软件包单元和用例
            </td>
        </tr>
        <tr>
            <td><b>在您的组织中：</b>
                <br> - 自定义元数据类型为代码和声明性自定义提供动态运行时信息
                <br> - 不存在自定义设置或自定义设置很少，并且没有与封装功能相关的设置
                <br> - 不存在自定义对象，以便为代码或声明性自定义提供动态运行时信息
            </td>
            <td><b>在您的组织中：</b>
                <br> - 使用自定义设置
                <br> - 自定义对象的存在是为了提供代码或声明性自定义的动态运行时信息
                <br> - 自定义元数据类型未用于（或未一致使用）为代码和声明性自定义提供动态运行时信息
            </td>
        </tr>
        <tr>
            <td><b>在 Apex 中：</b>
                <br> - 使用抽象或虚拟 Apex 类定义常见服务和模板代码
                <br> - 依赖于动态运行时信息的方法引用适当的自定义元数据类型
            </td>
            <td><b>在 Apex 中：</b>
                <br> - 常见服务和模板代码不易与其他类区分
                <br> - 跨类和方法的内部引用难以遵循，并且在整个代码库中不一致
                <br> - 方法没有使用一致的方法来访问动态、运行时信息，或者方法没有查询运行时行为信息的自定义对象，或者代码引用自定义设置
            </td>
        </tr>
        <tr>
            <td><b>在源控制和开发环境中：</b>
                <br> - package.xml 文件仅出现在早期阶段或概念验证项目清单中
            </td>
            <td><b>在源控制和开发环境中：</b>
                <br> - package.xml 文件用于控制元数据部署
            </td>
        </tr>
        <tr>
            <td><b>在软件包中：</b>
                <br> - 依赖于组织的解锁软件包仅用于早期阶段或概念验证实验
                <br> - 在生产或 Sandbox 中未定义非受管软件包
            </td>
            <td><b>在软件包中：</b>
                <br> - 所有软件包都是依赖于组织的解锁软件包
                <br> - 非受管软件包在生产或 Sandbox 中定义
            </td>
        </tr>
         <tr>
            <td rowspan="4"><b>依赖性管理</b></td>
            <td><b>在设计标准中：</b>
                <br> - 存在声明依赖性的标准
                <br> - 存在引入或修改依赖性的标准
            </td>
            <td><b>在设计标准中：</b>
                <br> - 设计标准不存在或未涉及如何声明依赖性
            </td>
        </tr>
        <tr>
            <td><b>在源控制中：</b>
                <br> - 解锁软件包的软件包版本使用别名 (<code>LATEST</code>) 在 <code>sfdx-project.json</code> 清单中声明依赖性
                <br> - 开发人员可以从源代码控制中创建临时组织并成功部署软件包元数据
            </td>
            <td><b>在源控制中：</b>
                <br> - 解锁软件包的软件包版本在 <code>sfdx-project.json</code> 清单中明确声明（无 <code>lateST</code> 别名）
                <br> - 开发人员无法使用源代码控制成功使用临时组织
            </td>
        </tr>
        <tr>
            <td><b>在软件包中：</b>
                <br> - 软件包之间没有重复的元数据
                <br> - 对于软件包开发，所有早期开发工作都在临时组织中进行
            </td>
            <td><b>在软件包中：</b>
                <br> - 通过在不同软件包中复制元数据来规避依赖性
                <br> - 早期软件包开发发生在 Developer Sandbox 中，或者早期软件包开发不能发生在临时组织中
            </td>
        </tr>
        <tr>
            <td colspan="2">另请参阅：<a href="/docs/architect/zh-cn/well-architected/guide/composable#松耦合">松耦合</a></td>
        </tr>
    </tbody>
</table>

## 与可撰写相关的工具

<table class="tools-table"><tbody><tr><th>工具</th><th>描述</th><th>分离问题</th><th>交互性</th><th>可打包性</th></tr>
<tr><td><a href="https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_rest.htm">Apex REST Web Services</a></td><td>通过 REST 向外部应用程序公开 Apex 类和方法</td><td class="check-col"></td><td class="check-col">X</td><td class="check-col"></td></tr>
<tr><td><a href="https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_web_services.htm#apex_web_services">Apex SOAP Web Services</a></td><td>通过 SOAP 向外部应用程序公开 Apex 类和方法</td><td class="check-col"></td><td class="check-col">X</td><td class="check-col"></td></tr>
<tr><td><a href="https://developer.salesforce.com/docs/atlas.en-us.change_data_capture.meta/change_data_capture/cdc_intro.htm">变更数据捕获</a></td><td>将更改发布到 Salesforce 记录</td><td class="check-col"></td><td class="check-col">X</td><td class="check-col"></td></tr>
<tr><td><a href="https://help.salesforce.com/s/articleView?id=sf.custommetadatatypes_overview.htm&language=en_US&r=https%3A%2F%2Fwww.google.com%2F&type=5">自定义元数据类型</a></td><td>定义可重用、可自定义、可封装的功能</td><td class="check-col"></td><td class="check-col"></td><td class="check-col">X</td></tr>
<tr><td><a href="https://developer.salesforce.com/docs/component-library/documentation/en/lwc/reference_decorators">装饰师</a></td><td>将函数或属性公开为 api</td><td class="check-col">X</td><td class="check-col">X</td><td class="check-col"></td></tr>
<tr><td><a href="https://developer.salesforce.com/docs/atlas.en-us.sfdx_dev.meta/sfdx_dev/sfdx_setup_enable_devhub.htm">Dev Hub</a></td><td>管理临时组织、第二代软件包和 Einstein 功能。</td><td class="check-col">X</td><td class="check-col">X</td><td class="check-col">X</td></tr>
<tr><td><a href="https://developer.salesforce.com/docs/atlas.en-us.api_streaming.meta/api_streaming/generic_streaming_intro.htm">通用事件（传统）*</a></td><td>发送与 Salesforce 数据更改无关的自定义事件</td><td class="check-col"></td><td class="check-col">X</td><td class="check-col"></td></tr>
<tr><td><a href="https://developer.salesforce.com/docs/component-library/documentation/en/lwc/lwc.data_ui_api">Lightning数据服务</a></td><td>跨组件缓存和共享数据</td><td class="check-col">X</td><td class="check-col">X</td><td class="check-col"></td></tr>
<tr><td><a href="https://developer.salesforce.com/docs/atlas.en-us.api_meta.meta/api_meta/meta_intro.htm">Metadata API</a></td><td>在 Salesforce 环境之间部署自定义</td><td class="check-col"></td><td class="check-col"></td><td class="check-col">X</td></tr>
<tr><td><a href="https://developer.salesforce.com/docs/atlas.en-us.sfdx_dev.meta/sfdx_dev/sfdx_dev_supported_mdapi_types.htm">元数据覆盖范围报表</a></td><td>确定几个渠道之间支持的元数据覆盖范围 </td><td class="check-col"></td><td class="check-col"></td><td class="check-col">X</td></tr>
<tr><td><a href="https://docs.mulesoft.com/composer/ms_composer_overview">MuleSoft Composer</a></td><td>使用单击而不是代码为数据构建流程自动化</td><td class="check-col"></td><td class="check-col">X</td><td class="check-col"></td></tr>
<tr><td><a href="https://developer.salesforce.com/docs/atlas.en-us.api.meta/api/sforce_api_om_outboundmessaging.htm">出站消息</a></td><td>在更新字段值时向外部端点发送消息</td><td class="check-col"></td><td class="check-col">X</td><td class="check-col"></td></tr>
<tr><td><a href="https://developer.salesforce.com/docs/atlas.en-us.platform_events.meta/platform_events/platform_events_intro.htm">平台事件 </a></td><td>发送包含近乎实时事件数据的安全和可扩展的消息</td><td class="check-col"></td><td class="check-col">X</td><td class="check-col"></td></tr>
<tr><td><a href="https://developer.salesforce.com/blogs/2021/07/pub-sub-api-building-event-driven-integrations-just-got-even-easier">发布/订阅 API</a></td><td>订阅平台事件、变更数据捕获或实时 Event Monitoring</td><td class="check-col"></td><td class="check-col">X</td><td class="check-col"></td></tr>
<tr><td><a href="https://developer.salesforce.com/docs/atlas.en-us.api_streaming.meta/api_streaming/pushtopic_events_intro.htm">PushTopic 事件（原有）*</a></td><td>发送和接收与用户定义的 SOQL 查询匹配的数据变更通知</td><td class="check-col"></td><td class="check-col">X</td><td class="check-col"></td></tr>
<tr><td><a href="https://developer.salesforce.com/tools/sfdxcli">Salesforce CLI</a></td><td>与 Salesforce 组织协作时开发和构建自动化</td><td class="check-col"></td><td class="check-col"></td><td class="check-col">X</td></tr>
<tr><td><a href="/docs/architect/zh-cn/reference-diagrams/guide/introduction">Salesforce Diagrams</a></td><td>创建图表以显示业务功能和技术详细信息</td><td class="check-col">X</td><td class="check-col"></td><td class="check-col"></td></tr>
<tr><td><a href="https://marketplace.visualstudio.com/items?itemName=salesforce.salesforcedx-vscode-expanded">适用于 Visual Studio 代码的 Salesforce 扩展（展开）</a></td><td>适用于 Salesforce 开发的官方 VS Code 扩展</td><td class="check-col"></td><td class="check-col"></td><td class="check-col">X</td></tr>
<tr><td><a href="https://developer.salesforce.com/docs/atlas.en-us.sfdx_dev.meta/sfdx_dev/sfdx_dev_scratch_orgs.htm">临时组织</a></td><td>将 Salesforce 代码和元数据部署到一次性组织</td><td class="check-col"></td><td class="check-col"></td><td class="check-col">X</td></tr>
<tr><td><a href="https://developer.salesforce.com/docs/atlas.en-us.sfdx_dev.meta/sfdx_dev/sfdx_dev_dev2gp.htm">第二代受管软件包</a></td><td>为 AppExchange 开发和分发应用程序</td><td class="check-col"></td><td class="check-col"></td><td class="check-col">X</td></tr>
<tr><td><a href="https://developer.salesforce.com/docs/atlas.en-us.api_tooling.meta/api_tooling/intro_tasks.htm">工具 API</a></td><td>为 Lightning 平台应用程序构建自定义开发工具或应用程序</td><td class="check-col"></td><td class="check-col"></td><td class="check-col">X</td></tr>
<tr><td><a href="https://developer.salesforce.com/docs/atlas.en-us.sfdx_dev.meta/sfdx_dev/sfdx_dev_unlocked_pkg_intro.htm">解锁的软件包</a></td><td>组织元数据、封装应用程序或扩展 AppExchange 应用程序</td><td class="check-col"></td><td class="check-col"></td><td class="check-col">X</td></tr>
<tr>
<td colspan="5">*Salesforce 将继续在当前功能范围内支持 PushTopic 和通用事件，但不打算对此技术进行进一步投资。</td>
</tr>
</table>

## 与可撰写相关的资源

<table class="tools-table"><tbody><tr><th>资源</th><th>描述</th><th>分离问题</th><th>交互性</th><th>可打包性</th></tr>
<tr><td><a href="https://blogs.mulesoft.com/api-integration/strategy/a-primitive-look-at-digital-integration/">对数字集成的初步了解</a></td><td>为连接概念开发通用语言</td><td class="check-col"></td><td class="check-col">X</td><td class="check-col"></td></tr>
<tr><td><a href="https://medium.com/p/cd4b7ebe926b">将域驱动的设计应用于 Salesforce</a></td><td>围绕业务功能定位解决方案</td><td class="check-col">X</td><td class="check-col"></td><td class="check-col"></td></tr>
<tr><td><a href="https://developer.salesforce.com/docs/atlas.en-us.218.0.sfdx_dev.meta/sfdx_dev/sfdx_dev_dev2gp_plan_best_practices.htm">第二代软件包的最佳实践</a></td><td>了解 2GP 打包模式和实践</td><td class="check-col"></td><td class="check-col"></td><td class="check-col">X</td></tr>
<tr><td><a href="https://developer.salesforce.com/docs/atlas.en-us.238.0.sfdx_dev.meta/sfdx_dev/packaging_packageable_components.htm">受管软件包中可用的组件</a></td><td>了解受管软件包元数据组件</td><td class="check-col"></td><td class="check-col"></td><td class="check-col">X</td></tr>
<tr><td><a href="/docs/architect/zh-cn/resources/guide/design-standards-template">设计标准模板</a></td><td>为您的组织创建设计标准</td><td class="check-col">X</td><td class="check-col">X</td><td class="check-col">X</td></tr>
<tr><td><a href="/docs/architect/zh-cn/decision-guides/guide/event-driven">事件驱动架构决策指南</a></td><td>比较事件驱动的架构模式和工具</td><td class="check-col"></td><td class="check-col">X</td><td class="check-col"></td></tr>
<tr><td><a href="https://developer.salesforce.com/docs/atlas.en-us.lightning.meta/lightning/events_anti_patterns.htm">事件反模式</a></td><td>确定使用事件时要避免的反模式</td><td class="check-col"></td><td class="check-col">X</td><td class="check-col"></td></tr>
<tr><td><a href="https://blogs.mulesoft.com/dev-guides/design-message-driven-and-event-driven-apis/">如何设计消息驱动和事件驱动的 API</a></td><td>阅读 MuleSoft 开发指南中的差异</td><td class="check-col">X</td><td class="check-col">X</td><td class="check-col"></td></tr>
<tr><td><a href="https://trailhead.salesforce.com/en/content/learn/modules/jobs-to-be-done-framework-for-designers/learn-about-the-jobs-to-be-done-framework">了解要完成的作业框架</a></td><td>在 Trailhead 上探索 JTBD</td><td class="check-col">X</td><td class="check-col"></td><td class="check-col"></td></tr>
<tr><td><a href="https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/guide/managing-global-state.html">在 B2C Commerce 中管理全球状态</a></td><td>在组件之间轻松传递数据以保持状态</td><td class="check-col">X</td><td class="check-col"></td><td class="check-col"></td></tr>
<tr><td><a href="https://www.lightningdesignsystem.com/guidelines/messaging/overview/">消息传递指南</a></td><td>交流相关信息，创造欢乐时刻</td><td class="check-col"></td><td class="check-col">X</td><td class="check-col"></td></tr>
<tr><td><a href="https://www.lightningdesignsystem.com/guidelines/messaging/types/">消息传递类型</a></td><td>根据用户交互的性质了解不同的消息传递类型</td><td class="check-col"></td><td class="check-col">X</td><td class="check-col"></td></tr>
<tr><td><a href="https://developer.salesforce.com/docs/atlas.en-us.238.0.api_meta.meta/api_meta/meta_types_list.htm">元数据类型</a></td><td>了解 Salesforce 组织中不同类型的元数据</td><td class="check-col">X</td><td class="check-col"></td><td class="check-col">X</td></tr>
<tr><td><a href="https://help.salesforce.com/s/articleView?id=sf.salesforce_app_enable_push_notifications.htm&type=5">移动应用程序通知类型</a></td><td>了解 Salesforce 移动应用程序的通知类型</td><td class="check-col"></td><td class="check-col">X</td><td class="check-col"></td></tr>
<tr><td><a href="https://developer.salesforce.com/docs/atlas.en-us.salesforce_visualforce_best_practices.meta/salesforce_visualforce_best_practices/pages_best_practices_perf_code_view_state.htm">优化视图状态</a></td><td>在 Visualforce 页面中维护状态</td><td class="check-col">X</td><td class="check-col"></td><td class="check-col"></td></tr>
<tr><td><a href="https://developer.salesforce.com/docs/atlas.en-us.sfdx_dev.meta/sfdx_dev/sfdx_dev_intro.htm">Salesforce 开发人员体验 (DX)</a></td><td>在 Lightning 平台上管理和开发应用程序</td><td class="check-col">X</td><td class="check-col">X</td><td class="check-col">X</td></tr>
<tr><td><a href="https://developer.salesforce.com/docs/atlas.en-us.api_meta.meta/api_meta/meta_unsupported_types.htm">不支持的元数据类型</a></td><td>识别在元数据 API 中不可用的组件</td><td class="check-col"></td><td class="check-col"></td><td class="check-col">X</td></tr>
</table>

## 告诉我们您的想法

帮助我们保持 Salesforce 架构合理与您相关；参加我们的[调查](https://sfdc.co/bxNtvh)，以提供有关此内容的反馈，并告诉我们您接下来想要看到的内容。
