×

[PR]この広告は3ヶ月以上更新がないため表示されています。
ホームページを更新後24時間以内に表示されなくなります。

C#デザインパターン  - Composite

ここに掲載したコードは、『増補改訂版Java言語で学ぶデザインパターン入門 / 結城 浩(著)』に掲載されているサンプルコードをC#に移植したものです。
解説らしい解説は載せていませんので、『増補改訂版Java言語で学ぶデザインパターン入門 / 結城 浩(著)』も合わせてお読みください。

※当ソースは、Visual C# 2008 Express Editionで動作を確認しています。
  Visual Studio 2005をお使いの方は、ブログの記事を残しておきますので、そちらをご覧ください。



■Entry.cs
using System;

namespace Gushwell.DesignPatterns {

public abstract class Entry {
public abstract string Name { get; protected set; }
public abstract int Size { get; protected set; }

// エントリを追加する
public virtual Entry Add(Entry entry) {
throw new FileTreatmentException();
}

// 一覧を表示する
public virtual void PrintList() {
PrintList("");
}

// prefixを前につけて一覧を表示する
protected internal abstract void PrintList(string prefix);

// 文字列表現
public override string ToString() {
return Name + " (" + Size + ")";
}
}
}


■File.cs
using System;

namespace Gushwell.DesignPatterns {

public class File : Entry {
override public string Name { get; protected set; }
override public int Size { get; protected set; }

public File(string name, int size) {
Name = name;
Size = size;
}

protected internal override void PrintList(string prefix) {
Console.WriteLine(prefix + "/" + this);
}
}
}


■Directory.cs
using System;
using System.Linq;
using System.Collections.Generic;

namespace Gushwell.DesignPatterns {

public class Directory : Entry {
private List<Entry> directory = new List<Entry>(); // ディレクトリエントリの集合

// 名前を得る
override public string Name { get; protected set; }

// サイズを得る
override public int Size {
get {
return directory.Aggregate(0, (s, e) => s + e.Size);
}
protected set { }
}

// コンストラクタ
public Directory(string name) {
Name = name;
}

// エントリの追加
public override Entry Add(Entry entry) {
directory.Add(entry);
return this;
}

// エントリの一覧
protected internal override void PrintList(string prefix) {
directory.ForEach(e => e.PrintList(prefix + "/" + Name));
}
}
}



■FileTreatmentException.cs
using System;

namespace Gushwell.DesignPatterns {

public class FileTreatmentException : System.SystemException {
public FileTreatmentException()
: base() {
}

public FileTreatmentException(string msg)
: base(msg) {
}
}
}


■Program.cs
using System;

namespace Gushwell.DesignPatterns {

public class Program {
public 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 e) {
Console.WriteLine(e.StackTrace.ToString());
}
}
}
}