1. 程式人生 > >設計模式(十)外觀模式

設計模式(十)外觀模式

股民炒股程式碼?

第一個版本

程式碼結構圖:

具體股票、國債、房產類:

// 股票1:
class Stock1{
    // 賣股票
    public void Sell(){
        Console.WriteLine("股票1賣出");
    }

    // 買股票
    public void Buy{
        Console.WriteLine("股票1買入");
    }
}

// 股票2:
class Stock2{
    // 程式碼類似股票1  略
}

// 股票3:
class Stock3{
    // 程式碼類似股票1  略
}

// 國債1:
class NationalDebt1{
    // 程式碼類似股票1  略
}

// 房地產1:
class Realty1{
    // 程式碼類似股票1  略
}

客戶端呼叫:

static voiod Main(string[] args){
    Stock1 gu1 = new Stock1();
    Stock2 gu2 = new Stock2();
    Stock3 gu3 = new Stock3();
    NationalDebt1 nd1 = new NationalDebt1();
    Realty1 rt1 = new Realty1();

    // 使用者需要了解股票、國債、房產情況,
    // 需要參與這些專案的具體買和賣。耦合性很高
    gu1.Buy();
    gu2.Buy();
    gu3.Buy();
    nd1.Buy();   
    rt1.Buy();

    gu1.Sell();
    gu2.Sell();
    gu3.Sell();
    nd1.Sell();   
    rt1.Sell();

    Console.Read();    
}

投資基金程式碼

程式碼結構圖:

基金類如下:

class Fund{
    Stock1 gu1;
    Stock2 gu2;
    Stock3 gu3;
    NationalDebt1 nd1;
    Realty1 rt1;
    // 基金類,它需要了解所有的股票或其他投資方式的方法或屬性
    // 進行組合,以備外界呼叫
    public Fund(){
        gu1=new Stock1();
        gu2=new Stock2();
        gu3=new Stock3();
        nd1=new NationalDebt1();
        rt1=new Realty1();
    }
    public void BuyFund(){
        gu1.Buy();
        gu2.Buy();
        gu3.Buy();
        nd1.Buy();   
        rt1.Buy();
    }
    public void SellFund(){
        gu1.Sell();
        gu2.Sell();
        gu3.Sell();
        nd1.Sell();   
        rt1.Sell();
    }
}

客戶端如下:

static void Main(string[] args){
    Fund jijin = new Fund();

    // 此時使用者不需要了解股票,甚至可以對股票一無所知
    // 參與股票的具體買賣都由基金公司完成
    // 客戶端程式碼非常簡潔明瞭

    // 基金購買
    jijin.BuyFund();
    // 基金贖回
    jijin.SellFund();

    Console.Read();
}

外觀模式

外觀模式(Facade)為子系統中的一組介面提供一個一致的介面,此模式定義了一個高層介面,這個介面使得這一子系統更加容易使用。

class SubSystemOne{
    public void MethodOne(){
        Console.WriteLine("子系統方法一");
    }
}

class SubSystemTwo{
    public void MethodTwo(){
        Console.WriteLine("子系統方法二");
    }
}

class SubSystemThree{
    public void MethodThree(){
        Console.WriteLine("子系統方法三");
    }
}

class SubSystemFour{
    public void MethodFour(){
        Console.WriteLine("子系統方法四");
    }
}

外觀類:

class Facade{
    SubSystemOne one;
    SubSystemTwo two;
    SubSystemThree three;
    SubSystemFour four;

    // 外觀類,它需要了解所有的子系統的方法或屬性,進行組合,以備外界呼叫
    public Facade(){
        one = new SubSystemOne();
        two = new SubSystemTwo();
        three = new SubSystemThree();
        four = new SubSystemFour();
    }

    public void MethodA(){
        Console.WriteLine("\n方法組A() --- ");
        one.MethodOne();
        two.MethodTwo();
        four.MethodFour();
    }

    public void MethodB(){
        Console.WriteLine("\n方法組A() --- ");
        two.MethodTwo();
        three.MethodThree();
    }
}

客戶端呼叫:

static void Main(string[] args){
    Facade facade = new Facade();

    // 由於Facade的作用,客戶端可以根本不知三個子系統類的存在
    
    facade.MethodA();
    facade.MethodB();

    Console.Read();
}

外觀模式完美地體現了依賴倒轉原則和迪米特法則的思想。

那麼,外觀模式在什麼時候用最好呢?

首先,在設計初期階段,應該要有意識的將不同的兩個層分離,比如經典的三層架構,就需要考慮在資料訪問層和業務邏輯層、業務邏輯層表示層的層與層之間建立外觀Facade,這樣可以為複雜的子系統提供一個簡單的介面,使得耦合大大降低

其次,在開發階段,子系統往往因為不斷的重構演化而變得越來越複雜,大多數的模式使用時也都會產生很多很小的類,這本是好事,但也給外部呼叫它們的使用者程式帶來了使用上的困難,增加外觀Facade可以提供一個簡單的介面,減少它們之間的依賴

第三,在維護一個遺留的大型系統時,可能這個系統已經非常難以維護和擴充套件了,但因為它包含非常重要的功能,新的需求開發必須要依賴於它。此時用外觀模式Facade也是非常合適的。你可以為新系統開發一個外觀Facade類,來提供設計粗糙或高度複雜的遺留程式碼的比較清晰簡單的介面,讓新系統與Facade物件互動,Facade與遺留程式碼互動所有複雜的工作

本章完。

------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 本文是連載文章,此為第十章,學習為子系統中的一組介面提供一個一致的介面的外觀模式。

下一章:

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------