打造可維護軟體C#版 第七章 以鬆散耦合的方式架構文件
第七章作者再提高層級,探討元件之間的耦合關係。元件有多個模組class所組成,C#中的元件是dll。
指導方針
頂層元件之間應該保持鬆散耦合
儘量減少目前模組要被呼叫的程式碼數量
獨立的元件有利於獨立的維護
本章處理元件層面的依賴關係。元件是系統頂層劃分的一部分,由系統的軟體架構定義。
元件層級的鬆散耦合稱為元件獨立,元件獨立的相反方向稱為元件依賴。
7.1 動機
元件內部的變更只影響元件本身時,系統更容易維護。
提升可維護性的調用分為兩種:
內部調用是健康的。
傳出調用也是健康的,因為他們將任務交給其他元件,產生向外的依賴性。(這個元件使用其他元件)
一個元件的傳出調用是另一個元件的傳入調用。
對可維護性有負面影響的調用包括:
傳入調用透過介面為其他元件提供功能性,相反地元件內的程式碼應當儘量封裝。(這個元件被其他元件使用)
透傳程式碼風險不小,透傳程式碼傳入調用,又委託其他元件。表示元件之間並未妥善劃分職責。
低度元件依賴容許獨立的維護
低依賴度意味可以獨立進行變更,這種情況發生在大多是內部調用或傳出調用。程式碼變更不會影響功能性修改範圍之外的程式碼。
低度元件依賴可以分離維護職責
低度元件依賴讓測試變容易
7.2 如何使用本指導方針?
下列要點可以幫助你運用本章原則:
限制擔任元件介面之模組的尺寸。
以高度抽象化的方式定義元件介面,這限制了跨元件邊界的請求類型,避免請求了解太多實作細節。
避免使用透傳調用程式碼,它對功能測試影響最嚴重。
抽象工廠設計模式
鬆散耦合的系統較多依賴契約contract,較少依賴細節實作。
抽象工廠設計模式將特定產品的建立封裝在通用的產品工廠介面背後,產品通常不只一種類型。
假設程式碼基礎包含PlatformServices的元件,它實作雲端主機平台的服務管理功能,這個元件支援兩個特定雲端主機提供者:Amazon AWS 和 Microsoft Azure ,以後會增加更多提供者。
為了啟動/停止伺服器以及保留儲存空間,我們必須為雲端主機平台實作以下介面:
public interface ICloudServerFactory
{
ICloudServer LaunchComputeServer();
ICloudServer LaunchDatabaseServer();
ICloudStorage CreateCloudStorage(long sizeGb);
}
基於這個介面,為AWS和Azure建立兩個特定的工廠類別:
public class AWSCloudServerFactory : ICloudServerFactory
{
public ICloudServer LaunchComputeServer()
{
return new AWSComputeServer();
}
public ICloudServer LaunchDatabaseServer()
{
return new AWSDatabaseServer();
}
public ICloudStorage CreateCloudStorage(long sizeGb)
{
return new AWSCloudStorage(sizeGb);
}
}
public class AzureCloudServerFactory : ICloudServerFactory
{
public ICloudServer LaunchComputeServer()
{
return new AzureComputeServer();
}
public ICloudServer LaunchDatabaseServer()
{
return new AzureDatabaseServer();
}
public ICloudStorage CreateCloudStorage(long sizeGb)
{
return new AzureCloudStorage(sizeGb);
}
}
這些工廠類別會調用特定的AWS和Azure實作類別,但針對伺服器和儲存機制回傳通用的介面型別。
PlatformServices元件之外的程式碼可以使用簡明的介面模組ICloudServerFactory ,例如:
public class ApplicationLauncher
{
public static void Main(string[] args)
{
ICloudServerFactory factory;
if (args[1].Equals("-azure"))
{
factory = new AzureCloudServerFactory();
}
else
{
factory = new AWSCloudServerFactory();
}
ICloudServer computeServer = factory.LaunchComputeServer();
ICloudServer databaseServer = factory.LaunchDatabaseServer();
}
}
PlatformServices 與 ICloudServerFactory 為其他元件提供小介面,元件與它形成鬆散耦合的關係。
範例中將特定雲端主機平台封裝到一個小型工廠介面之後。
7.3 常見的反對意見
反對意見:因為元件之間相互纏節,所以無法修正元件依賴
遇到糾結在一起的元件,可先分析透傳調用類型的模組。
反對意見:沒時間修正元件依賴
的確時間有限,重點在於權衡取捨,若是元件依賴會引發問題還是要解決。
反對意見:透傳調用是需求
有的軟體設計包含一個中間層,在這分層中,接收請求的模組有以下限制:
不應該處理請求本身。
不應該知道哪裡及如何處理請求,不知道實作細節。
中間層的接收模組有傳入請求和傳出請求,而不是將請求透傳給接收元件之中的某個特定模組。
7.4 參考
SIG如何評估元件獨立性
SIG將元件的鬆散耦合定義為元件獨立性。
為了釐清元件之間的依賴關係,需要區分隱藏程式碼和介面程式碼。
隱藏程式碼
隱藏程式碼由不含傳入依賴的模組構成,模組只能內部調用,或者調用所屬元件之外的其他模組(傳出調用)。
介面程式碼
介面程式碼由內含傳入依賴的模組所構成,包含具有傳入調用與透傳調用之模組程式碼。
留言
張貼留言