首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> C# >> C# 入門

用設計模式固化你的 C# 程式(四):Composite 組合模式

     編輯:C# 入門

前言

當需要以統一介面處理「部分-整體」階層結構時,Composite 模式讓客戶端程式碼無需區分單一物件與容器物件,大幅簡化遞迴結構的操作邏輯。

核心概念

  • Component (介面):定義葉節點與容器節點共同操作(如 Draw())。
  • Leaf (葉節點):無子節點的基本元素(如 Line、Circle)。
  • Composite (容器節點):包含子元素集合,實作操作時遞迴委派給子元素。

應用場景:繪圖應用程式

支援基本圖形與複合圖形(圖形群組)統一繪製。

C# 實作

using System;
using System.Collections.Generic;

// Component 介面
public interface IShape
{
    void Draw();
}

// Leaf: 直線
public class Line : IShape
{
    private readonly double _x1, _y1, _x2, _y2;

    public Line(double x1, double y1, double x2, double y2)
        => (_x1, _y1, _x2, _y2) = (x1, y1, x2, y2);

    public void Draw() => Console.WriteLine($"Drawing line ({_x1},{_y1}) -> ({_x2},{_y2})");
}

// Leaf: 圓形
public class Circle : IShape
{
    private readonly double _x, _y, _radius;

    public Circle(double x, double y, double radius)
        => (_x, _y, _radius) = (x, y, radius);

    public void Draw() => Console.WriteLine($"Drawing circle at ({_x},{_y}) radius {_radius}");
}

// Composite: 圖形群組
public class Drawing : IShape
{
    private readonly List _shapes = new();

    public void Add(IShape shape) => _shapes.Add(shape);

    public void Draw()
    {
        Console.WriteLine("Drawing group:");
        foreach (var shape in _shapes)
            shape.Draw(); // 遞迴委派
    }
}

客戶端使用:統一處理單一與群組圖形

public class Program
{
    public static void Main()
    {
        var shapes = new IShape[]
        {
            new Line(0, 0, 10, 10),
            new Circle(5, 5, 3),
            new Drawing 
            { 
                new Line(1, 1, 2, 2),
                new Circle(3, 3, 1.5)
            }
        };

        foreach (var shape in shapes)
            shape.Draw(); // 客戶端無需判斷型別
    }
}

輸出結果:

Drawing line (0,0) -> (10,10)
Drawing circle at (5,5) radius 3
Drawing group:
Drawing line (1,1) -> (2,2)
Drawing circle at (3,3) radius 1.5

進階:支援移除與子節點存取


public class Drawing : IShape
{
    private readonly List _shapes = new();

    public void Add(IShape shape) => _shapes.Add(shape);
    public void Remove(IShape shape) => _shapes.Remove(shape);
    public IShape GetChild(int index) => _shapes[index];

    public void Draw()
    {
        foreach (var shape in _shapes)
            shape.Draw();
    }
}

優缺點分析

優點缺點
簡化客戶端:統一介面處理樹狀結構設計過於通用:可能允許不合理的組合(如將圖形加入葉節點)
易於新增元件型別難以限制容器內容:需在執行時檢查或引入型別約束
符合開放封閉原則效能開銷:遞迴遍歷深層樹狀結構可能較慢

實務應用範例

  • 檔案系統:檔案與目錄統一介面(FileSystemInfo)。
  • UI 控制項樹:Control/ContainerControl (WinForms/WPF)。
  • 選單系統:選單項目與子選單。
  • 組織架構:員工與部門。

設計建議

  1. Component 介面盡量精簡,僅定義共同操作。
  2. Composite 類別內部集合建議使用 IList<T> 或 ICollection<T>。
  3. 若需限制子元素型別,可在 Add 方法加入型別檢查或使用泛型約束。
  4. 考慮實作 IEnumerable<IShape> 方便 LINQ 查詢。

總結

Composite 模式將「部分-整體」階層抽象為統一介面,讓客戶端程式碼免於處理遞迴邏輯與型別判斷。它是處理樹狀結構的基石模式。下一篇將介紹 State 狀態模式。

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