程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> .NET實例教程 >> C#面向對象設計模式縱橫談 學習筆記9 Composite 組合(結構型模式)

C#面向對象設計模式縱橫談 學習筆記9 Composite 組合(結構型模式)

編輯:.NET實例教程

在我們開發過程中,我們可能需要用到一種設計,一個容器可以包含一個對象,並且也可以包含一個容器,我們需要通過一個接口或一個抽象類來表示這個容器或對象,也就是說容器或對象是同一總類型,但是包含關系,也就是說我們需要用一種模式來實現多叉樹的結構。節點可以包含字節點,也可以包含子項。

我們可以通過Composite模式來實現。

首先看看Composite模式的動機:

如何將"客戶代碼與復雜的對象容器結構"解耦?讓對象容器自己來實現自身的復雜結構,從而使得客戶代碼就像處理簡單對象一樣來處理復雜的對象容器?

Composite模式的意圖:

將對象組合成樹形結構以表示"部分-整體"的層次結構。Composite使得用戶對單個對象和組合對象的使用具有一致性。

看看實現的代碼



public interface IBox
...{
    void Process();
    void Add(IBox box);
    void Remove(IBox box);
}

這是一個接口,它定義了對象和容器應該需要實現的方法,在這個接口裡Add和Remove方法是對象不需要實現的,可以在實現這兩個方法是拋出異常,或者為空方法。



public class SingleBox : IBox
...{
    public void Process
    ...{
        
    }

    public void Add(IBox box)
    ...{
        throw new Exception();
    }

    public void Remove(IBox box)
...{
        throw new Exception();
    }
}

這是對象類的定義,它僅僅實現過了Process方法,表明這個對象需要處理的工作。



public class ContainerBox : IBox
...{
    ArrayList list = null;

    public ContainerBox()
    ...{
        list = new ArrayList();
    }

    public void Add(IBox box)
    ...{
        list.Add(box);
    }

    public void Remove(IBox box)
...{
        list.Remove(list);
    }

    public void Process()
    ...{
        //1.Do Something for myself

        //2.Do process for the box in the list
        foreach (IBox box in list)
        ...{
            box.Process();
        }
    }
}

這是容器的實現代碼在Add和Remove方法中,我們可以添加實現了IBox接口的對象或容器,在Process方法中,我們依次調用IBox接口的Process方法將每個Box處理一次。

那麼我們在客戶程序可以像如下代碼一樣使用



static void Main(string[] args)
...{
    IBox box = Factory.GetBox();

    box.Add(new SingleBox());

    IBox box1 = Factory.GetBox();

    box1.Add(box);

    box1.Process();
}

可以說我們在容器的Process方法裡實現了遞歸。

Composite模式的幾個要點:

  • Composite模式采用樹形結構來實現普遍存在的對象容器,從而將"一對多"的關系轉化為"一對一"的關系,使得客戶代碼可以一致地處理對象和對象容器,無需關心處理的是單個的對象,還是組合的對象容器。
  • 將"客戶代碼與復雜的對象容器結構"解耦是Composite模式的核心思想,解耦之後,客戶代碼將與純粹的抽象接口--而非對象容器的復內部實現結構--發生依賴關系,從而更能"應對變化"。
  • Composite模式中,是將"Add和Remove等和對象容器相關的方法"定義在"表示抽象對象的Component類"中,還是將其定義在"表示對象容器的Composite類"中,是一個關乎"透明性"和"安全性"的兩難問題,需要仔細權衡。這裡有可能違背面向對象的"單一職責原則",但是對於這種特殊結構,這又是必須付出的代價。ASP.Net控件的實現在這
    方面為我們提供了一個很好的示范。
  • Composite模式在具體實現中,可以讓父對象中的子對象反向追溯;如果父對象有頻繁的遍歷需求,可使用緩存技巧來改善效率。

Composite模式普遍用於控件中,如控件可以是容器,但是控件也可以被另外一個控件加入,那麼另外一個控件也是一個容器。在ASP.Net中也是如此。如果我們將IBox接口看作Control接口,Process方法改為Render方法,就是繪制自己。那麼我們會發現,我們把控件慢慢的組合成樹,然後使用樹的根節點的Render方法,那麼我們就將控件容器下的控件和控件容器都Render出來了。

在Asp.Net中Control是使用ControlCollection來實現的,那麼它是通過在IBox接口裡添加一個Box屬性,返回值為IBox,那麼我們對象實現這個接口的時候,get訪問器可以返回為空。這就是ASP.Net控件給我們提供的很好的示范。如何來權衡透明性和安全性。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved