Skip to main content

功能与策略

大多数现实世界的应用程序都需要适应不同设备和平台的功能和策略。此页面包含有关如何在代码中处理这些场景的建议。

针对每种设备类型的优势进行设计

#

考虑不同设备的独特优势和劣势。除了屏幕尺寸和输入方式(如触摸、鼠标、键盘)之外,您还可以利用哪些其他独特功能?Flutter 使您的代码能够在不同的设备上 运行 ,但强大的设计不仅仅是运行代码。考虑每个平台最擅长什么,并查看是否有独特的可利用功能。

例如:Apple 的 App Store 和 Google 的 Play Store 有不同的规则,应用程序需要遵守这些规则。不同的主机操作系统在时间上以及彼此之间也具有不同的功能。

另一个示例是利用 Web 极低的共享障碍。如果您正在部署 Web 应用程序,请确定要支持哪些深层链接,并以此为出发点设计导航路线。

Flutter 建议用于根据这些独特功能处理不同行为的模式是为您的应用程序创建一组 CapabilityPolicy 类。

功能

#

功能 定义代码或设备 能够 做什么。功能示例包括:

  • API 的存在
  • 操作系统强制的限制
  • 物理硬件要求(如摄像头)

策略

#

策略 定义代码 应该 做什么。

策略示例包括:

  • 应用商店指南
  • 设计偏好
  • 指向主机设备的资产或副本
  • 服务器端启用的功能

如何构建策略代码

#

最简单的机械方法是 Platform.isAndroidPlatform.isIOSkIsWeb。这些 API 可以机械地让您知道代码在哪里运行,但在应用程序扩展其运行位置以及主机平台添加功能时,存在一些问题。

以下指南说明了在为您的应用程序开发功能和策略时的最佳实践:

避免使用 Platform.isAndroid 和类似函数来做出布局决策或关于设备可以做什么的假设。

而是用方法描述您想要分支的内容。

示例:您的应用程序有一个在网站上购买东西的链接,但出于策略原因,您不想在 iOS 设备上显示该链接。

dart
bool shouldAllowPurchaseClick() {
  // Apple App Store 指南禁止。
  return !Platform.isIOS;
}

...
TextSpan(
  text: '在浏览器中购买',
  style: new TextStyle(color: Colors.blue),
  recognizer: shouldAllowPurchaseClick ? TapGestureRecognizer()
    ..onTap = () { launch('<some url>') : null;
  } : null,

通过添加间接层,您获得了什么?代码更清晰地说明了分支路径存在的原因。此方法可以直接存在于类中,但代码的其他部分也可能需要相同的检查。如果是这样,请将代码放在一个类中。

policy.dart
dart

class Policy {

  bool shouldAllowPurchaseClick() {
    // Apple App Store 指南禁止。
    return !Platform.isIOS;
  }
}

使用此类中的代码,任何小部件测试都可以模拟 Policy().shouldAllowPurchaseClick 并独立于设备运行位置验证行为。这也意味着,如果您以后决定在 Web 上购买不适合 Android 用户,您可以更改实现,并且可点击文本的测试无需更改。

功能

#

有时您希望您的代码执行某些操作,但 API 不存在,或者您可能依赖于尚未在您支持的所有平台上实现的插件功能。这是设备 能够 做什么的限制。

这些情况类似于上面描述的策略决策,但这些被称为 功能 。当类的结构相似时,为什么将策略类与功能分开?Flutter 团队在生产应用中发现,在应用程序 能够 做什么和 应该 做什么之间做出逻辑区分,有助于大型产品响应平台能够做什么或要求的更改,以及在编写初始代码后您自己的偏好。

例如,考虑以下情况:一个平台添加了一个新权限,该权限要求用户在代码调用敏感 API 之前与系统对话框进行交互。您的团队为平台 1 完成了这项工作,并创建了一个名为 requirePermissionDialogFlow 的功能。然后,如果平台 2 添加了类似的要求,但仅适用于新的 API 版本,则 requirePermissionDialogFlow 的实现现在可以检查 API 级别并为平台 2 返回 true。您已经利用了您已经完成的工作。

策略

#

即使您似乎不会做出许多基于策略的决策,我们也鼓励您最初使用 Policy 类。随着类复杂性的增加或输入数量的扩展,您可能会决定按功能或其他标准分解策略类。

对于策略实现,您可以使用编译时、运行时或远程过程调用 (RPC) 支持的实现。

编译时策略检查适用于偏好不太可能更改且意外更改值可能会产生重大后果的平台。例如,如果平台要求您不要链接到 Play 商店,或者要求您根据应用程序的内容使用特定的支付提供商。

运行时检查可以很好地确定用户是否可以使用触摸屏。Android 有一个您可以检查的功能,您的 Web 实现可以检查最大触摸点。

RPC 支持的策略更改适用于增量功能推出或以后可能更改的决策。

总结

#

使用 Capability 类定义代码 能够 做什么。您可以根据 API 的存在、操作系统强制的限制和物理硬件要求(如摄像头)进行检查。功能通常涉及编译时或运行时检查。

使用 Policy 类(根据复杂性而定)来定义代码 应该 做什么以遵守应用商店指南、设计偏好以及需要引用主机设备的资产或副本。策略可以混合使用编译时、运行时或 RPC 检查。

通过模拟功能和策略来测试分支代码,以便在功能或策略更改时无需更改小部件测试。

根据尝试分支的内容而不是设备类型来命名功能和策略类中的方法。