2006年02月27日

Visitor -構造を渡り歩きながら仕事をする

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



FileTreatmentExceptionクラス
using System;

namespace Gushwell.DesignPatterns {

[Serializable]
public class FileTreatmentException : System.SystemException {
public FileTreatmentException() {
}
public FileTreatmentException(string msg)
: base(msg) {
}
}
}


Visitorクラス
using System;

namespace Gushwell.DesignPatterns {

public abstract class Visitor {
public abstract void Visit(File file);
public abstract void Visit(Directory directory);
}
}


IElementインターフェース
using System;

namespace Gushwell.DesignPatterns {

public interface IElement {
void Accept(Visitor v);
}
}


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

namespace Gushwell.DesignPatterns {

public abstract class Entry : IElement, IEnumerable {
public abstract string Name { get; }
public abstract int Size { get; }

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

// IEnumeratorの生成
public virtual IEnumerator GetEnumerator() {
throw new FileTreatmentException();
}

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

public abstract void Accept(Visitor param1);
}
}


Fileクラス
using System;

namespace Gushwell.DesignPatterns {

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

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

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

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

public override void Accept(Visitor v) {
v.Visit(this);
}
}
}


Directoryクラス
using System.Collections.Generic;

namespace Gushwell.DesignPatterns {

public class Directory : Entry, IEnumerable {
private string name; // ディレクトリの名前
private List<Entry> dir = new List<Entry>(); // ディレクトリエントリの集合

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

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

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

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

// 訪問者の受け入れ
public override void Accept(Visitor v) {
v.Visit(this);
}

// IEnumeratorの生成
public override IEnumerator GetEnumerator() {
return dir.GetEnumerator();
}
}
}


ListVisitorクラス
using System;

namespace Gushwell.DesignPatterns {

public class ListVisitor : Visitor {
private string currentdir = ""; // 現在注目しているディレクトリ名

// ファイルを訪問したときに呼ばれる
public override void Visit(File file) {
Console.WriteLine(currentdir + "/" + file);
}

// ディレクトリを訪問したときに呼ばれる
public override void Visit(Directory directory) {
Console.WriteLine(currentdir + "/" + directory);
string savedir = currentdir;
currentdir = currentdir + "/" + directory.Name;

foreach (Entry entry in directory)
entry.Accept(this);

currentdir = savedir;
}
}
}


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.Accept(new ListVisitor());

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.Accept(new ListVisitor());
} catch (FileTreatmentException e) {
Console.Error.WriteLine(e.StackTrace);
}
}
}
}

  

Posted by gushwell at 23:08Comments(0)TrackBack(0)

2006年02月22日

Decorator−飾り枠と中身の同一視

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



Displayクラス
using System;

namespace Gushwell.DesignPatterns {

public abstract class Display {
public abstract int Columns { get; }
public abstract int Rows { get; }

// row番目の文字列を得る
public abstract string GetRowText(int row);

// 全部表示する
public virtual void Show() {
for (int i = 0; i < Rows; i++) {
Console.WriteLine(GetRowText(i));
}
}
}
}


StringDisplayクラス
using System;
using System.Text;

namespace Gushwell.DesignPatterns {

public class StringDisplay : Display {

// 文字数
override public int Columns {
get { return Encoding.GetEncoding("shift-jis").GetByteCount(str); }
}

// 行数は1
override public int Rows {
get { return 1; }

}

// 表示文字列
private string str;

// 引数で表示文字列を指定
public StringDisplay(string str) {
this.str = str;
}

// rowが0のときのみ返す
public override string GetRowText(int row) {
if (row == 0) {
return str;
} else {
return null;
}
}
}
}


Borderクラス
using System;

namespace Gushwell.DesignPatterns {

public abstract class Border : Display {
protected internal Display display; // この飾り枠がくるんでいる「中身」を指す

// インスタンス生成時に「中身」を引数で指定
protected internal Border(Display display) {
this.display = display;
}
}
}


SideBorderクラス
using System;

namespace Gushwell.DesignPatterns {

public class SideBorder : Border {
// 文字数は中身の両側に飾り文字分を加えたもの
override public int Columns {
get { return 1 + display.Columns + 1; }

}

// 行数は中身の行数に同じ
override public int Rows {
get { return display.Rows; }

}
private char borderChar; // 飾りとなる文字

public SideBorder(Display display, char ch)
: base(display) {
this.borderChar = ch;
}

// 指定行の内容は、中身の指定行の両側に飾り文字をつけたもの
public override string GetRowText(int row) {
return borderChar + display.GetRowText(row) + borderChar;
}
}
}


FullBorderクラス
using System;

namespace Gushwell.DesignPatterns {

public class FullBorder : Border {

// 文字数は中身の両側に左右の飾り文字分を加えたもの
override public int Columns {
get { return 1 + display.Columns + 1; }

}

// 行数は中身の行数に上下の飾り文字分を加えたもの
override public int Rows {
get { return 1 + display.Rows + 1; }
}

public FullBorder(Display display)
: base(display) {
}

// 指定した行の内容
public override string GetRowText(int row) {
if (row == 0) {
// 上端の枠
return "+" + MakeLine('-', display.Columns) + "+";
} else if (row == display.Rows + 1) {
// 下端の枠
return "+" + MakeLine('-', display.Columns) + "+";
} else {
// それ以外
return "|" + display.GetRowText(row - 1) + "|";
}
}

// 文字chをcount個連続させた文字列を作る
private string MakeLine(char ch, int count) {
System.Text.StringBuilder buf = new System.Text.StringBuilder();
for (int i = 0; i < count; i++) {
buf.Append(ch);
}
return buf.ToString();
}
}
}


Programクラス
using System;

namespace Gushwell.DesignPatterns {

public class Program {
[STAThread]
public static void Main(string[] args) {
Display b1 = new StringDisplay("Hello, world.");
Display b2 = new SideBorder(b1, '#');
Display b3 = new FullBorder(b2);
b1.Show();
b2.Show();
b3.Show();
Display b4 =
new SideBorder(
new FullBorder(
new FullBorder(
new SideBorder(
new FullBorder(
new StringDisplay("こんにちは。")
),
'*'
)
)
),
'/'
);
b4.Show();
Console.ReadLine();
}
}

}  
Posted by gushwell at 23:16Comments(0)TrackBack(0)

2006年02月20日

Composite ― 容器と中身の同一視

   このエントリーをはてなブックマークに追加 Clip to Evernote
ここに掲載したコードは、『増補改訂版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());
}
}
}
}

  
Posted by gushwell at 22:24Comments(0)TrackBack(0)

2006年02月15日

Strategy -アルゴリズムをごっそり切り替える

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


Handクラス
using System;

namespace Gushwell.Design.Patterns {

public class Hand {
public const int HANDVALUE_GUU = 0; // グーを表す値
public const int HANDVALUE_CHO = 1; // チョキを表す値
public const int HANDVALUE_PAA = 2; // パーを表す値

public static readonly Hand[] hand = new Hand[] {
new Hand(HANDVALUE_GUU),
new Hand(HANDVALUE_CHO),
new Hand(HANDVALUE_PAA)
};

private static readonly string[] name = new string[]
{ "グー", "チョキ", "パー" };
private int handvalue; // じゃんけんの手の値

private Hand(int handvalue) {
this.handvalue = handvalue;
}

// 値からインスタンスを得る
public static Hand GetHand(int handvalue) {
return hand[handvalue];
}

// thisがhより強いときtrue
public virtual bool IsStrongerThan(Hand h) {
return Fight(h) == 1;
}

// thisがhより弱いときtrue
public virtual bool IsWeakerThan(Hand h) {
return Fight(h) == -1;
}

// 引き分けは0, thisの勝ちなら1, hの勝ちなら-1
private int Fight(Hand h) {
if (this == h) {
return 0;
} else if ((this.handvalue + 1) % 3 == h.handvalue) {
return 1;
} else {
return -1;
}
}

// 文字列表現へ変換
public override string ToString() {
return name[handvalue];
}
}
}


IStrategyインターフェース
using System;

namespace Gushwell.Design.Patterns {

public interface IStrategy {
Hand NextHand();
void Study(bool win);
}
}


WinningStrategy
using System;

namespace Gushwell.Design.Patterns {

public class WinningStrategy : IStrategy {
private Random random;
private bool won = false;
private Hand prevHand;

public WinningStrategy(int seed) {
random = new Random((int)seed);
}

public virtual Hand NextHand() {
if (!won) {
prevHand = Hand.GetHand(random.Next(3));
}
return prevHand;
}

public virtual void Study(bool win) {
won = win;
}
}
}


ProbStrategyクラス
using System;

namespace Gushwell.Design.Patterns {
public class ProbStrategy : IStrategy {
private Random random;
private int prevHandValue = 0;
private int currentHandValue = 0;
private int[][] history = new int[][] { new int[] { 1, 1, 1 },
new int[] { 1, 1, 1 },
new int[] { 1, 1, 1 } };

public ProbStrategy(int seed) {
random = new Random((int)seed);
}

public virtual Hand NextHand() {
int bet = random.Next(GetSum(currentHandValue));
int handvalue = 0;
if (bet < history[currentHandValue][0]) {
handvalue = 0;
} else if (bet < history[currentHandValue][0] +
history[currentHandValue][1]) {
handvalue = 1;
} else {
handvalue = 2;
}
prevHandValue = currentHandValue;
currentHandValue = handvalue;
return Hand.GetHand(handvalue);
}

private int GetSum(int hv) {
int sum = 0;
for (int i = 0; i < 3; i++) {
sum += history[hv][i];
}
return sum;
}

public virtual void Study(bool win) {
if (win) {
history[prevHandValue][currentHandValue]++;
} else {
history[prevHandValue][(currentHandValue + 1) % 3]++;
history[prevHandValue][(currentHandValue + 2) % 3]++;
}
}
}
}


Playerクラス
using System;

namespace Gushwell.Design.Patterns {

public class Player {
private string name;
private IStrategy strategy;
private int wincount;
private int losecount;
private int gamecount;

public Player(string name, IStrategy strategy) {
// 名前と戦略を授けられる
this.name = name;
this.strategy = strategy;
}

public virtual Hand NextHand() {
// 戦略におうかがいを立てる
return strategy.NextHand();
}

public virtual void Win() {
// 勝った
strategy.Study(true);
wincount++;
gamecount++;
}

public virtual void Lose() {
// 負けた
strategy.Study(false);
losecount++;
gamecount++;
}

public virtual void Even() {
// 引き分け
gamecount++;
}

public override string ToString() {
return "[" + name + ":" + gamecount + " games, " +
wincount + " win, " +
losecount + " lose" + "]";
}
}
}


Programクラス
using System;

namespace Gushwell.Design.Patterns {

public class Program {
[STAThread]
public static void Main(string[] args) {
if (args.Length != 2) {
Console.WriteLine("Usage: Program randomseed1 randomseed2");
Console.WriteLine("Example: Program 314 15");
return;
}

int seed1 = int.Parse(args[0]);
int seed2 = int.Parse(args[1]);
Player player1 = new Player("Taro", new WinningStrategy(seed1));
Player player2 = new Player("Hana", new ProbStrategy(seed2));
for (int i = 0; i < 10000; i++) {
Hand nextHand1 = player1.NextHand();
Hand nextHand2 = player2.NextHand();
if (nextHand1.IsStrongerThan(nextHand2)) {
Console.WriteLine("Winner:" + player1);
player1.Win();
player2.Lose();
} else if (nextHand2.IsStrongerThan(nextHand1)) {
Console.WriteLine("Winner:" + player2);
player1.Lose();
player2.Win();
} else {
Console.WriteLine("Even...");
player1.Even();
player2.Even();
}
}

Console.WriteLine("Total result:");
Console.WriteLine(player1.ToString());
Console.WriteLine(player2.ToString());
}
}
}
  
Posted by gushwell at 21:51Comments(0)TrackBack(0)

2006年02月13日

Borland Delphi 売却

   このエントリーをはてなブックマークに追加 Clip to Evernote
米BorlandがDelphiなどIDE事業を売却、アプリライフサイクル管理分野に注力 だそうです。
Borlandの言語製品には、いろいろとお世話になっていたので、かなりショックですね。
Delphiはどうなってしまうんだろうか。



  
Posted by gushwell at 22:54Comments(0)TrackBack(0)

2006年02月12日

Microsoft ACE

   このエントリーをはてなブックマークに追加 Clip to Evernote
d1579560.JPGMicrosoft から Award for Customer Excellence というのを頂いた。
写真の置物は、ACE Visual Studio Cube というんだそうです。
こういったものをもらうのは初めてなので、うれしいですね。  
Posted by gushwell at 22:57Comments(0)TrackBack(0)

2006年02月10日

AbstractFactoryパターン -関連する部品を組み合わせて製品を作る

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



Factoryクラス
using System;

namespace Gushwell.DesignPatterns.BaseFactory {

public abstract class Factory {

public static Factory GetFactory(string classname) {
Factory factory = null;
try {
factory = (Factory)Activator.CreateInstance(Type.GetType(classname));
} catch (System.TypeLoadException) {
Console.Error.WriteLine("クラス " + classname + " が見つかりません。");
} catch (System.Exception e) {
Console.Error.WriteLine(e.StackTrace);
}
return factory;
}

public abstract Link CreateLink(string caption, string url);
public abstract Tray CreateTray(string caption);
public abstract Page CreatePage(string title, string author);
}
}



Pageクラス
using System;
using System.Text;
using System.Collections.Generic;
using System.IO;

namespace Gushwell.DesignPatterns.BaseFactory {

public abstract class Page {
protected string title;
protected string author;
protected List<Item> content = new List<Item>();

public Page(string title, string author) {
this.title = title;
this.author = author;
}

public virtual void Add(Item item) {
content.Add(item);
}

public virtual void Output() {
try {
string filename = title + ".html";
StreamWriter writer = new StreamWriter(filename, false, Encoding.Default);
writer.Write(this.MakeHTML());
writer.Close();
Console.WriteLine(filename + " を作成しました。");
} catch (System.IO.IOException e) {
Console.Error.WriteLine(e.StackTrace);
}
}

public abstract string MakeHTML();
}
}



Trayクラス
using System;
using System.Collections.Generic;

namespace Gushwell.DesignPatterns.BaseFactory {

public abstract class Tray : Item {
protected List<Item> tray = new List<Item>();

public Tray(string caption)
: base(caption) {
}

public virtual void Add(Item item) {
tray.Add(item);
}
}
}



Itemクラス
using System;

namespace Gushwell.DesignPatterns.BaseFactory {

public abstract class Item {
protected string caption;

public Item(string caption) {
this.caption = caption;
}

public abstract string MakeHTML();
}
}



Linkクラス
using System;

namespace Gushwell.DesignPatterns.BaseFactory {

public abstract class Link : Item {
protected string url;

public Link(string caption, string url)
: base(caption) {
this.url = url;
}
}
}





ListFactoryクラス
using System;
using Gushwell.DesignPatterns.BaseFactory;

namespace Gushwell.DesignPatterns.List {

public class ListFactory : Factory {
public override Link CreateLink(string caption, string url) {
return new ListLink(caption, url);
}

public override Tray CreateTray(string caption) {
return new ListTray(caption);
}

public override Page CreatePage(string title, string author) {
return new ListPage(title, author);
}
}
}



ListLinkクラス
using System;
using Gushwell.DesignPatterns.BaseFactory;

namespace Gushwell.DesignPatterns.List {

public class ListLink : Link {
public ListLink(string caption, string url)
: base(caption, url) {
}

public override string MakeHTML() {
return " <li><a href=\"" + url + "\">" + caption + "</a></li>\n";
}
}
}



ListPageクラス
using System;
using System.Text;
using Gushwell.DesignPatterns.BaseFactory;

namespace Gushwell.DesignPatterns.List {

public class ListPage : Page {
public ListPage(string title, string author)
: base(title, author) {
}

public override string MakeHTML() {
StringBuilder buffer = new StringBuilder();
buffer.Append("<html><head><title>" + title + "</title></head>\n");
buffer.Append("<body>\n");
buffer.Append("<h1>" + title + "</h1>\n");
buffer.Append("<ul>\n");

foreach (Item item in content) {
buffer.Append(item.MakeHTML());
}
buffer.Append("</ul>\n");
buffer.Append("<hr><address>" + author + "</address>");
buffer.Append("</body></html>\n");
return buffer.ToString();
}
}
}


ListTrayクラス
using System;
using System.Text;
using Gushwell.DesignPatterns.BaseFactory;

namespace Gushwell.DesignPatterns.List {

public class ListTray : Tray {
public ListTray(string caption)
: base(caption) {
}

public override string MakeHTML() {
StringBuilder buffer = new StringBuilder();
buffer.Append("<li>\n");
buffer.Append(caption + "\n");
buffer.Append("<ul>\n");
foreach (Item item in tray) {
buffer.Append(item.MakeHTML());
}

buffer.Append("</ul>\n");
buffer.Append("</li>\n");
return buffer.ToString();
}
}
}




TableFactoryクラス
using System;
using Gushwell.DesignPatterns.BaseFactory;

namespace Gushwell.DesignPatterns.Table {

public class TableFactory : Factory {
public override Link CreateLink(string caption, string url) {
return new TableLink(caption, url);
}

public override Tray CreateTray(string caption) {
return new TableTray(caption);
}

public override Page CreatePage(string title, string author) {
return new TablePage(title, author);
}
}
}



TableLinkクラス
using System;
using Gushwell.DesignPatterns.BaseFactory;


namespace Gushwell.DesignPatterns.Table {

public class TableLink : Link {
public TableLink(string caption, string url)
: base(caption, url) {
}

public override string MakeHTML() {
return "<td><a href=\"" + url + "\">" + caption + "</a></td>\n";
}
}
}



TablePageクラス
using System;
using System.Text;
using Gushwell.DesignPatterns.BaseFactory;

namespace Gushwell.DesignPatterns.Table {

public class TablePage : Page {
public TablePage(string title, string author)
: base(title, author) {
}

public override string MakeHTML() {
StringBuilder buffer = new StringBuilder();
buffer.Append("<html><head><title>" + title + "</title></head>\n");
buffer.Append("<body>\n");
buffer.Append("<h1>" + title + "</h1>\n");
buffer.Append("<table width=\"80%\" border=\"3\">\n");
foreach (Item item in content) {
buffer.Append("<tr>" + item.MakeHTML() + "</tr>");
}

buffer.Append("</table>\n");
buffer.Append("<hr><address>" + author + "</address>");
buffer.Append("</body></html>\n");
return buffer.ToString();
}
}
}



TableTrayクラス
using System;
using System.Text;
using Gushwell.DesignPatterns.BaseFactory;

namespace Gushwell.DesignPatterns.Table {

public class TableTray : Tray {
public TableTray(string caption)
: base(caption) {
}

public override string MakeHTML() {
StringBuilder buffer = new StringBuilder();
buffer.Append("<td>");
buffer.Append("<table width=\"100%\" border=\"1\"><tr>");
buffer.Append("<td bgcolor=\"#cccccc\" align=\"center\" colspan=\"" +
tray.Count + "\"><b>" + caption + "</b></td>");
buffer.Append("</tr>\n");
buffer.Append("<tr>\n");
foreach (Item item in tray) {
buffer.Append(item.MakeHTML());
}

buffer.Append("</tr></table>");
buffer.Append("</td>");
return buffer.ToString();
}
}
}





Programクラス
using System;
using Gushwell.DesignPatterns.BaseFactory;

namespace Gushwell.DesignPatterns {
public class Program {
[STAThread]
public static void Main(string[] args) {
if (args.Length != 1) {
const string ListFactoryClass =
"Gushwell.DesignPatterns.List.ListFactory";
const string TableFactoryClass =
"Gushwell.DesignPatterns.Table.TableFactory";
Console.WriteLine("Usage: AFactorySample TypeName");
Console.WriteLine("Example 1: AFactorySample " + ListFactoryClass);
Console.WriteLine("Example 2: AFactorySample " + TableFactoryClass);
return;
}
Factory factory = Factory.GetFactory(args[0]);

Link asahi = factory.CreateLink("朝日新聞", "http://www.asahi.com/");
Link yomiuri = factory.CreateLink("読売新聞", "http://www.yomiuri.co.jp/");

Link us_yahoo = factory.CreateLink("Yahoo!", "http://www.yahoo.com/");
Link jp_yahoo = factory.CreateLink("Yahoo!Japan", "http://www.yahoo.co.jp/");
Link excite = factory.CreateLink("Excite", "http://www.excite.com/");
Link google = factory.CreateLink("Google", "http://www.google.com/");

Tray traynews = factory.CreateTray("新聞");
traynews.Add(asahi);
traynews.Add(yomiuri);

Tray trayyahoo = factory.CreateTray("Yahoo!");
trayyahoo.Add(us_yahoo);
trayyahoo.Add(jp_yahoo);

Tray traysearch = factory.CreateTray("サーチエンジン");
traysearch.Add(trayyahoo);
traysearch.Add(excite);
traysearch.Add(google);

Page page = factory.CreatePage("LinkPage", "結城 浩");
page.Add(traynews);
page.Add(traysearch);
page.Output();
}
}
}

  
Posted by gushwell at 22:30Comments(0)TrackBack(0)

2006年02月08日

C#デザインパターン Index

   このエントリーをはてなブックマークに追加 Clip to Evernote

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

別館「Gushwell's C# Programing Page」に、C#3.0に対応したコードを掲載しています。こちらのサイトでは、ソースコードのダウンロードもできますので、ぜひお立ち寄りください。

■生成に関するパターン
Factory Method インスタンス作成をサブクラスにまかせる
Singleton たった1つのインスタンス
Prototype コピーしてインスタンスを作る
Builder 複雑なインスタンスを組み立てる
Abstract Factory 関連する部品を組み合わせて製品を作る


■構造に関するパターン
Adapter 皮かぶせて再利用
Bridge 機能の階層と実装の階層を分ける
Composite 容器と中身の同一視
Decorator 飾り枠と中身の同一視
Facade シンプルな窓口
Flyweight 同じものを共有して無駄をなくす
Proxy 必要になってから作る


■振る舞いに関するパターン
Iterator 1つ1つ数え上げる
Template Method 具体的な処理をサブクラスにまかせる
Strategy アルゴリズムをごっそり切り替える
Visitor 構造を渡り歩きながら仕事をする
Chain of Responsibility 責任のたらい回し
Mediator 相手は相談役1人だけ
Observer 状態の変化を通知する
Memento 状態を保存する
State 状態をクラスとして表現する
Command 命令をクラスにする
Interpreter 文法規則をクラスで表現する

4797327030増補改訂版Java言語で学ぶデザインパターン入門
結城 浩
ソフトバンククリエイティブ 2004-06-19

by G-Tools
  
Posted by gushwell at 22:31Comments(0)TrackBack(0)