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 = [];を作成すると良いでしょう。
コメント