> ## Documentation Index
> Fetch the complete documentation index at: https://meta.niceshare.site/llms.txt
> Use this file to discover all available pages before exploring further.

# 關注點分離

> 關注點分離（SoC）是一種將軟體劃分為不同模組，每個模組處理特定關注點的設計原則。了解其起源、優勢以及如何應用。

<Info>
  **類別**: 原則<br />
  **類型**: 軟體架構原則<br />
  **來源**: Edsger W. Dijkstra，1974<br />
  **別名**: SoC，關注點分離
</Info>

<Note>
  **快速回答** — 關注點分離（Separation of
  Concerns，SoC）是一種將軟體系統劃分為不同部分，每個部分處理各自獨立關注點的設計原則。由Edsger
  W.
  Dijkstra於1974年提出，這一原則是現代軟體架構的基石，能夠實現複雜系統的可維護性、可擴展性和清晰性。
</Note>

## 什麼是關注點分離？

關注點分離是一種將軟體系統分解為不同模組的實踐，每個模組處理一個特定的關注點。「關注點」是指系統中任何感興趣的領域或職責——如業務邏輯、資料持久化、使用者介面、安全或網路。透過隔離這些關注點，開發者可以獨立處理各個部分而不影響其他部分。

> 「關注點分離是前進的唯一途徑。」 — Edsger W. Dijkstra

這一原則源於Dijkstra 1974年的論文《論科學思維的作用》，他在文中指出人腦一次只能容納有限的資訊。透過將問題分解為不同的關注點，我們使其變得易於人類理解和處理。

在現代軟體開發中，SoC體現在各個層面。在最高層級，你可能會將展示層與業務邏輯層分開。在模組層級，你可能會將資料存取與領域邏輯分開。在函數層級，你可能會將純計算與副作用分開。每一層都有明確的職責，透過定義良好的介面與其他層互動。

### 關注點分離的三個層次

* **入門**: 識別任何程式碼中不同的關注點。如果你的使用者介面程式碼中包含SQL查詢，那就是關注點的混合。將每個關注點移到它自己的位置。
* **實踐**: 使用強制執行SoC的架構模式，例如用於Web應用程式的模型-視圖-控制器（MVC）或用於企業系統的分層架構。
* **進階**: 在組織層面應用關注點分離。康威定律表明，系統設計往往反映溝通結構。按關注點組織團隊，以實現並行開發並減少協調開銷。

## 起源

「關注點分離」一詞由Edsger W. Dijkstra引入，他是歷史上最有影響力的電腦科學家之一。在1974年的散文《論科學思維的作用》中，Dijkstra討論了人類認知的局限性，以及將問題分解為可管理的部分對於應對複雜性至關重要。

Dijkstra的見解早於現代軟體工程，但隨著軟體系統變得越來越複雜，它變得越來越重要。在接下來的幾十年中，SoC被嵌入眾多架構模式中：1970年代的模組化程式設計、1980年代的物件導向設計、2000年代的服務導向架構，以及2010年代的微服務。

該原則也連接了更廣泛的政治哲學中的「三權分立」概念——正如民主政府將立法、行政和司法權力分開以防止權力集中，軟體系統也分離關注點以防止複雜性變得無法管理。

## 核心要點

<Steps>
  <Step title="提升可理解性">
    當每個模組處理一個關注點時，開發者可以理解和處理各個部分，而無需掌握整個系統。
  </Step>

  <Step title="支援並行開發">
    良好分離的關注點允許不同的開發者或團隊同時工作，而不會相互干擾彼此的進度。
  </Step>

  <Step title="便於測試">
    隔離的關注點可以獨立測試。你可以單獨對業務邏輯進行單元測試，而不需要使用者介面、資料庫或網路連線。
  </Step>

  <Step title="降低變更影響">
    當某個關注點發生變化時，其影響是局部的。對使用者介面的修改不需要修改業務邏輯。
  </Step>
</Steps>

## 應用場景

<CardGroup cols={2}>
  <Card title="分層架構">
    將程式碼組織成層（展示層、業務邏輯層、資料存取層）。每層有特定的角色，透過介面與相鄰層通訊。
  </Card>

  <Card title="元件設計">
    圍繞特定職責設計軟體元件。支付元件處理支付；通知元件處理通知。
  </Card>

  <Card title="函數式編程">
    將純函數（無副作用）與非純函數（I/O、狀態變更）分離。這使程式碼更容易理解和測試。
  </Card>

  <Card title="橫切關注點">
    使用面向切面程式設計等技術來處理影響系統多個部分的關注點，如日誌或安全，而不會污染業務程式碼。
  </Card>
</CardGroup>

## 經典案例

2000年代初，一個大型電子商務平台艱難應對一個單體程式碼庫，業務邏輯、資料庫查詢和HTML範本交織在相同的PHP檔案中。一個由五名開發者組成的團隊管理著數千個檔案，但由於破坏無關功能的風險，新增功能需要數月時間。

該公司採用了模型-視圖-控制器（MVC）架構，這強制在資料（模型）、展示（視圖）和邏輯（控制器）之間進行分離。他們還實現了一個獨立的資料存取層。

結果改變了開發速度。原先需要三個月的新功能在三週內就能交付。開發者可以專業化——一些人專注於使用者體驗，另一些人專注於業務規則——而不會互相干擾。平台可以擴展，因為每個關注點都可以獨立優化或替換：他們從關聯式資料庫切換到NoSQL來儲存產品目錄，而無需觸及展示層。

這個案例展示了SoC的力量：透過圍繞不同關注點組織程式碼，曾經的瓶頸變成了一個可擴展、可維護的系統。

## 邊界與失效場景

最常見的失敗是建立不符合實際關注點的人為邊界。沒有邏輯理由地將程式碼分成不同的檔案或模組會增加複雜性而沒有好處。關注點應該基於*變更理由*來分離——因不同原因變更的事物應該放在不同的地方。

另一個陷阱是過度分離，當管理多個模組的成本超過收益時。如果兩個關注點總是同時發生變化，將它們放在一起通常更合理。

邊界條件：當收益——降低複雜性、並行開發、可測試性——超過建立和維護分離的成本時，才應用SoC。從粗粒度的分離開始，隨著模式的出現再細化。

## 常見誤區

<AccordionGroup>
  <Accordion title="誤區：SoC意味著更多檔案">
    分離不是關於建立更多檔案——而是關於邏輯組織。你可以透過清晰的命名和結構在同一檔案內實現分離，儘管單獨的檔案通常更清晰。
  </Accordion>

  <Accordion title="誤區：SoC只適用於程式碼">
    該原則延伸到程式碼之外。你可以在系統架構、API設計、文件甚至組織結構中分離關注點。
  </Accordion>

  <Accordion title="誤區：SoC消除複雜性">
    分離管理複雜性但不消除它。系統仍然具有相同的總複雜性；SoC透過將其分布在專注的模組中，使其更容易被人類理解。
  </Accordion>
</AccordionGroup>

## 相關概念

關注點分離與其他基本軟體設計原則密切相關：

<CardGroup cols={3}>
  <Card title="單一職責原則">
    SoC和SRP密切相關。SRP通常被認為是在類別和函數層面實現SoC的方式。
  </Card>

  <Card title="模組化">
    模組化是SoC的實際應用，建立具有明確定義介面的自包含模組。
  </Card>

  <Card title="內聚性">
    內聚性衡量單個模組的職責之間關聯程度。模組內的高內聚性與SoC相輔相成。
  </Card>
</CardGroup>

## 一句話總結

<Tip>
  **根據不同的職責領域將系統劃分為模組——每個關注點都有自己的位置，使整個系統更容易理解、开发和維護。**
</Tip>
