# 原則{#principles}

本頁說明了 Tuist 設計和發展的支柱原則。這些原則與專案一同演進，旨在確保與專案基礎保持一致的可持續發展。

## 預設為慣例{#default-to-conventions}

Tuist 存在的原因之一是因為 Xcode 在常規方面較弱，這導致複雜的專案難以擴充與維護。因此，Tuist
採取了不同的方式，預設為簡單且設計徹底的慣例。**開發人員可以選擇不使用這些慣例，但這是一個有意識的決定，感覺並不自然。**

例如，透過使用所提供的公共介面來定義目標之間的依賴關係是一種慣例。這樣一來，Tuist
就能確保專案是以正確的組態產生，以便進行連結。開發人員可以選擇透過建立設定來定義依賴關係，但他們會以隱含的方式來做，因此會破壞 Tuist
的功能，例如`tuist graph` 或`tuist cache` ，這些功能都需要依循某些慣例。

我們之所以預設使用慣例，是因為我們能代表開發人員做的決定越多，他們就越能專注於為應用程式製作功能。當我們在許多專案中都沒有慣例時，我們就必須做出與其他決策不一致的決策，結果就會產生難以管理的意外複雜性。

## 表現是真理的來源{#manifests-are-the-source-of-truth}

有許多層的組態和它們之間的契約會導致專案設定難以推理和維護。試想一下一般的專案。專案的定義在`.xcodeproj` 目錄中，CLI 在腳本中
(例如`Fastfiles`)，而 CI
邏輯則在管道中。這是三個層級，我們需要維護它們之間的契約。*您有多少次遇到這樣的情況：您在專案中改變了一些東西，但一週之後您發現釋出的腳本毀了？*

我們可以透過單一真相來源 (即艙單檔案) 來簡化這個問題。這些檔案提供 Tuist 所需的資訊，讓它可以產生開發人員可用來編輯檔案的 Xcode
專案。此外，它允許從本機或 CI 環境建立專案的標準指令。

**Tuist 應該擁有複雜性，並揭露一個簡單、安全且愉快的介面，儘可能明確地描述他們的專案。**

## 讓隱性變得明確{#make-the-implicit-explicit}

Xcode 支援隱含的配置。一個很好的例子就是推斷隱含定義的相依性。雖然隱含配置對於配置簡單的小型專案來說沒問題，但隨著專案變大，它可能會導致緩慢或奇怪的行為。

Tuist 應該為隱含的 Xcode 行為提供明確的 API。它還應該支援定義 Xcode 隱含性，但實現方式應鼓勵開發人員選擇顯式方法。支持 Xcode
隱含性和複雜性有助於 Tuist 的採用，之後，團隊可以花一些時間來擺脫隱含性。

相依性的定義就是一個很好的例子。雖然開發人員可以透過建立設定和階段來定義依賴關係，但 Tuist 提供了美觀的 API 來鼓勵採用。

**將 API 設計成明確的，可以讓 Tuist 在專案上執行一些檢查和最佳化，否則是不可能的。** 此外，它還能實現一些功能，例如`tuist graph`
，它可以匯出依賴圖的表示，或`tuist cache` ，它可以將所有目標緩存為二進檔。

> [!TIP]
> 我們應該將從 Xcode 移植功能的每個請求都視為一個機會，藉由簡單且明確的 API 來簡化概念。


## 保持簡單{#keep-it-simple}

在擴充 Xcode 專案時，其中一個主要的挑戰來自於**Xcode 暴露了許多複雜性給使用者。**
正因為如此，團隊的總線因素很高，團隊中只有少數人瞭解專案以及建立系統所丟出的錯誤。這是一個很糟糕的情況，因為團隊只依賴幾個人。

Xcode 是一個很棒的工具，但這麼多年來的改進、新的平台和程式語言，都反映在其表面上，它努力保持簡單。

Tuist
應該把握機會讓事情簡單化，因為從簡單的事情做起會很有趣，也能激勵我們。沒有人想花時間去調試一個發生在編譯過程最後的錯誤，或是了解為什麼他們無法在裝置上執行應用程式。Xcode
將這些任務委託給其底層的建立系統，在某些情況下，它無法將錯誤轉譯為可執行的項目。您是否遇到過*"framework X not found"*
錯誤，卻不知道該怎麼辦？試想一下，如果我們得到一份錯誤的潛在根本原因清單。

## 從開發人員的經驗開始{#start-from-the-developers-experience}

Xcode 缺乏創新的部分原因，或者換句話說，不如其他程式設計環境，是因為**我們經常從現有的解決方案開始分析問題。**
因此，我們現在發現的大多數解決方案都圍繞著相同的想法和工作流程。將現有的解決方案包含在方程式中固然是件好事，但我們不該讓它們束縛了我們的創意。

我們喜歡像 [Tom Preston](https://tom.preston-werner.com/) 在
[這個播客](https://tom.preston-werner.com/)中說的那樣：*"大多數的事情都是可以實現的，只要在宇宙的限制下，你腦子裡想的東西都可以用程式碼來實現。*
如果**，我們想像開發人員的體驗是** ，那麼實現它只是時間的問題 -
從開發人員的體驗開始分析問題，會給我們一個獨特的觀點，讓我們找到使用者喜歡使用的解決方案。

我們可能會想跟隨大家的做法，即使這意味著要忍受大家不斷抱怨的不便。我們不要這樣做。我如何想像將我的應用程式歸檔？我希望程式碼簽章是什麼樣子？我可以用 Tuist
協助簡化哪些流程？舉例來說，增加對 [Fastlane](https://fastlane.tools/)
的支援是一個解決問題的方法，我們需要先了解這個問題。我們可以透過詢問「為什麼」的問題來找出問題的根源。一旦我們縮小動機的來源，我們就可以思考Tuist如何幫助他們。也許解決方案是與
Fastlane 整合，但重要的是，在做出取捨之前，我們不要忽略其他同樣有效的解決方案。

## 錯誤可能會發生{#errors-can-and-will-happen}

我們，開發人員，有一種固有的誘惑，漠視錯誤可能發生。因此，我們在設計和測試軟體時只會考慮理想的情況。

Swift、它的類型系統以及結構良好的程式碼可能有助於避免某些錯誤，但不是所有錯誤，因為有些錯誤是我們無法控制的。我們無法假設使用者永遠都有網際網路連線，或是系統指令會成功傳回。Tuist運行的環境並不是我們所能控制的沙盒，因此我們需要努力了解它們可能會如何改變和影響Tuist。

錯誤處理不善會導致不良的使用者經驗，使用者可能會失去對專案的信任。我們希望使用者能享受 Tuist 的每一件產品，甚至是我們向他們呈現錯誤的方式。

我們應該站在使用者的角度，想像我們期望錯誤告訴我們什麼。如果程式語言是錯誤傳播的溝通管道，而使用者是錯誤的目的地，則應該以目標 (使用者)
所使用的語言來撰寫錯誤。它們應該包含足夠的資訊來知道發生了什麼事，並隱藏不相干的資訊。此外，它們應該是可操作的，告訴使用者可以採取哪些步驟來恢復錯誤。

最後，我們的測試案例應該考慮失敗的情況。這不僅能確保我們按照應有的方式處理錯誤，還能防止未來的開發人員破壞邏輯。
