邁向架構師的暖身運動(1):介面導向設計

介面導向設計(interface-oriented design) 在軟體架構設計中,是一個必修的技能,不過在整個軟體架構領域中,它只是個入門磚而已,沒有它,想要做好軟體架構是很困難的,原因只有一個:它是基礎。

平常在書上看到,或是前輩(老師)在講,好的軟體設計必須要具備彈性(flexible)與擴充性(extensible),如果軟體設計的不夠彈性,那麼在程式設計師重覆使用軟體元件時,很容易就會發生卡住,以及在需求變更時無法自行設計或開發相容的元件,也就是不具彈性。通常彈性和擴充性是相輔相成的,沒有彈性也代表著沒有擴充性。

在實務上,我想只要是有寫過程式的人,或多或少都會知道 OOP (Object-Oriented Programming) 這個玩意,不論你是用 C++, Java, VB 或是 PHP,然而知易行難,要學會如何使用類別很容易,但要學會如何擴充類別,尤其是具有彈性的類別就不容易了,除了要對 OOP 本身的概念夠了解,也需要有一些藝術家的思維,畢竟軟體設計在某種程度上,和設計師一樣,需要投以藝術的眼光的,而沒有基本的底子,可能連它是什麼都看不出來,這在軟體元件設計上也是一樣的。

也許你曾經聽過元件為主的設計(Component-Based Design;CBD),它是將軟體功能塑模並發展成一個一個的元件,然後將這些元件組合一套軟體或應用系統,並且各個元件都可以各自延伸以客制自己需要的功能。不過說起來容易,要做起來還真的不是普通的困難,因為若要做到這樣的情境,你的設計必須:

  • 模組本身要具有可擴充性,可以依需要衍生使用。
  • 模組間必須要可以橋接,並且可以相互維持並發揮功能。
  • 如果需要,模組必須可以由兩種以上的程式語言使用。

CBD 的概念已經被廣泛運用在軟體工業,並且由各大軟體廠商所實作,像 CORBA 和微軟的 COM 模型,都是試圖讓開發人員實作出具有 CBD 能力的元件模組,並且能夠有一個標準的平台組合元件以產出軟體成品,雖然它們本身組成的結構都很複雜 (尤其是 COM),不過它們都有一個相同的東西:介面。介面 (interface)  是軟體元件之間的規則,可以定義:

  • 相似的模組必須要遵守的規範。
  • 橋接元件時的標準。

介面導向設計 (interface-oriented design) 是一種以介面定義基本規範,並且遵循介面定義實作模組的一種設計方法,使用這種方式設計,不但模組本身具有一定的規範,使用模組的應用程式也有可以一定使用它的方法,而且只要依循介面的定義,軟體工程師可以實作出自己的模組,而不需要綁在特定的模組或平台中,也不必改動使用它的應用程式,因為使用它的應用程式是使用介面來呼叫,而不是使用類別呼叫。

例如,某個資料庫元件需要有 CRUD (Create/Retrive/Update/Delete) 四功能,但為了要相容於不同的資料庫,因此我們可以定義一個介面:

public interface IDataProvider
{
      void Create(Dictionary<string, object> DataList);
      void Update(object Key, Dictionary<string, object> DataList);
      void Delete(object Key);
      List<Dictionary<string, object>> Select();
      Dictionary<string, object> Select(object Key);    
}

然後就可以針對不同的資料庫來實作:

public class MssqlProvider : IDataProvider
{
    ....
}
public class MysqlProvider : IDataProvider
{
    ....
}
public class OracleProvider : IDataProvider
{
    ....
}
public class DB2Provider : IDataProvider
{
    ....
}

而前端使用的應用程式,只需要載入要存取的資料庫的模組,然後直接取用介面即可:

IDataProvider provider = Activator.CreateInstance(typeof(MysqlProvider)) as IDataProvider;
List<Dictionary<string, object>> dataList = provider.Select();

以介面來設計元件,最大的好處就是可以降低元件與用戶端之間的藕合性,這樣在抽換模組時用戶端應用程式可以連動都不用動,省下為更改資料庫所要耗費的重覆工作。

在現代很多的軟體架構中,介面是隨處可見的,尤其是在具有一定規模的軟體中,像是 SharpDevelop 這套 Open Source 的 IDE,用介面的地方非常的多,而像是 WCF (Windows Communication Foundation) 也規定要利用 WCF 做通訊的物件,也一定要使用介面來宣告,介面在軟體中,其實就是一種合約 (contract),它規範了用戶端與模組必須要遵守的規範,沒有依照它的宣告的話,就無法使用軟體(在設計時,光編輯這一道程序就不會讓你過)。

因此,在設計嚴謹的軟體架構或 Framework (尤其是做為基底服務的)中,介面是絕對必要,也是絕對核心的基本構成要件之一,學會與習慣使用介面來規劃與設計模組,是架構師必備的技能之一,同時它也是基本功,沒有搞定它的話,是無法成為稱職的軟體架構師的。