功能與政策
瞭解如何使您的應用適應平臺、應用商店、公司等所要求的各項能力與策略。
大多數實際應用都需要適應不同裝置和平臺的能力與策略。本頁面提供了在程式碼中處理這些場景的建議。
根據每種裝置型別的優勢進行設計
#考慮不同裝置的獨特優勢與劣勢。除了螢幕尺寸和輸入方式(如觸控、滑鼠、鍵盤)之外,您還可以利用哪些其他獨特能力?Flutter 使您的程式碼能夠執行在不同的裝置上,但優秀的設計不僅僅是讓程式碼跑起來。請思考每個平臺最擅長的是什麼,並看看是否有可以利用的獨特能力。
例如:Apple 的 App Store 和 Google 的 Play Store 有不同的應用準則。不同的宿主作業系統隨著時間的推移以及彼此之間,其能力也在不斷變化。
另一個例子是利用 Web 極低的共享門檻。如果您要部署一個 Web 應用,請確定要支援哪些深層連結(Deep Links),並據此設計導航路由。
針對這些獨特能力處理不同行為時,Flutter 推薦的模式是為您的應用建立一套 Capability(能力)和 Policy(策略)類。
能力
#能力(Capability)定義了程式碼或裝置能夠做什麼。能力的例子包括:
- API 的存在性
- 作業系統強制的限制
- 物理硬體需求(如攝像頭)
策略
#策略(Policy)定義了程式碼應該做什麼。
策略的例子包括:
- 應用商店指南
- 設計偏好
- 引用宿主裝置的資源或文案
- 伺服器端啟用的功能
如何構建策略程式碼
#最簡單的機械式實現方法是使用 Platform.isAndroid、Platform.isIOS 和 kIsWeb。這些 API 可以機械地讓您知道程式碼正在何處執行,但隨著應用可執行範圍的擴大以及宿主平臺功能更新,這種方式會帶來一些問題。
以下指南闡述了在為應用開發能力和策略時的最佳實踐:
避免使用 Platform.isAndroid 及類似函式來進行佈局決策或對裝置能力做出假設。
相反,應在方法中描述您想要分支處理的邏輯。
示例:您的應用在網站中有一個購買連結,但出於策略原因,您不希望在 iOS 裝置上顯示該連結。
bool shouldAllowPurchaseClick() {
// Banned by Apple App Store guidelines.
return !Platform.isIOS;
}
...
TextSpan(
text: 'Buy in browser',
style: new TextStyle(color: Colors.blue),
recognizer: shouldAllowPurchaseClick ? TapGestureRecognizer()
..onTap = () { launch('<some url>') : null;
} : null,
透過增加一層間接性,您得到了什麼?程式碼更加清晰地說明了為什麼存在該分支路徑。此方法可以直接存在於類中,但很可能程式碼的其他部分也需要進行相同的檢查。如果是這樣,請將該程式碼放入一個專門的類中。
class Policy {
bool shouldAllowPurchaseClick() {
// Banned by Apple App Store guidelines.
return !Platform.isIOS;
}
}
將此程式碼放在類中後,任何 Widget 測試都可以 Mock 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 檢查的組合。
透過 Mock 能力和策略來測試分支程式碼,這樣當能力或策略發生變化時,Widget 測試無需更改。
在命名能力和策略類的方法時,應基於它們試圖進行分支處理的邏輯含義,而不是基於裝置型別。