首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C# 設計模式深度解析:組合模式(Composite Pattern)的透明與安全實現

     編輯:關於C語言

在軟件開發中,經常需要處理「部分-整體」的樹形結構:如文件系統(文件/文件夾)、UI 控件樹、圖形編輯器(基本圖形/復合圖形)。客戶端希望統一介面操作單個對象與組合對象,避免充斥 if (isLeaf) ... else ... 的分支判斷。組合模式正是為此而生。

核心定義

組合模式允許你將對象組合成樹形結構來表現「部分-整體」的層次結構,使得客戶以一致的方式處理單個對象以及對象的組合。

關鍵在於:葉子節點與容器節點實現相同的抽象介面(Component)。

兩種實現風格

1. 透明式組合模式

在抽象基類 Component 中聲明 Add/Remove/GetChild 等管理方法。葉子類繼承後拋出異常或空實現。

  • 優點:客戶端完全面向抽象編程,無需區分葉子與容器。
  • 缺點:葉子類擁有無意義的方法,違反「介面隔離原則」,運行時才能發現錯誤。

2. 安全式組合模式

僅在容器類 Composite 中聲明管理方法,葉子類 Leaf 不包含這些方法。

  • 優點:編譯期即可捕獲錯誤調用,類職責單一。
  • 缺點:客戶端需區分葉子與容器類型(或強制轉型),失去完全透明性。

C# 代碼示例:圖形編輯器

透明式實現

// 抽象構件
public abstract class Graphics {
    public string Name { get; set; }
    public Graphics(string name) { Name = name; }
    public abstract void Draw();
    public abstract void Add(Graphics g);
    public abstract void Remove(Graphics g);
}

// 葉子:直線
public class Line : Graphics {
    public Line(string name) : base(name) { }
    public override void Draw() => Console.WriteLine("畫 " + Name);
    public override void Add(Graphics g) => throw new Exception("不能向簡單圖形添加");
    public override void Remove(Graphics g) => throw new Exception("不能向簡單圖形移除");
}

// 葉子:圓
public class Circle : Graphics { /* 類似 Line */ }

// 容器:復雜圖形
public class ComplexGraphics : Graphics {
    private List children = new List();
    public ComplexGraphics(string name) : base(name) { }
    public override void Draw() => children.ForEach(g => g.Draw());
    public override void Add(Graphics g) => children.Add(g);
    public override void Remove(Graphics g) => children.Remove(g);
}

安全式實現

// 抽象構件:移除管理方法
public abstract class Graphics {
    public string Name { get; set; }
    public Graphics(string name) { Name = name; }
    public abstract void Draw();
}

// 葉子:無 Add/Remove
public class Line : Graphics { /* ... */ }
public class Circle : Graphics { /* ... */ }

// 容器:擁有管理方法
public class ComplexGraphics : Graphics {
    private List children = new List();
    public void Add(Graphics g) => children.Add(g);
    public void Remove(Graphics g) => children.Remove(g);
    public override void Draw() => children.ForEach(g => g.Draw());
}

UML 類圖關係

三大角色:

  • Component(抽象構件):定義公共介面,透明式中包含管理方法。
  • Leaf(葉子構件):無子對象,實現具體行為(如 Draw)。
  • Composite(容器構件):擁有子對象集合,實現管理方法,Draw 遞歸調用子對象。

透明式組合模式類圖 安全式組合模式類圖

優缺點與注意事項

優點缺點
  • 客戶端代碼簡潔,統一處理單個/組合對象
  • 解耦客戶代碼與複雜對象容器結構
  • 易於添加新構件類型
  • 設計較複雜,需理清層次關系
  • 透明式違反介面隔離;安全式失去透明性

最佳實踐:

  1. 頻繁遍歷樹結構時,考慮在父節點緩存遍歷結果。
  2. 客戶端盡量使用 Component 多態調用,避免直接實例化具體葉子類。

.NET 框架中的應用

System.Windows.Forms.Control 正是透明式組合模式的經典應用:Label、TextBox 為葉子;GroupBox、Panel 為容器,均繼承 Control 並實現 OnPaint 遞歸繪製。

適用場景

  • 需要表示對象「整體-部分」層次結構。
  • 希望用戶忽略組合對象與單個對象的差異,統一調用。

組合模式將客戶程序與複雜元素內部結構解耦,使客戶程序能像處理簡單元素一樣處理複雜元素,是構建靈活可擴展樹形結構的利器。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved