「JAVA言語で学ぶデザインパターン入門」をC#で書いてみた【Compositeパターン】

「増補改訂版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)

その他のデザインパターンは以下の記事から確認してください。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA