2006年02月20日

Composite ― 容器と中身の同一視

  
ここに掲載したコードは、『増補改訂版Java言語で学ぶデザインパターン入門 / 結城 浩(著)』に掲載されているサンプルコードをC#に移植したものです。移植後のコードの公開に関しては、結城氏の了解を得ています。
※当ソースは、Visual C# 2005 Express Editionで動作を確認しています。



Entryクラス
using System;

namespace Gushwell.DesignPatterns {

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

// エントリを追加する
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 + ")";
}
}
}


Directoryクラス
using System;
using System.Collections;

namespace Gushwell.DesignPatterns {

public class Directory : Entry {
private string name; // ディレクトリの名前
private ArrayList directory = new ArrayList(); // ディレクトリエントリの集合

// 名前を得る
override public string Name {
get { return name; }
}

// サイズを得る
override public int Size {
get {
int size = 0;
foreach (Entry entry in directory) {
size += entry.Size;
}
return size;
}
}

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

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

// エントリの一覧
protected internal override void PrintList(string prefix) {
Console.WriteLine(prefix + "/" + this);
foreach (Entry entry in directory) {
entry.PrintList(prefix + "/" + name);
}
}
}
}


Fileクラス
using System;

namespace Gushwell.DesignPatterns {

public class File : Entry {
private string name;
private int size;

override public string Name {
get { return name; }
}

override public int Size {
get { return size; }
}

public File(string name, int size) {
this.name = name;
this.size = size;
}

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


FileTreatmentExceptionクラス
using System;

namespace Gushwell.DesignPatterns {

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

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


Programクラス
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());
}
}
}
}



 

この記事へのトラックバックURL