「増補改訂版Java言語で学ぶデザインパターン入門」の「Compositeパターン」をC#で書いてみました。
GitHubにもコードを置いています。
参考
DesignPattern【Composite】GitHub
コード
public abstract class Entry
{
public abstract string GetName();
public abstract int GetSize();
public abstract Entry Add(Entry entry);
public void PrintList()
{
PrintList("");
}
public abstract void PrintList(string prefix);
public override string ToString()
{
return $"{GetName()}({GetSize()})";
}
}
public class File : Entry
{
private string name;
private int size;
public File(string name, int size)
{
this.name = name;
this.size = size;
}
public override Entry Add(Entry entry)
{
throw new FileTreatmentException();
}
public override string GetName()
{
return name;
}
public override int GetSize()
{
return size;
}
public override void PrintList(string prefix)
{
Console.WriteLine($"{prefix}/{this}");
}
}
public class Directory : Entry
{
private string name;
private IList Entry> directory = new List Entry>();
public Directory(string name)
{
this.name = name;
}
public override string GetName()
{
return name;
}
public override int GetSize()
{
int size = 0;
var it = directory.GetEnumerator();
while (it.MoveNext())
{
size += it.Current.GetSize();
}
return size;
}
public override Entry Add(Entry entry)
{
directory.Add(entry);
return this;
}
public override void PrintList(string prefix)
{
Console.WriteLine($"{prefix}/{this}");
var it = directory.GetEnumerator();
while (it.MoveNext())
{
it.Current.PrintList($"{prefix}/{name}");
}
}
}
public class FileTreatmentException : Exception
{
public FileTreatmentException() : base()
{
}
public FileTreatmentException(string message) : base(message)
{
}
public FileTreatmentException(string message, Exception innerException)
: base(message, innerException)
{
}
}
class Program
{
static void Main(string[] args)
{
try
{
Console.WriteLine("Making root entries...");
Directory rootdir = new Directory("root");
Directory bindir = new Directory("bin");
Directory tmpdir = new Directory("tmp");
Directory usrdir = new Directory("usr");
rootdir.Add(bindir);
rootdir.Add(tmpdir);
rootdir.Add(usrdir);
bindir.Add(new File("vi", 10000));
bindir.Add(new File("latex", 20000));
rootdir.PrintList();
Console.WriteLine("");
Console.WriteLine("Making user entries...");
Directory yuki = new Directory("yuki");
Directory hanako = new Directory("hanako");
Directory tomura = new Directory("tomura");
usrdir.Add(yuki);
usrdir.Add(hanako);
usrdir.Add(tomura);
yuki.Add(new File("diary.html", 100));
yuki.Add(new File("Composite.java", 200));
hanako.Add(new File("memo.tex", 300));
tomura.Add(new File("game.doc", 400));
tomura.Add(new File("junk.mail", 500));
rootdir.PrintList();
}
catch (FileTreatmentException ex)
{
Console.WriteLine(ex);
}
}
}
実行結果は以下のようになります。
Making root entries...
/root(30000)
/root/bin(30000)
/root/bin/vi(10000)
/root/bin/latex(20000)
/root/tmp(0)
/root/usr(0)
Making user entries...
/root(31500)
/root/bin(30000)
/root/bin/vi(10000)
/root/bin/latex(20000)
/root/tmp(0)
/root/usr(1500)
/root/usr/yuki(300)
/root/usr/yuki/diary.html(100)
/root/usr/yuki/Composite.java(200)
/root/usr/hanako(300)
/root/usr/hanako/memo.tex(300)
/root/usr/tomura(900)
/root/usr/tomura/game.doc(400)
/root/usr/tomura/junk.mail(500)
その他のデザインパターンは以下の記事から確認してください。