C#でデザインパターン「Compositeパターン」

C# コンピュータ
C#

Compositeパターンと言ったらファイルシステムでしょう。
ということでサンプルコードを作成してみました。

using System.ComponentModel;
using System.Runtime.CompilerServices;

/// <summary>
/// Composite パターン
/// </summary>
interface INode
{
    string Name {get; set;}
    string Location {get; set;}

    string GetFullname();
}
class File : INode
{
    public string Name {get; set;}
    public string Location {get; set;}
    public File(string name, string location)
    {
        Name = name;
        Location = location;
    }
    public string GetFullname() => Name == "/" ? Name : (Location + "/" + Name);
}
class Dir : INode
{
    public string Name {get; set;}
    public string Location {get; set;}
    List<INode> _nodes = [];
    public Dir(string name, string location)
    {
        Name = name;
        Location = location;
    }
    public void Add(INode node)
    {
        _nodes.Add(node);
    }
    public IEnumerable<INode> GetNodes()
    {
        foreach(var node in _nodes)
        {
            yield return node;
        }
    }
    public string GetFullname() => Name == "/" ? Name : (Location + "/" + Name);
}
class Program
{
    static void GetChildNode(INode node)
    {
        Console.WriteLine($"{node.GetFullname()}");
        if (node is Dir dir)
        {
            foreach(var n in dir.GetNodes())
            {
                GetChildNode(n);
            }
        }
    }
    static public void Main()
    {
        var root = new Dir("root", "");
        root.Add(new File("sample.txt", root.GetFullname()));
        
        var subDir = new Dir("SubDir", root.GetFullname());
        root.Add(subDir);
        subDir.Add(new File("test1.txt", subDir.GetFullname()));
        subDir.Add(new File("test2.txt", subDir.GetFullname()));

        GetChildNode(root);

        // 結果
        // /root
        // /root/sample.txt
        // /root/SubDir
        // /root/SubDir/test1.txt
        // /root/SubDir/test2.txt
    }
}

再帰処理でrootから全てのノードにアクセスしています。
インターフェイスを合わせるのであればFileクラスにも要素数が0個のList<INode> _nodes = [];を作成すると良いでしょう。

コメント