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

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

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



■Trouble.cs
using System;

namespace Gushwell.DesignPatterns {

public class Trouble {
// トラブル番号を得る
virtual public int Number { get; private set; }

// トラブルの生成
public Trouble(int number) {
Number = number;
}

// トラブルの文字列表現
public override string ToString() {
return "[Trouble " + Number + "]";
}
}
}


■Support.cs
using System;

namespace Gushwell.DesignPatterns {

public abstract class Support {
private string name; // このトラブル解決者の名前
private Support next; // たらい回しの先

// トラブル解決者の生成
public Support(string name) {
this.name = name;
}

// たらい回しの先を設定
public virtual Support SetNext(Support next) {
this.next = next;
return next;
}

// トラブル解決の手順
public void DoSupport(Trouble trouble) {
if (Resolve(trouble)) {
Done(trouble);
} else if (next != null) {
next.DoSupport(trouble);
} else {
Fail(trouble);
}
}
// 文字列表現
public override string ToString() {
return "[" + name + "]";
}

// 解決用メソッド
protected abstract bool Resolve(Trouble trouble);

// 解決
protected virtual void Done(Trouble trouble) {
Console.WriteLine(trouble + " is resolved by " + this + ".");
}

// 未解決
protected virtual void Fail(Trouble trouble) {
Console.WriteLine(trouble + " cannot be resolved.");
}
}
}


■NoSupport.cs
using System;

namespace Gushwell.DesignPatterns {

public class NoSupport : Support {
public NoSupport(string name)
: base(name) {
}

// 解決用メソッド
protected override bool Resolve(Trouble trouble) {
return false; // 自分は何も処理しない
}
}
}


■LimitSupport.cs
using System;

namespace Gushwell.DesignPatterns {

public class LimitSupport : Support {
private int limit; // この番号未満なら解決できる

public LimitSupport(string name, int limit)
: base(name) {
this.limit = limit;
}

// 解決用メソッド
protected override bool Resolve(Trouble trouble) {
return trouble.Number < limit;
}
}
}


■OddSupport.cs
using System;

namespace Gushwell.DesignPatterns {

public class OddSupport : Support {
public OddSupport(string name)
: base(name) {
}

// 解決用メソッド
protected override bool Resolve(Trouble trouble) {
return (trouble.Number % 2 == 1);
}
}
}


■SpecialSupport.cs
using System;

namespace Gushwell.DesignPatterns {

public class SpecialSupport : Support {
private int number; // この番号だけ解決できる

public SpecialSupport(string name, int number)
: base(name) {
this.number = number;
}

// 解決用メソッド
protected override bool Resolve(Trouble trouble) {
return (trouble.Number == number);
}
}
}



■Program.cs
using System;

namespace Gushwell.DesignPatterns {
public class Program {
public static void Main(string[] args) {
Support alice = new NoSupport("Alice");
Support bob = new LimitSupport("Bob", 100);
Support charlie = new SpecialSupport("Charlie", 429);
Support diana = new LimitSupport("Diana", 200);
Support elmo = new OddSupport("Elmo");
Support fred = new LimitSupport("Fred", 300);
// 連鎖の形成
alice.SetNext(bob).SetNext(charlie).SetNext(diana).SetNext(elmo).SetNext(fred);
// さまざまなトラブル発生
for (int i = 0; i < 500; i += 33) {
alice.DoSupport(new Trouble(i));
}
}
}
}