カテゴリ: C# 更新日: 2026/07/20

C#のコンポジットパターン完全攻略!木構造データを管理する設計術

C#のコンポジットパターンで木構造データを扱う例を紹介
C#のコンポジットパターンで木構造データを扱う例を紹介

先生と生徒の会話形式で理解しよう

生徒

「C#でフォルダーの中にフォルダーがあるような、木のような構造データを扱うにはどうすればいいですか?」

先生

「C#のデザインパターンの一つである、コンポジットパターンを使うと非常にスッキリと管理できますよ。」

生徒

「コンポジットパターンって何ですか?難しそうですが、どういう仕組みか教えてください。」

先生

「大丈夫です。整理整頓の例えを使って、基本から一緒に見ていきましょう。」

1. コンポジットパターンとは何か

1. コンポジットパターンとは何か
1. コンポジットパターンとは何か

コンポジットパターンとは、一言でいえば「入れ物」と「中身」を同じ種類のものとして扱うための設計テクニックです。プログラミングの現場では、デザインパターンという、先人が見つけた「使いやすい設計の型」の一つとして知られています。このパターンを使うと、複雑な構造であっても、まるで単純な一つのアイテムであるかのように操作できるのが特徴です。

例えば、パソコンのフォルダーをイメージしてください。フォルダーの中には、ファイルが入っていることもあれば、さらに別のフォルダーが入っていることもありますよね。この「フォルダーの中にフォルダーがある」という構造を木構造と呼びます。コンポジットパターンを使うと、フォルダーもファイルも同じ「中身」として統一して扱うことができるため、プログラムが驚くほどシンプルになります。

2. 木構造とコンポジットの基礎知識

2. 木構造とコンポジットの基礎知識
2. 木構造とコンポジットの基礎知識

まず、なぜ木構造という言葉を使うのかを解説します。プログラムの世界では、一番上の階層(ルート)から枝分かれしていくデータ構造を、逆さまの木に見立ててツリー構造木構造と呼びます。ここで出てくる基本的な用語を整理しましょう。

  • リーフ(葉):それ以上中身を持たない、一番端にある要素のこと。今回の例では「ファイル」に当たります。
  • コンポジット(合成物):中に他の要素を保持できる入れ物のこと。今回の例では「フォルダー」に当たります。

コンポジットパターンの肝は、これら「リーフ」と「コンポジット」に共通の役割を与えることです。これにより、プログラムを書くとき、それがファイルなのかフォルダーなのかを逐一気にすることなく、共通の命令を送ることができるようになります。

3. インターフェースで共通のルールを作る

3. インターフェースで共通のルールを作る
3. インターフェースで共通のルールを作る

C#でコンポジットパターンを実装する際、まず必要なのがインターフェースです。インターフェースとは、プログラムの中で「この機能は必ず持っていなければならない」というルールを定義する設計図のようなものです。今回は「中身を表示する」というルールを定義してみましょう。


public interface IFileSystemItem
{
    void Display(string indent);
}

ここでは、IFileSystemItemという名前のインターフェースを作りました。これによって、ファイルクラスもフォルダークラスも、このインターフェースに従うことで、「表示する」という機能を持たなければならないというルールが決まりました。

4. リーフとなるファイルクラスを作成する

4. リーフとなるファイルクラスを作成する
4. リーフとなるファイルクラスを作成する

次に、一番下の単位であるファイルクラスを作成します。これは単純に名前を表示するだけのクラスです。プログラム未経験の方も、以下のコードを見ると「名前を表示しているだけだな」とイメージできるはずです。


public class File : IFileSystemItem
{
    private string name;
    public File(string name) { this.name = name; }
    public void Display(string indent)
    {
        Console.WriteLine(indent + "- ファイル: " + name);
    }
}

このFileクラスは、Displayという命令を受けると、自分の名前を表示します。この時点では非常に単純な構造ですね。これが後ほど、フォルダーという「入れ物」の中にたくさん格納されることになります。

5. コンポジットとなるフォルダークラスを作成する

5. コンポジットとなるフォルダークラスを作成する
5. コンポジットとなるフォルダークラスを作成する

ここが今回の主役、フォルダークラスです。Listという、データを複数保管するための箱を使って、ファイルやさらに別のフォルダーを管理します。


using System.Collections.Generic;

public class Folder : IFileSystemItem
{
    private string name;
    private List<IFileSystemItem> children = new List<IFileSystemItem>();
    public Folder(string name) { this.name = name; }
    public void Add(IFileSystemItem item) { children.Add(item); }
    public void Display(string indent)
    {
        Console.WriteLine(indent + "+ フォルダー: " + name);
        foreach (var item in children)
        {
            item.Display(indent + "  ");
        }
    }
}

このクラスの面白いところは、Displayの中で自分の中身に対して再度Displayを呼び出している点です。これを再帰的処理と呼びます。自分の中に何が入っていても、その中身にも「表示せよ」と命令をリレーしていくことで、木構造全体を自動的に表示できるのです。

6. 実際に木構造を動かしてみる

6. 実際に木構造を動かしてみる
6. 実際に木構造を動かしてみる

最後に、これまで作ったクラスを組み合わせて、実際に木構造を作ってみましょう。Mainメソッドという、プログラムが最初に動き出す場所で、フォルダーを作り、その中にファイルやフォルダーを追加していきます。


class Program
{
    static void Main()
    {
        Folder root = new Folder("ルート");
        Folder docs = new Folder("ドキュメント");
        docs.Add(new File("メモ.txt"));
        root.Add(docs);
        root.Add(new File("設定.ini"));
        root.Display("");
    }
}

このコードを実行すると、以下のようにきれいな階層構造が表示されます。


+ フォルダー: ルート
  + フォルダー: ドキュメント
    - ファイル: メモ.txt
  - ファイル: 設定.ini

このように、コンポジットパターンを使うと、階層の深さを気にすることなく、スマートに木構造データを操作できるようになります。初心者の方でも、この「共通ルールを作って再帰的に呼び出す」という仕組みをマスターすれば、より高度なアプリケーション開発がぐっと身近になるはずです。

カテゴリの一覧へ
新着記事
New1
C#
C#のDictionary(辞書)の使い方を初心者向けに完全解説!キーと値でデータ管理を学ぼう
New2
C#
C#の数値型をマスターしよう!int・double・decimalの違いと使い方
New3
C#
C#で始めるIoT開発!音声認識とスピーカー制御の仕組みを解説
New4
Azure
Azure Reposの使い方を徹底解説!Gitによるソースコード管理とブランチ戦略(Gitflow)
人気記事
No.1
Java&Spring記事人気No1
COBOL
COBOLの数値データ型「PIC 9」の使い方と注意点をやさしく解説!
No.2
Java&Spring記事人気No2
C#
C#のpartialクラスとは?初心者でも理解できるクラス分割の基本
No.3
Java&Spring記事人気No3
C#
C#のWPFとは?XAMLでGUI開発を基礎から完全解説!初心者向けの入門ガイド
No.4
Java&Spring記事人気No4
Azure
Azureストレージの冗長性比較!LRS/GRS/ZRSの選び方とコストの最適解を完全解説
No.5
Java&Spring記事人気No5
C#
C#のログ出力入門!SerilogとNLogの使い方を徹底解説
No.6
Java&Spring記事人気No6
C#
C#のrefとoutキーワードとは?引数の参照渡しを理解しよう
No.7
Java&Spring記事人気No7
C#
C#のforeachループを完全ガイド!初心者でもわかるコレクション操作の基本
No.8
Java&Spring記事人気No8
COBOL
COBOLの小数点の扱いと符号付きデータ型(S, V)の使い方を初心者向けに解説!