

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 分解單體的模式
<a name="decomposing-patterns"></a>

在您決定在應用程式產品組合中分解整體之後，您應該選擇適當的分解模式，並將其引入您的組織。

**注意**  
您可以使用多種模式來分解整體。例如，您可以依[業務能力](decompose-business-capability.md)分解整體，然後使用[子網域模式](decompose-subdomain.md)來進一步細分。

**Topics**
+ [依業務能力分解](decompose-business-capability.md)
+ [依子網域分解](decompose-subdomain.md)
+ [依交易分解](decompose-transactions.md)
+ [每個團隊模式的服務](service-per-team.md)
+ [Strangler 無花果模式](strangler-fig.md)
+ [依抽象模式分支](branch-by-abstraction.md)

# 依業務能力分解
<a name="decompose-business-capability"></a>

您可以使用組織的業務流程或功能來分解整體。*業務能力*是企業用來產生價值的方式 （例如，銷售、客戶服務或行銷）。一般而言，組織具有多種業務功能，這些功能因產業或產業而異。如果您的團隊充分了解組織的業務單位，而且您擁有每個業務單位的主題專家 (SMEs)，請使用此模式。下表說明使用此模式的優點和缺點。


****  

| 優點 | 缺點 | 
| --- | --- | 
|  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/modernization-decomposing-monoliths/decompose-business-capability.html) |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/modernization-decomposing-monoliths/decompose-business-capability.html) | 

在下圖中，保險體會根據業務功能分解為四個微服務。

![\[依業務功能分解整體\]](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/modernization-decomposing-monoliths/images/decompose-by-business-capability.png)


# 依子網域分解
<a name="decompose-subdomain"></a>

此模式使用[網域驅動設計 (DDD)](https://en.wikipedia.org/wiki/Domain-driven_design) 子網域來分解單體。此方法會將組織的網域模型細分為標示為*核心* （業務的關鍵差異因素）、*支援* （可能與業務相關，但與差異因素無關） 或*一般* （非業務特定） 的個別子網域。此模式適用於在子網域相關模組之間具有明確定義界限的現有單體系統。這表示您可以透過將現有模組重新封裝為微服務來分解整體，但不會大幅重寫現有程式碼。每個子網域都有一個模型，該模型的範圍稱為*邊界內容*。微服務是圍繞此邊界內容開發的。下表說明使用此模式的優點和缺點。


****  

| 優點 | 缺點 | 
| --- | --- | 
|  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/modernization-decomposing-monoliths/decompose-subdomain.html) | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/modernization-decomposing-monoliths/decompose-subdomain.html) | 

下圖顯示保險整體如何在由業務功能分解之後分解為子網域。

![\[依子網域分解整體\]](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/modernization-decomposing-monoliths/images/decompose-by-subdomain.png)


下圖顯示*銷售*和*行銷*服務細分為較小的微服務。*購買*和*宣告*模型是*銷售*的重要業務差異，並分為兩個單獨的微服務。透過使用*行銷活動*、*分析*和*報告*等支援的業務功能來分解*行銷*。

# 依交易分解
<a name="decompose-transactions"></a>

在分散式系統中，應用程式通常必須呼叫多個微服務才能完成一項商業交易。為了避免延遲問題或兩階段遞交問題，您可以根據交易將微服務分組。如果您認為回應時間很重要，且不同的模組在封裝之後不會建立整體，則此模式是適當的。下表說明使用此模式的優點和缺點。


****  

| 優點 | 缺點 | 
| --- | --- | 
|  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/modernization-decomposing-monoliths/decompose-transactions.html) |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/modernization-decomposing-monoliths/decompose-transactions.html)  | 

在下圖中，根據交易，保險整體分為多個微服務。

![\[依交易分解整體\]](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/modernization-decomposing-monoliths/images/decompose-by-transaction.png)


在保險系統中，索賠請求通常會在提交後標記給客戶。這表示如果沒有*客戶*微服務，就無法存在宣告服務。*銷售*和*客戶*封裝在一個微服務套件中，而商業交易需要與兩者協調。

# 每個團隊模式的服務
<a name="service-per-team"></a>

每個團隊模式的服務不會透過業務功能或服務分解整體，而是將其分解為由個別團隊管理的微服務。每個團隊都負責業務功能，並擁有該功能的程式碼庫。團隊獨立開發、測試、部署或擴展其服務，主要與其他團隊互動以交涉 APIs。建議您將每個微服務指派給單一團隊。不過，如果團隊夠大，多個子團隊可以在相同的團隊結構中擁有單獨的微服務。下表說明使用此模式的優點和缺點。


****  

| 優點 | 缺點 | 
| --- | --- | 
|  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/modernization-decomposing-monoliths/service-per-team.html)  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/modernization-decomposing-monoliths/service-per-team.html)  | 

下圖顯示單體如何分割為由個別團隊管理、維護和交付的微服務。

![\[團隊將整體分解為微服務\]](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/modernization-decomposing-monoliths/images/service-per-team.png)


# Strangler 無花果模式
<a name="strangler-fig"></a>

到目前為止，本指南中討論的設計模式適用於分解綠地專案的應用程式。涉及大型單體應用程式的布朗菲爾德專案呢？ 將先前的設計模式套用到它們會很困難，因為在主動使用它們時將其分成較小的部分是一項重大任務。

[ Strangler fig 模式](https://martinfowler.com/bliki/StranglerFigApplication.html)是由 Martin Fowler 引入的熱門設計模式，其受到特定類型的 fig 的啟發，該類 fig 會在樹的上分支中植入。現有的樹最初會成為新無花果的支援結構。 然後，該無花果會將其根傳送到地面，逐漸包圍原始樹狀結構，並只將新的自助式無花果留在原處。

此模式通常用於將特定功能取代為新服務，以累加方式將單體應用程式轉換為微服務。目標是讓舊版和新的現代化版本共存。新系統最初由現有系統支援並包裝。此支援可讓新系統有時間成長，並可能完全取代舊系統。

透過實作 strangler fig 模式，從單體應用程式轉換為微服務的程序包含三個步驟：轉換、共存和消除：
+ *轉換* – 透過與舊版應用程式平行移植或重寫這些元件，來識別和建立現代化元件。
+ *共存* – 保留整體應用程式以進行轉返。在整體周邊整合 HTTP 代理 （例如 [Amazon API Gateway](https://docs.aws.amazon.com/apigateway/latest/developerguide/welcome.html)) 以攔截外部系統呼叫，並將流量重新導向至現代化版本。這可協助您逐步實作功能。
+ *消除* – 從整體淘汰舊功能，因為流量會從舊版整體重新導向到現代化服務。

下表說明使用 strangler fig 模式的優點和缺點。


****  

| 優點 | 缺點 | 
| --- | --- | 
|  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/modernization-decomposing-monoliths/strangler-fig.html)  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/modernization-decomposing-monoliths/strangler-fig.html)  | 

下圖顯示如何透過將 strangler fig 模式套用至應用程式架構，將單體分割為微服務。這兩個系統都平行運作，但您會開始將功能移到整體程式碼基礎之外，並使用新功能增強功能。這些新功能讓您有機會以最符合您需求的方式架構微服務。您將繼續從整體中剔除功能，直到全部被微服務取代為止。此時，您可以消除整體應用程式。這裡要注意的重點是整體和微服務都會一起存活一段時間。

![\[使用 strangler fig 模式將整體分解為微服務\]](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/modernization-decomposing-monoliths/images/strangler-fig.png)


# 依抽象模式分支
<a name="branch-by-abstraction"></a>

當您可以在整體周邊攔截呼叫時，strangler fig 模式運作良好。不過，如果您想要將存在於舊版應用程式堆疊中更深且具有上游相依性的元件現代化，建議您依抽象模式來分支。此模式可讓您變更現有的程式碼基礎，讓現代化版本與舊版安全地共存，而不會造成中斷。

若要透過抽象模式成功使用分支，請遵循此程序：

1. 識別具有上游相依性的整合元件。

1. 建立抽象層，代表要現代化之程式碼與其用戶端之間的互動。

1. 當抽象化就位時，請將現有的用戶端變更為使用新的抽象化。

1. 使用整合之外的重做功能建立新的抽象實作。

1. 準備好時，將抽象概念切換到新實作。

1. 當新實作提供所有必要功能給使用者，且整體不再使用時，請清除較舊的實作。

依抽象模式劃分的分支通常與[功能切換](http://martinfowler.com/bliki/FeatureToggle.html)混淆，這也可讓您逐步變更系統。差別在於功能切換旨在允許開發新功能，並在系統執行時讓使用者看不到這些功能。因此，功能切換會在部署時間或執行時間使用，以選擇應用程式中是否顯示特定功能或一組功能。依抽象分割是一種開發技術，可與功能切換結合，以在舊實作和新實作之間切換。

下表說明依抽象模式使用分支的優點和缺點。


****  

| 優點 | 缺點 | 
| --- | --- | 
|  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/modernization-decomposing-monoliths/branch-by-abstraction.html)  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/modernization-decomposing-monoliths/branch-by-abstraction.html)  | 

下圖顯示保險體中*通知*元件的分支抽象模式。首先建立通知功能的摘要或界面。以小幅度遞增，現有用戶端會變更為使用新的抽象。這可能需要搜尋程式碼基底，以呼叫與*通知*元件相關的 APIs。您會建立通知功能的新實作，做為整體外部的微服務，並將其託管在現代化架構中。在整體中，您新建立的抽象界面充當中介裝置，並呼叫新的實作。以小幅度遞增，您可以將通知功能移植到新實作，直到完全測試並就緒為止，都會保持非作用中狀態。當新實作準備就緒時，您可以切換抽象以使用它。建議您使用可輕鬆翻轉的切換機制 （例如功能切換），以便在遇到任何問題時輕鬆切換回舊功能。當新的實作開始為您的使用者提供所有通知功能，且不再使用整體時，您可以清除舊的實作，並移除您可能已實作的任何切換功能旗標

![\[透過抽象模式使用分支將整體分解為微服務\]](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/modernization-decomposing-monoliths/images/branch-by-abstraction.png)
