<?xml version="1.0" encoding="UTF-8" ?> <rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>デザインパターン</title><link>http://blogs.wankuma.com/masaru/category/1223.aspx</link><description>デザインパターン</description><managingEditor>まさる（高野 将、TAKANO Sho）</managingEditor><dc:language>ja-JP</dc:language><generator>.Text Version 0.95.2004.102</generator><item><dc:creator>まさる（高野 将、TAKANO Sho）</dc:creator><title>デザインパターンを学ぶ～その２７：IObservable、IObserverでObserverパターン～</title><link>http://blogs.wankuma.com/masaru/archive/2011/08/23/201752.aspx</link><pubDate>Tue, 23 Aug 2011 23:32:00 GMT</pubDate><guid>http://blogs.wankuma.com/masaru/archive/2011/08/23/201752.aspx</guid><wfw:comment>http://blogs.wankuma.com/masaru/comments/201752.aspx</wfw:comment><comments>http://blogs.wankuma.com/masaru/archive/2011/08/23/201752.aspx#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://blogs.wankuma.com/masaru/comments/commentRss/201752.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/masaru/services/trackbacks/201752.aspx</trackback:ping><description>&lt;p&gt;.NET Framework 4 では、イベントベースでないObserverパターンを実装するためのインターフェースとして、&lt;/p&gt; &lt;p&gt;&lt;a href="http://msdn.microsoft.com/ja-jp/library/dd783449.aspx"&gt;IObserver(T) インターフェイス (System)&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href="http://msdn.microsoft.com/ja-jp/library/dd990377.aspx"&gt;IObservable(T) インターフェイス (System)&lt;/a&gt;&lt;/p&gt; &lt;p&gt;の２つが新たに追加されました。&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;この２つのインターフェースは&lt;a href="http://msdn.microsoft.com/en-us/data/gg577609"&gt;Reactive Extensions（Rx）&lt;/a&gt;でもおなじみですが、どのように使えばよいかを学ぶため、&lt;a href="http://blogs.wankuma.com/masaru/archive/2007/05/23/77751.aspx"&gt;デザインパターンを学ぶ～その４：Ovserverパターン(1)～&lt;/a&gt;のコードをIObserver&amp;lt;T&amp;gt;、IObservable&amp;lt;T&amp;gt;を使用する形で再実装してみました。&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div&gt;
&lt;pre style="display: none" class="c#" name="code"&gt;using System;
using System.Collections.Generic;

namespace ConsoleApplication1
{
  // メール情報
  class MailInfo
  {
    public string From { get; set; }
    public string To { get; set; }
    public string Subject { get; set; }
  }

  // メール管理クラス
  class MailManager : IObservable&amp;lt;MailInfo&amp;gt;
  {
    // Observerリスト
    private List&amp;lt;IObserver&amp;lt;MailInfo&amp;gt;&amp;gt; observers;

    // クラス
    public MailManager()
    {
      observers = new List&amp;lt;IObserver&amp;lt;MailInfo&amp;gt;&amp;gt;();
    }

    // Observer購読
    public IDisposable Subscribe(IObserver&amp;lt;MailInfo&amp;gt; observer)
    {
      if (!observers.Contains(observer))
      {
        observers.Add(observer);
      }
      return new Unsubscriber(observers, observer);
    }

    // データ設定
    public void SetData(MailInfo mailInfo)
    {
      // Observerに通知
      observers.ForEach(x =&amp;gt; x.OnNext(mailInfo));
    }

    // 購読解除クラス
    public class Unsubscriber : IDisposable
    {
      private ICollection&amp;lt;IObserver&amp;lt;MailInfo&amp;gt;&amp;gt; observers;
      private IObserver&amp;lt;MailInfo&amp;gt; observer;

      public Unsubscriber(ICollection&amp;lt;IObserver&amp;lt;MailInfo&amp;gt;&amp;gt; observers, IObserver&amp;lt;MailInfo&amp;gt; observer)
      {
        this.observers = observers;
        this.observer = observer;
      }

      // 購読解除
      public void Dispose()
      {
        if (observers.Contains(observer))
        {
          observers.Remove(observer);
        }
      }
    }
  }

  // Faxクラス
  class Fax : IObserver&amp;lt;MailInfo&amp;gt;
  {
    public void OnNext(MailInfo value)
    {
      Console.WriteLine("Faxを送信します。");
      Console.WriteLine("From:{0}, To:{1}, Subject:{2}", value.From, value.To, value.Subject);
    }

    public void OnCompleted()
    {
      throw new NotImplementedException();
    }

    public void OnError(Exception error)
    {
      throw new NotImplementedException();
    }
  }

  // Printerクラス
  class Printer : IObserver&amp;lt;MailInfo&amp;gt;
  {
    public void OnNext(MailInfo value)
    {
      Console.WriteLine("印刷します。");
      Console.WriteLine("From={0}, To={1}, Subject={2}", value.From, value.To, value.Subject);
    }

    public void OnCompleted()
    {
      throw new NotImplementedException();
    }

    public void OnError(Exception error)
    {
      throw new NotImplementedException();
    }
  }

  // テストプログラム
  class Program
  {
    static void Main(string[] args)
    {
      var manager = new MailManager();

      // Faxで購読
      var fax = new Fax();
      IDisposable faxUnsubscriber = manager.Subscribe(fax);

      // データ設定、通知
      manager.SetData(new MailInfo()
      {
        From = "masaru@wankuma.com",
        To = "test@example.com",
        Subject = "送るよ～ん"
      });

      // Printerで購読
      var printer = new Printer();
      IDisposable printerUnsubscriber = manager.Subscribe(printer);

      // データ設定、通知
      manager.SetData(new MailInfo()
      {
        From = "masaru@wankuma.com",
        To = "test@example.com",
        Subject = "再送するよ～ん"
      });

      // Faxでの購読解除
      faxUnsubscriber.Dispose();

      // データ設定、通知
      manager.SetData(new MailInfo()
      {
        From = "masaru@wankuma.com",
        To = "test@example.com",
        Subject = "最後送るよ～ん"
      });
    }
  }
}
&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;実行結果&lt;/h4&gt;
&lt;p&gt;&lt;a href="http://masaru.wankuma.com/img/blogimg/IObservableIObserverObserver_14AF3/image_thumb1.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image_thumb1" border="0" alt="image_thumb1" src="http://masaru.wankuma.com/img/blogimg/IObservableIObserverObserver_14AF3/image_thumb1_thumb.png" width="681" height="496"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;一言でいえば、IObservable&amp;lt;T&amp;gt;のSubscribeメソッドで、IObserver&amp;lt;T&amp;gt;での購読を指定し、購読登録したIObserver&amp;lt;T&amp;gt;のOnNextメソッドで通知を行う、となるでしょうか。&lt;/p&gt;
&lt;p&gt;（なお、今回はIObserver&amp;lt;T&amp;gt;のOnCompletedメソッド、OnErrorメソッドは実装を省いています。）&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.wankuma.com/masaru/archive/0001/01/01/78369.aspx"&gt;デザインパターンを学ぶ～その５：Ovserverパターン(2)～&lt;/a&gt;でのイベントを用いた実装では、イベントハンドラーの登録、削除を行う必要があり若干煩雑になってしまっていましたが、今回の実装では登録はSubscribe、解除はDisposeするだけと、非常にシンプルになっています。&lt;/p&gt;
&lt;p&gt;また、イベントの登録、解除はC#では+=,-=演算子、VBではAddHandler,RemoveHandlerステートメントと実装がバラバラになってしまうので、それが統一できることも大きい改善点ではないかと思います。&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;まだ、さわりの部分しか試していませんが、よく出来ていますねぇ。&lt;/p&gt;
&lt;p&gt;また機会を見て、OnCompletedメソッド、OnErrorメソッドの動きを含め、Rxと絡めつつ学んでいこうと思います。&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/masaru/aggbug/201752.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>まさる</dc:creator><title>デザインパターンを学ぶ～その26：Facade（Fa&amp;ccedil;ade）パターン～</title><link>http://blogs.wankuma.com/masaru/archive/2010/03/29/187513.aspx</link><pubDate>Mon, 29 Mar 2010 02:50:00 GMT</pubDate><guid>http://blogs.wankuma.com/masaru/archive/2010/03/29/187513.aspx</guid><wfw:comment>http://blogs.wankuma.com/masaru/comments/187513.aspx</wfw:comment><comments>http://blogs.wankuma.com/masaru/archive/2010/03/29/187513.aspx#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://blogs.wankuma.com/masaru/comments/commentRss/187513.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/masaru/services/trackbacks/187513.aspx</trackback:ping><description>&lt;blockquote&gt; &lt;p&gt;&lt;strong&gt;Facade（Facade）：ファサード&lt;/strong&gt;&lt;br&gt;　表面、一面、うわべ、建物の正面&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Facade（Facade）パターンは、複数の関連するクラス群のオブジェクトを使った、ある程度複雑な処理に対して「窓口」となるインターフェースを提供するパターンです。ただし、Facadeで使用するクラスのカプセル化は行わないため、Facadeを通さずに直接使用することも可能です。&lt;/p&gt; &lt;p&gt;インターフェースを用意するという点で、Adapterパターンに似ていると感じるかもしれません。ただ、Adapterパターンの目的がインターフェースの「変換」であるのに対して、Facadeパターンの目的はインターフェースを「簡素化」することです。&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;それでは、実装例を見てみましょう。まずは、以下のようなクラス群があったとします。&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:9272ad63-0bc6-4d9e-be7f-4b117d0320cd" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="c#"&gt;public class RoomLight
{
	public void TurnOn()
	{
		Console.WriteLine("ルームライトをつけました");
	}

	public void TurnOff()
	{
		Console.WriteLine("ルームライトを消しました");
	}
}

public class DVDPlayer
{
	public void PowerOn()
	{
		Console.WriteLine("プレイヤーの電源を入れました");
	}

	public void PowerOff()
	{
		Console.WriteLine("プレイヤーの電源を落としました");
	}

	public void Insert(string dvdName)
	{
		Console.WriteLine("{0}を挿入します", dvdName);
	}

	public void Eject()
	{
		Console.WriteLine("DVDを取り出しました");
	}

	public void Play()
	{
		Console.WriteLine("再生しました");
	}

	public void Stop()
	{
		Console.WriteLine("停止しました");
	}
}
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;これらのクラス群を用いた処理として、以下の2つを考えます。&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;・DVDの視聴開始&lt;/p&gt;
&lt;p&gt;・DVDの視聴終了&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;この2つの処理を行うFacadeクラスは以下のようになります。&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:aea4a391-95a7-4c9d-b7b4-f58972583129" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="c#"&gt;public class TheaterRoomFacade
{
	public void PlayMovie(string dvdName)
	{
		Console.WriteLine("DVD:{0}の視聴を始めます", dvdName);
		var player = new DVDPlayer();
		player.PowerOn();
		player.Insert(dvdName);
		player.Play();

		var light = new RoomLight();
		light.TurnOff();
	}

	public void StopMovie()
	{
		Console.WriteLine("DVDの視聴を終えます");
		var light = new RoomLight();
		light.TurnOn();

		var player = new DVDPlayer();
		player.Stop();
		player.Eject();
		player.PowerOff();
	}
}
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;クライアント（今回はProgramクラスのMainメソッド）では、Facadeを通して各クラスを用いた処理を行うようにします。&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:08eca9eb-4472-4168-b1a1-8567c410a524" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="c#"&gt;public class Program
{
	static void Main(string[] args)
	{
		var facade = new TheaterRoomFacade();
		facade.PlayMovie("崖の上のポニョ");

		Console.WriteLine("--- 視聴中 ---");

		facade.StopMovie();
	}
}
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;それでは実行してみましょう。&lt;/p&gt;
&lt;p&gt;&lt;a href="http://masaru.wankuma.com/img/blogimg/26Facade1_14D4E/image.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://masaru.wankuma.com/img/blogimg/26Facade1_14D4E/image_thumb.png" width="681" height="496"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Facadeパターンを適用する際の利点として、たとえば今後オーディオシステムも導入した場合、クライアントコードの変更はせずに、Facadeにだけ変更を加えればよくなるといったことがあげられます。&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;ちなみに、Facadeパターンの実際に実用的な例としては、ASP.NET MVCやStrutsなどのMVCモデルのアプリケーションでは、Controllerにあたるクラスが一種のFacadeとみなせます。&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;さて、今回はFacadeパターンについて簡単に解説しました。次回はTemplate Methodパターンを紹介します。&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/masaru/aggbug/187513.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>まさる</dc:creator><title>デザインパターンを学ぶ～その25：Adapterパターン(2)～</title><link>http://blogs.wankuma.com/masaru/archive/2010/03/10/186994.aspx</link><pubDate>Wed, 10 Mar 2010 23:52:00 GMT</pubDate><guid>http://blogs.wankuma.com/masaru/archive/2010/03/10/186994.aspx</guid><wfw:comment>http://blogs.wankuma.com/masaru/comments/186994.aspx</wfw:comment><comments>http://blogs.wankuma.com/masaru/archive/2010/03/10/186994.aspx#Feedback</comments><slash:comments>44</slash:comments><wfw:commentRss>http://blogs.wankuma.com/masaru/comments/commentRss/186994.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/masaru/services/trackbacks/186994.aspx</trackback:ping><description>&lt;p&gt;&lt;a href="http://blogs.wankuma.com/masaru/archive/2010/03/08/186913.aspx" target="_blank"&gt;前回&lt;/a&gt;に引き続き「Adapterパターン」です。&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;前回は「継承型」のAdapterパターンを紹介しました。今回は「委譲型」のAdapterパターンを紹介します。&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;まずはおさらいとして、Adapterで適合させたいインターフェイス、クラスを見てみましょう。&lt;/p&gt; &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:d1bde507-8acf-4496-902c-80f683591783" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="c#"&gt;// しゃべれるインターフェース
interface ISpeakable
{
  void Speak();
}

// 人間クラス
class Human : ISpeakable
{
  // しゃべる
  public void Speak()
  {
    Console.WriteLine("こんにちは");
  }
}

// アヒルクラス
class Duck
{
  // 鳴く
  public void Quack()
  {
    Console.WriteLine("クワックワッ");
  }
}
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;今回の目的はDuckクラスをISpeakableインターフェイスを使って呼び出すようにすることです。&lt;/p&gt;
&lt;p&gt;そのためには、ISpeakableインターフェイスを実装したクラスの内部にDuckクラスのオブジェクトを持たせ、SpeakメソッドではそのオブジェクトのQuackメソッドを呼び出す（委譲）ようにします。&lt;/p&gt;
&lt;p&gt;それでは、委譲型のAdapterの例を以下に示します。&lt;/p&gt;
&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:507dd527-ad99-4e19-aed8-f3ae2809b35c" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="c#"&gt;// 委譲Adapter
class DelegateSpeakAdapter : ISpeakable
{
	// 内部にアヒル型を持つ
	private Duck duck = new Duck();

	// しゃべる
	public void Speak()
	{
		// 内部に持ったアヒルを鳴かせる &amp;lt;- ここのところが委譲
		this.duck.Quack();
	}
}&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;実行結果は以下の通りです。&lt;/p&gt;
&lt;p&gt;&lt;a href="http://masaru.wankuma.com/img/blogimg/25Adapter2_14CBD/image.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://masaru.wankuma.com/img/blogimg/25Adapter2_14CBD/image_thumb.png" width="465" height="189"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;さて、インターフェイスを実装するクラス内にオブジェクトを含有する構造はDecoratorパターンに似ています。しかし、Decoratorパターンがクラスの「装飾」を目的としていたのに対し、Adapterパターンは既存のクラスにインターフェイスを「適合」させることが目的です。&lt;/p&gt;
&lt;p&gt;したがって、パターンを適用する場合は明確に使い分けるように注意しなければなりません。&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;以上でAdapterパターンは終わりです。&lt;/p&gt;
&lt;p&gt;次回はAdapterパターンと目的が似ているFacadeパターンを取り上げるつもりです。&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/masaru/aggbug/186994.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>まさる</dc:creator><title>デザインパターンを学ぶ～その24：Adapterパターン(1)～</title><link>http://blogs.wankuma.com/masaru/archive/2010/03/08/186913.aspx</link><pubDate>Mon, 08 Mar 2010 23:25:00 GMT</pubDate><guid>http://blogs.wankuma.com/masaru/archive/2010/03/08/186913.aspx</guid><wfw:comment>http://blogs.wankuma.com/masaru/comments/186913.aspx</wfw:comment><comments>http://blogs.wankuma.com/masaru/archive/2010/03/08/186913.aspx#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://blogs.wankuma.com/masaru/comments/commentRss/186913.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/masaru/services/trackbacks/186913.aspx</trackback:ping><description>&lt;blockquote&gt; &lt;p&gt;&lt;strong&gt;Adapter&lt;/strong&gt;&lt;br&gt;　適合者&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Adapterパターンはその名の通り、クラスのインターフェースを「適合」させるためのパターンです。&lt;/p&gt; &lt;p&gt;ベンダーが作成したクラスなど、手を加えられないクラスに対して、統一したインターフェースを実現したい場合に用います。&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;例をあげましょう。まず、以下のようなインターフェイスがあったとしましょう。&lt;/p&gt; &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:36c19d5f-1fc2-4086-8322-d938a8b03690" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="c#"&gt;// しゃべれるインターフェース
interface ISpeakable
{
	void Speak();
}&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;そして、ISpeakableインターフェイスを実装した人間クラスがあります。&lt;/p&gt;
&lt;p&gt;
&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:673db8d3-f202-4786-9b57-e6c6ed556c04" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="c#"&gt;// 人間クラス
class Human : ISpeakable
{
	// しゃべる
	public void Speak()
	{
		Console.WriteLine("こんにちは");
	}
}
&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;今回は、次のようなDuckクラスも、Humanクラスと同じように使用したいと考えています。&lt;/p&gt;
&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:2bbc8fb2-f4c7-42f0-8ba5-3319e17dfc1a" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="c#"&gt;// アヒルクラス
class Duck
{
	// 鳴く
	public void Quack()
	{
		Console.WriteLine("クワックワッ");
	}
}
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;こういったときAdapterパターンを使ってDuckに適合するAdapterクラスを作成します。&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;なお、Adapterパターンには大きく分けて、「継承型」と「委譲型」があります。今回は「継承型」を紹介します。&lt;/p&gt;
&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:eb0b3911-ffe0-47fd-8910-e7ede1f29d03" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="c#"&gt;// 継承Adapter
class InheritanceSpeakAdapter : Duck, ISpeakable
{
	// しゃべる
	public void Speak()
	{
		// 基底クラスのメソッドを呼び出す
		Quack();
	}
}
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;継承型のAdapterパターンでは、インターフェースを適合させたいクラスを継承した上で、インターフェイスを実装します。&lt;/p&gt;
&lt;p&gt;そして、インターフェイスのメソッドを実装する際、基底クラスのメソッドを呼び出すように設定します。&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;それでは、実行してみましょう。&lt;/p&gt;
&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:11ead4ef-a047-47e8-9271-a9c4d419f99f" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="c#"&gt;class Program
{
	static void Main(string[] args)
	{
		// 人間がしゃべる
		{
			var speaker = new Human();
			speaker.Speak();
		}

		// アヒルがしゃべる
		{
			var speaker = new InheritanceSpeakAdapter();
			speaker.Speak();
		}
	}
}
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://masaru.wankuma.com/img/blogimg/24Adapter1_1461C/image.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://masaru.wankuma.com/img/blogimg/24Adapter1_1461C/image_thumb.png" width="513" height="225"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;同一の呼び出し方で、人間とアヒルにしゃべらせることができました。&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;次回は委譲型のAdapterパターンを紹介します。&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/masaru/aggbug/186913.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>まさる</dc:creator><title>デザインパターンを学ぶ～その23：Commandパターン(3)～</title><link>http://blogs.wankuma.com/masaru/archive/2010/01/07/184755.aspx</link><pubDate>Thu, 07 Jan 2010 23:45:00 GMT</pubDate><guid>http://blogs.wankuma.com/masaru/archive/2010/01/07/184755.aspx</guid><wfw:comment>http://blogs.wankuma.com/masaru/comments/184755.aspx</wfw:comment><comments>http://blogs.wankuma.com/masaru/archive/2010/01/07/184755.aspx#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://blogs.wankuma.com/masaru/comments/commentRss/184755.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/masaru/services/trackbacks/184755.aspx</trackback:ping><description>&lt;p&gt;&lt;a href="http://blogs.wankuma.com/masaru/archive/2008/11/21/161907.aspx"&gt;デザインパターンを学ぶ～その21：Commandパターン(1)～&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href="http://blogs.wankuma.com/masaru/archive/2009/01/06/165749.aspx"&gt;デザインパターンを学ぶ～その22：Commandパターン(2)～&lt;/a&gt;&lt;/p&gt; &lt;p&gt;と続いたCommandパターンの最後は、Undo機能を実装してみましょう。手順は次の通り。&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;ol&gt; &lt;li&gt;Do、UndoメソッドをもつIUndoableCommandインターフェイスを定義します。&lt;br&gt;&lt;/li&gt; &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:ca98dc58-c7fb-4ebc-a20c-231deb2c9c8b" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="c#"&gt;public interface IUndoableCommand
{
  void Do();
  void Undo();
}
&lt;/pre&gt;&lt;/div&gt;
&lt;li&gt;Receiverを定義します。今回はサンプルとしてCounterクラスを考えます。&lt;br&gt;&lt;/li&gt;
&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:bfbf2982-dad1-4a1a-886e-154f7451881e" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="c#"&gt;public class Counter
{
  public Counter(int initialValue)
  {
    Count = initialValue;
  }

  public void Up()
  {
    Count++;
  }

  public void Down()
  {
    Count--;
  }

  public int Count
  {
    get;
    private set;
  }
}
&lt;/pre&gt;&lt;/div&gt;
&lt;li&gt;Counterクラスに対し、カウントアップ、ダウンを行うCommandクラスを定義します。&lt;br&gt;&lt;/li&gt;
&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:882f0de3-1f6c-4a37-b45a-3b28a28c16d9" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="c#"&gt;public class CountUpCommand : IUndoableCommand
{
  private Counter counter;

  public CountUpCommand(Counter counter)
  {
    this.counter = counter;
  }

  public void Do()
  {
    counter.Up();
  }

  public void Undo()
  {
    counter.Down();
  }
}

public class CountDownCommand : IUndoableCommand
{
  private Counter counter;

  public CountDownCommand(Counter counter)
  {
    this.counter = counter;
  }

  public void Do()
  {
    counter.Down();
  }

  public void Undo()
  {
    counter.Up();
  }
}
&lt;/pre&gt;&lt;/div&gt;
&lt;li&gt;Undoに備えて何もしないNullCommandクラスも定義します。&lt;br&gt;&lt;/li&gt;
&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:5c1b5bdd-f065-4496-a00b-cfcd4ad5fc8a" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="c#"&gt;public class NullCommand : IUndoableCommand
{
  public void Do()
  {
  }

  public void Undo()
  {
  }
}
&lt;/pre&gt;&lt;/div&gt;
&lt;li&gt;Invokerとして、CountManagerクラスを定義します。&lt;br&gt;&lt;/li&gt;
&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:0015a4a3-2b3a-4443-9fd5-1db0030fcee3" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="c#"&gt;public class CountManager
{
  private IUndoableCommand upCommand;   // カウントアップ用Command
  private IUndoableCommand downCommand; // カウントダウン用Command
  private IUndoableCommand undoCommand; // Undo用Command

  public CountManager(IUndoableCommand upCommand, IUndoableCommand downCommand)
  {
    // 引数で渡されたCommandをフィールド設定
    this.upCommand = upCommand;
    this.downCommand = downCommand;
    
    // 最初はUndo操作をしても何もしないので、
    // NullCommandをundoCommandに設定
    this.undoCommand = new NullCommand();
  }

  public void DoUp()
  {
    // カウントアップ実行
    upCommand.Do();
    // 実行したCommandをundoCommandに設定
    undoCommand = upCommand;
  }

  public void DoDown()
  {
    // カウントダウン実行
    downCommand.Do();
    // 実行したCommandをundoCommandに設定
    undoCommand = downCommand;
  }

  public void Undo()
  {
    // Undo実行
    undoCommand.Undo();
    // Undoを連続して行えないよう、
    // NullCommandを設定
    undoCommand = new NullCommand();
  }
}
&lt;/pre&gt;&lt;/div&gt;&lt;/ol&gt;
&lt;p&gt;では、実行してみましょう。実行用コードは以下の通りです。&lt;/p&gt;
&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:1d27c54e-0f2d-4ffb-a871-5d3138db2efe" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="c#"&gt;class Program
{
  static void Main(string[] args)
  {
    // 新規カウンター（Receiver）作成
    Counter counter = new Counter(10);
    Console.WriteLine(counter.Count);

    // カウントアップ、ダウン用Commandクラスのインスタンス作成
    CountUpCommand cuc = new CountUpCommand(counter);
    CountDownCommand cdc = new CountDownCommand(counter);

    // CountManager（Invoker）を作成
    CountManager cm = new CountManager(cuc, cdc);

    // カウントアップ
    cm.DoUp();
    Console.WriteLine(counter.Count);

    // カウントダウン
    cm.DoDown();
    Console.WriteLine(counter.Count);

    // Undo
    cm.Undo();
    Console.WriteLine(counter.Count);

    // Undo
    cm.Undo();
    Console.WriteLine(counter.Count);
  }
}
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;実行結果は以下の通り。&lt;/p&gt;
&lt;p&gt;&lt;a href="http://masaru.wankuma.com/img/blogimg/23Command3_14642/image.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://masaru.wankuma.com/img/blogimg/23Command3_14642/image_thumb.png" width="505" height="206"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;一度目のUndoでカウンターが元に戻り、二度目のUndoではカウンターに変化がないことが確認できます。&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;さて、ここまでのやり方は一度しかUndoが出来ないものでした。これを複数回Undo可能にするにはどうすればいいのでしょうか？&lt;/p&gt;
&lt;p&gt;実はかなり簡単です。Invokerの中にStackとして実行したCommandを保持して、PopしながらUndoを行えばいいだけです。以下は、複数回のUndoを可能にしたCountManagerMultiUndoableです。&lt;/p&gt;
&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:24285080-cbd6-46b1-802a-de7bb6f524a6" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="c#"&gt;public class CountManagerMultiUndoable
{
  private IUndoableCommand upCommand;           // カウントアップ用Command
  private IUndoableCommand downCommand;         // カウントダウン用Command
  private Stack&amp;lt;IUndoableCommand&amp;gt; undoCommands; // Undo用CommandのStack

  public CountManagerMultiUndoable(IUndoableCommand upCommand, IUndoableCommand downCommand)
  {
    // 引数で渡されたCommandをフィールド設定
    this.upCommand = upCommand;
    this.downCommand = downCommand;

    // Stackを初期化
    undoCommands = new Stack&amp;lt;IUndoableCommand&amp;gt;();
  }

  public void DoUp()
  {
    // カウントアップ実行
    upCommand.Do();
    // 実行したCommandをStackにPush
    undoCommands.Push(upCommand);
  }

  public void DoDown()
  {
    // カウントダウン実行
    downCommand.Do();
    // 実行したCommandをStackにPush
    undoCommands.Push(downCommand);
  }

  public void Undo()
  {
    if (undoCommands.Count != 0)
    {
      // Stackが空でなければ、PopしてUndo実行
      var undoCommand = undoCommands.Pop();
      undoCommand.Undo();
    }
  }
}
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;では、実行してみましょう。先ほどと違って、Undoを3回行うようにしてみます。&lt;/p&gt;
&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:381561f3-fdb1-4c75-a733-c4d717238e67" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="c#"&gt;class Program
{
  static void Main(string[] args)
  {
    // 新規カウンター（Receiver）作成
    Counter counter = new Counter(10);
    Console.WriteLine(counter.Count);

    // カウントアップ、ダウン用Commandクラスのインスタンス作成
    CountUpCommand cuc = new CountUpCommand(counter);
    CountDownCommand cdc = new CountDownCommand(counter);

    // CountManager（Invoker）を作成
    CountManagerMultiUndoable cm = new CountManagerMultiUndoable(cuc, cdc);

    // カウントアップ
    cm.DoUp();
    Console.WriteLine(counter.Count);

    // カウントダウン
    cm.DoDown();
    Console.WriteLine(counter.Count);

    // Undo
    cm.Undo();
    Console.WriteLine(counter.Count);

    // Undo
    cm.Undo();
    Console.WriteLine(counter.Count);

    // Undo
    cm.Undo();
    Console.WriteLine(counter.Count);
  }
}
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;実行結果は以下の通りです。&lt;/p&gt;
&lt;p&gt;&lt;a href="http://masaru.wankuma.com/img/blogimg/23Command3_14642/image_3.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://masaru.wankuma.com/img/blogimg/23Command3_14642/image_thumb_3.png" width="481" height="206"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;2度Undoが行われ、3度目は何もカウンターに変化がないことが確認できます。&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;ここまで3回にわたりCommandパターンを紹介しましたが、いかがでしたでしょうか？&lt;/p&gt;
&lt;p&gt;Commandパターンは他にも、&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;QueueにCommandオブジェクトを登録して順次呼び出す&lt;/li&gt;
&lt;li&gt;Commandオブジェクトを永続化して、必要な際に取り出して呼び出す&lt;/li&gt;
&lt;li&gt;Commandオブジェクトを直列化（シリアライズ）して、ネットワークなどの境界を越えて実行&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;など、色々と活用する場面があるようです。&lt;/p&gt;
&lt;p&gt;私も今後もどのように有効に活用できるか考えていきたいと思います。&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;昨年はまったくと言っていいほど進まなかった、このデザインパターンシリーズ。今年はがんばってやっていこうと思います。次回は「Adapterパターン」に入っていくつもりですので、今後ともお付き合いをお願いします。&lt;/p&gt;
&lt;p&gt;なお、今後コードはC#のみとさせてもらいます。案外VBにportするのが大変なものでf(^^;&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/masaru/aggbug/184755.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>まさる</dc:creator><title>FizzBuzz＞これは何パターンなんだろ？</title><link>http://blogs.wankuma.com/masaru/archive/2009/10/21/182278.aspx</link><pubDate>Wed, 21 Oct 2009 00:18:00 GMT</pubDate><guid>http://blogs.wankuma.com/masaru/archive/2009/10/21/182278.aspx</guid><wfw:comment>http://blogs.wankuma.com/masaru/comments/182278.aspx</wfw:comment><comments>http://blogs.wankuma.com/masaru/archive/2009/10/21/182278.aspx#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://blogs.wankuma.com/masaru/comments/commentRss/182278.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/masaru/services/trackbacks/182278.aspx</trackback:ping><description>&lt;p&gt;FizzBuzz祭りでいじくってて出来たコードの断片。&lt;/p&gt; &lt;p&gt; &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:a4b17af7-e298-4032-8d04-50d607b58bef" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="c#"&gt;using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
  class FizzBuzzSpeaker
  {
    private int number;
    private FizzBuzzSpeaker child;

    public FizzBuzzSpeaker(int number, FizzBuzzSpeaker speaker)
    {
      this.number = number;
      this.child = speaker;
    }

    public void Speak()
    {
      if (this.child != null)
      {
        this.child.Speak();
      }

      Console.WriteLine(
        this.number % 3 == 0 &amp;amp;&amp;amp; this.number % 5 == 0 ? "FizzBuzz"
        : this.number % 3 == 0 ? "Fizz"
        : this.number % 5 == 0 ? "Buzz"
        : number.ToString()
        );
    }
  }
  class Program
  {
    static void Main(string[] args)
    {
      FizzBuzzSpeaker speaker = null;
      for (var n = 1; n &amp;lt;= 30; n++)
      {
        speaker = new FizzBuzzSpeaker(n, speaker);
      }
      speaker.Speak();
    }
  }
}&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;Decoratorのような、Chain-of-Responsibilityのような、どちらでもないような？&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/masaru/aggbug/182278.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>まさる</dc:creator><title>FizzBuzz＞それChain-of-Responsibilityパターンで</title><link>http://blogs.wankuma.com/masaru/archive/2009/10/13/182059.aspx</link><pubDate>Tue, 13 Oct 2009 08:05:00 GMT</pubDate><guid>http://blogs.wankuma.com/masaru/archive/2009/10/13/182059.aspx</guid><wfw:comment>http://blogs.wankuma.com/masaru/comments/182059.aspx</wfw:comment><comments>http://blogs.wankuma.com/masaru/archive/2009/10/13/182059.aspx#Feedback</comments><slash:comments>848</slash:comments><wfw:commentRss>http://blogs.wankuma.com/masaru/comments/commentRss/182059.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/masaru/services/trackbacks/182059.aspx</trackback:ping><description>&lt;p&gt;ネタ元→&lt;a href="http://blogs.wankuma.com/episteme/archive/2009/10/12/182047.aspx"&gt;無意味に難解なFizzBuzz&lt;/a&gt;&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;Decoratorパターンだとぅ?&lt;br&gt;そんじゃこちとらChain-of-Responsibilityパターンで&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;C#にportぢゃ！うら！&lt;/p&gt; &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:49f698dc-b0af-4c1d-aece-a37c815228f6" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="c#"&gt;using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
  abstract class Checker
  {
    public abstract bool Equals(int n);
  }

  class Holder
  {
    private Checker checker;
    public Holder(Checker checker)
    {
      this.checker = checker;
    }
    public bool Equals(int n)
    {
      return this.checker.Equals(n);
    }
  }

  class FizzBuzz : Checker
  {
    private int mod;
    private string word;
    public FizzBuzz(int mod, string word)
    {
      this.mod = mod;
      this.word = word;
    }

    public override bool Equals(int n)
    {
      if (n % mod != 0)
      {
        return false;
      }
      Console.WriteLine("{0}({1})", word, n);
      return true;
    }
  }

  class Program
  {
    static void Main(string[] args)
    {
      List&amp;lt;Holder&amp;gt; holders = new List&amp;lt;Holder&amp;gt;();
      holders.Add(new Holder(new FizzBuzz(15, "FizzBuzz")));
      holders.Add(new Holder(new FizzBuzz(3, "Fizz")));
      holders.Add(new Holder(new FizzBuzz(5, "Buzz")));

      for (var i = 1; i &amp;lt;= 30; i++)
      {
        bool hit = false;
        foreach (var holder in holders)
        {
          if (holder.Equals(i))
          {
            hit = true;
            break;
          }
        }
        if (!hit)
        {
          Console.WriteLine("{0} ", i);
        }
      }
    }
  }
}
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://masaru.wankuma.com/img/blogimg/FizzBuzzChainofResponsibility_7115/image.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://masaru.wankuma.com/img/blogimg/FizzBuzzChainofResponsibility_7115/image_thumb.png" width="841" height="692"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;＃合ってるかしら？f(^^;&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/masaru/aggbug/182059.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>まさる</dc:creator><title>FizzBuzz＞それDecoratorパターンで（改）</title><link>http://blogs.wankuma.com/masaru/archive/2009/10/12/182043.aspx</link><pubDate>Mon, 12 Oct 2009 08:15:00 GMT</pubDate><guid>http://blogs.wankuma.com/masaru/archive/2009/10/12/182043.aspx</guid><wfw:comment>http://blogs.wankuma.com/masaru/comments/182043.aspx</wfw:comment><comments>http://blogs.wankuma.com/masaru/archive/2009/10/12/182043.aspx#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://blogs.wankuma.com/masaru/comments/commentRss/182043.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/masaru/services/trackbacks/182043.aspx</trackback:ping><description>&lt;p&gt;&lt;a href="http://blogs.wankuma.com/masaru/archive/2009/10/03/181803.aspx"&gt;FizzBuzz＞それLINQで＞それワンライナーで&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href="http://blogs.wankuma.com/masaru/archive/2009/10/06/181924.aspx"&gt;FizzBuzz＞それyield returnで&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href="http://blogs.wankuma.com/masaru/archive/2009/10/12/182042.aspx"&gt;FizzBuzz＞それDecoratorパターンで&lt;/a&gt;&lt;/p&gt; &lt;p&gt;の続き。&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;よく考えたら逆順にぶっこむ必要がなかったので、改訂版を。&lt;/p&gt; &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:2e7a6bc5-4f0b-4be0-95be-50ce0a1441fd" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="c#"&gt;using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
  // FizzBuzzのもと
  public abstract class FizzBuzzBase
  {
    // 中の人
    public FizzBuzzBase FizzBuzz { get; private set; }

    // しゃべる言葉
    public abstract string Word { get; }

    // 中の人をセット
    public FizzBuzzBase(FizzBuzzBase fizzbuzz)
    {
      this.FizzBuzz = fizzbuzz;
    }

    // しゃべれ
    public void Speak()
    {
      // 中の人にしゃべらせる
      if (this.FizzBuzz != null)
      {
        this.FizzBuzz.Speak();
      }

      // 自分がしゃべる
      Console.WriteLine(Word);
    }
  }

  // Fizz
  public class Fizz : FizzBuzzBase
  {
    public Fizz(FizzBuzzBase fizzbuzz)
      : base(fizzbuzz)
    {
    }

    public override string Word
    {
      get { return "Fizz"; }
    }
  }

  // Buzz
  public class Buzz : FizzBuzzBase
  {
    public Buzz(FizzBuzzBase fizzbuzz)
      : base(fizzbuzz)
    {
    }

    public override string Word
    {
      get { return "Buzz"; }
    }
  }

  // FizzBuzz
  public class FizzBuzz : FizzBuzzBase
  {
    public FizzBuzz(FizzBuzzBase fizzbuzz)
      : base(fizzbuzz)
    {
    }

    public override string Word
    {
      get { return "FizzBuzz"; }
    }
  }

  // 数字
  public class Number : FizzBuzzBase
  {
    private int number;

    public Number(int number, FizzBuzzBase fizzbuzz)
      : base(fizzbuzz)
    {
      this.number = number;
    }

    public override string Word
    {
      get { return this.number.ToString(); }
    }
  }

  // メイン
  class Program
  {
    static void Main(string[] args)
    {
      FizzBuzzBase fizzbuzz = null;
      foreach (int i in Enumerable.Range(1, 20))
      {
        if (i % 3 == 0 &amp;amp;&amp;amp; i % 5 == 0)
        {
          fizzbuzz = new FizzBuzz(fizzbuzz);
        }
        else if (i % 3 == 0)
        {
          fizzbuzz = new Fizz(fizzbuzz);
        }
        else if (i % 5 == 0)
        {
          fizzbuzz = new Buzz(fizzbuzz);
        }
        else
        {
          fizzbuzz = new Number(i, fizzbuzz);
        }
      }

      // しゃべれ
      fizzbuzz.Speak();
    }
  }
}
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;違うのはFizzBuzzBaseクラスのSpeakメソッドの中身。&lt;/p&gt;
&lt;p&gt;中の人にしゃべらせてから、自分がしゃべればいいだけでしたf(^^;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;一応実行結果。&lt;/p&gt;
&lt;p&gt;&lt;a href="http://masaru.wankuma.com/img/blogimg/FizzBuzzDecorator_73D3/image.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://masaru.wankuma.com/img/blogimg/FizzBuzzDecorator_73D3/image_thumb.png" width="697" height="458"&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/masaru/aggbug/182043.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>まさる</dc:creator><title>FizzBuzz＞それDecoratorパターンで</title><link>http://blogs.wankuma.com/masaru/archive/2009/10/12/182042.aspx</link><pubDate>Mon, 12 Oct 2009 08:09:00 GMT</pubDate><guid>http://blogs.wankuma.com/masaru/archive/2009/10/12/182042.aspx</guid><wfw:comment>http://blogs.wankuma.com/masaru/comments/182042.aspx</wfw:comment><comments>http://blogs.wankuma.com/masaru/archive/2009/10/12/182042.aspx#Feedback</comments><slash:comments>42</slash:comments><wfw:commentRss>http://blogs.wankuma.com/masaru/comments/commentRss/182042.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/masaru/services/trackbacks/182042.aspx</trackback:ping><description>&lt;p&gt;&lt;a href="http://blogs.wankuma.com/masaru/archive/2009/10/03/181803.aspx"&gt;FizzBuzz＞それLINQで＞それワンライナーで&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href="http://blogs.wankuma.com/masaru/archive/2009/10/06/181924.aspx"&gt;FizzBuzz＞それyield returnで&lt;/a&gt;&lt;/p&gt; &lt;p&gt;の続き。&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;FizzBuzzを「いかに面倒に解くか」みたいになってるので、Decoratorパターンでやってみた。&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:34a3bb91-4913-4bcd-b8c1-53e5f587f9a3" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="c#"&gt;using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
  // FizzBuzzのもと
  public abstract class FizzBuzzBase
  {
    // 中の人
    public FizzBuzzBase FizzBuzz { get; private set; }

    // しゃべる言葉
    public abstract string Word { get; }

    // 中の人をセット
    public FizzBuzzBase(FizzBuzzBase fizzbuzz)
    {
      this.FizzBuzz = fizzbuzz;
    }

    // しゃべれ
    public void Speak()
    {
      Console.WriteLine(Word);

      // 中の人にしゃべらせる
      if (this.FizzBuzz != null)
      {
        this.FizzBuzz.Speak();
      }
    }
  }

  // Fizz
  public class Fizz : FizzBuzzBase
  {
    public Fizz(FizzBuzzBase fizzbuzz)
      : base(fizzbuzz)
    {
    }

    public override string Word
    {
      get { return "Fizz"; }
    }
  }

  // Buzz
  public class Buzz : FizzBuzzBase
  {
    public Buzz(FizzBuzzBase fizzbuzz)
      : base(fizzbuzz)
    {
    }

    public override string Word
    {
      get { return "Buzz"; }
    }
  }

  // FizzBuzz
  public class FizzBuzz : FizzBuzzBase
  {
    public FizzBuzz(FizzBuzzBase fizzbuzz)
      : base(fizzbuzz)
    {
    }

    public override string Word
    {
      get { return "FizzBuzz"; }
    }
  }

  // 数字
  public class Number : FizzBuzzBase
  {
    private int number;

    public Number(int number, FizzBuzzBase fizzbuzz)
      : base(fizzbuzz)
    {
      this.number = number;
    }

    public override string Word
    {
      get { return this.number.ToString(); }
    }
  }

  // メイン
  class Program
  {
    static void Main(string[] args)
    {
      FizzBuzzBase fizzbuzz = null;
      // 1からしゃべらせるため、逆からぶっこむ
      foreach (int i in Enumerable.Range(1, 20).Reverse())
      {
        if (i % 3 == 0 &amp;amp;&amp;amp; i % 5 == 0)
        {
          fizzbuzz = new FizzBuzz(fizzbuzz);
        }
        else if (i % 3 == 0)
        {
          fizzbuzz = new Fizz(fizzbuzz);
        }
        else if (i % 5 == 0)
        {
          fizzbuzz = new Buzz(fizzbuzz);
        }
        else
        {
          fizzbuzz = new Number(i, fizzbuzz);
        }
      }

      // しゃべれ
      fizzbuzz.Speak();
    }
  }
}
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://masaru.wankuma.com/img/blogimg/FizzBuzzDecorator_71D2/image.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://masaru.wankuma.com/img/blogimg/FizzBuzzDecorator_71D2/image_thumb.png" width="689" height="458"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;うん、上々♪&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/masaru/aggbug/182042.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>まさる</dc:creator><title>VBでProducer/Consumerパターン</title><link>http://blogs.wankuma.com/masaru/archive/2009/09/16/181309.aspx</link><pubDate>Wed, 16 Sep 2009 22:31:00 GMT</pubDate><guid>http://blogs.wankuma.com/masaru/archive/2009/09/16/181309.aspx</guid><wfw:comment>http://blogs.wankuma.com/masaru/comments/181309.aspx</wfw:comment><comments>http://blogs.wankuma.com/masaru/archive/2009/09/16/181309.aspx#Feedback</comments><slash:comments>10</slash:comments><wfw:commentRss>http://blogs.wankuma.com/masaru/comments/commentRss/181309.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/masaru/services/trackbacks/181309.aspx</trackback:ping><description>&lt;p&gt;ネタ元：&lt;a href="http://blogs.wankuma.com/episteme/archive/2009/09/16/181289.aspx"&gt;生産者 と 消費者&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;＃勝手にportしちゃうぞ企画第２段ｗ&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;今回はMSDNライブラリ「&lt;a href="http://msdn.microsoft.com/ja-jp/library/yy12yx1f.aspx"&gt;方法 : producer スレッドと consumer スレッドを同期する (C# プログラミング ガイド)&lt;/a&gt;」のコードをVBにportしました。&lt;/p&gt; &lt;p&gt;VBに変換する際気を付けるのは、以下のような点。&lt;/p&gt; &lt;ul&gt; &lt;li&gt;lockステートメントはSyncLock  &lt;li&gt;配列の初期化方法が違う&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;コードは以下の通り。&lt;/p&gt; &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:575fc333-ef35-416d-84bf-46aa62182276" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="vb"&gt;Imports System.Threading

Public Class SyncEvents
	Private _newItemEvent As EventWaitHandle
	Public ReadOnly Property NewItemEvent() As EventWaitHandle
		Get
			Return _newItemEvent
		End Get
	End Property

	Private _exitThreadEvent As EventWaitHandle
	Public ReadOnly Property ExitThreadEvent() As EventWaitHandle
		Get
			Return _exitThreadEvent
		End Get
	End Property

	Private _eventArray As WaitHandle()
	Public ReadOnly Property EventArray() As WaitHandle()
		Get
			Return _eventArray
		End Get
	End Property

	Public Sub New()
		_newItemEvent = New AutoResetEvent(False)
		_exitThreadEvent = New ManualResetEvent(False)
		_eventArray = New WaitHandle() {_newItemEvent, _exitThreadEvent}
	End Sub
End Class

Public Class Producer
	Private _queue As Queue(Of Integer)
	Private _syncEvents As SyncEvents

	Public Sub New(ByVal q As Queue(Of Integer), ByVal e As SyncEvents)
		_queue = q
		_syncEvents = e
	End Sub

	Public Sub ThreadRun()
		Dim count As Integer = 0
		Dim r As New Random()
		While Not _syncEvents.ExitThreadEvent.WaitOne(0, False)
			SyncLock DirectCast(_queue, ICollection).SyncRoot
				While _queue.Count &amp;lt; 20
					_queue.Enqueue(r.Next(0, 100))
					_syncEvents.NewItemEvent.Set()
					count += 1
				End While
			End SyncLock
		End While
		Console.WriteLine("Producer thread: produced {0} items", count)
	End Sub
End Class

Public Class Consumer
	Private _queue As Queue(Of Integer)
	Private _syncEvents As SyncEvents

	Public Sub New(ByVal q As Queue(Of Integer), ByVal e As SyncEvents)
		_queue = q
		_syncEvents = e
	End Sub

	Public Sub ThreadRun()
		Dim count As Integer = 0
		While WaitHandle.WaitAny(_syncEvents.EventArray) &amp;lt;&amp;gt; 1
			SyncLock DirectCast(_queue, ICollection).SyncRoot
				Dim item As Integer = _queue.Dequeue()
				count += 1
			End SyncLock
		End While
		Console.WriteLine("Consumer thread: consumed {0} items", count)
	End Sub
End Class

Public Class Program
	Private Shared Sub ShowQueueContents(ByVal q As Queue(Of Integer))
		SyncLock DirectCast(q, ICollection).SyncRoot
			For Each item As Integer In q
				Console.Write("{0} ", item)
			Next
		End SyncLock
		Console.WriteLine()
	End Sub

	Public Shared Sub Main()
		Dim queue As New Queue(Of Integer)
		Dim syncEvent As New SyncEvents()

		Console.WriteLine("Configuring worker threads...")

		Dim producer As New Producer(queue, syncEvent)
		Dim cunsumer As New Consumer(queue, syncEvent)

		Dim producerThread As New Thread(AddressOf producer.ThreadRun)
		Dim consumerThread As New Thread(AddressOf cunsumer.ThreadRun)

		Console.WriteLine("Launching producer and consumer threads...")

		producerThread.Start()
		consumerThread.Start()

		For i As Integer = 0 To 3
			Thread.Sleep(2500)
			ShowQueueContents(queue)
		Next i

		Console.WriteLine("Signaling threadds to terminate...")

		syncEvent.ExitThreadEvent.Set()

		producerThread.Join()
		consumerThread.Join()
	End Sub
End Class&lt;/pre&gt;&lt;/div&gt;&lt;img src ="http://blogs.wankuma.com/masaru/aggbug/181309.aspx" width = "1" height = "1" /&gt;</description></item></channel></rss>