JavaではイベントハンドラなどObserver/Subjectなパタンは下記のようなコードになりますが、C#ではdelegateやeventなど言語レベルでいろいろサポートされてるみたいです

まずはJavaで

public class Program {
    public static void main(String[] str) {
        new Program();
    }

    public Program() {
        Subject obj = new Subject("hogehoge");
        obj.addObserver(new MyObserver());
        obj.notifyObservers();
    }

    static void action(String str) {
        System.out.println(str);
    }

    class MyObserver implements Observer {
        public void update(String str) {
            action(str);
        }
    }
}
interface Observer {
    void update(String str);
}
class Subject {
    private String str;

    private Observer observer;

    public Subject(String str) {
        this.str = str;
    }

    public void notifyObservers() {
        observer.update(str);
    }

    public void addObserver(Observer observer) {
        this.observer = observer;
    }
}

こんなヤツですね

まずはC#でJavaっぽく

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ObserverSample
{
    class Program
    {
        static void Main(string[] args)
        {
            new Program();
        }

        public Program()
        {
            Subject obj = new Subject("hogehoge");
            obj.addObserver(new MyObserver());
            obj.notifyObservers();
        }

        static void Action(String str)
        {
            Console.WriteLine(str);
        }

        class MyObserver : Observer
        {
            public void update(String str)
            {
                Action(str);
            }
        }
    }
}
namespace ObserverSample
{
// 以下はJavaと全く同じコード
    interface Observer
    {
        void update(String str);
    }

    class Subject
    {
        private String str;

        private Observer observer;

        public Subject(String str)
        {
            this.str = str;
        }

        public void notifyObservers()
        {
            observer.update(str);
        }

        public void addObserver(Observer observer)
        {
            this.observer = observer;
        }
    }
}

次にC#でdelegateを使ってみる

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ObserverSample2
{
    class Program
    {
        static void Main(string[] args)
        {
            new Program();
        }

        public Program()
        {
            Subject obj = new Subject("hogehoge");
            obj.update += new update(Action);  //<-C#ではこうやってObserverを追加する
            //obj.addObserver(new MyObserver());
            obj.notifyObservers();
        }

        static void Action(String str)
        {
            Console.WriteLine(str);
        }

        //class MyObserver : Observer
        //{
        //    public void update(String str)
        //    {
        //        Action(str);
        //    }
        //}
    }
}


namespace ObserverSample2
{
    // Observerのインタフェースは使わない
    //interface Observer
    //{
    //    void update(String str);
    //}

    // Observerのインタフェース(リスナ)のメソッドをdelegateで宣言
    delegate void update(String str);

    class Subject
    {
        private String str;

        // フィールドの変数をdelegateに変更する
        //private Observer observer;
        public update update;  // <-実はdelegate

        public Subject(String str)
        {
            this.str = str;
        }

        public void notifyObservers()
        {
            //observer.update(str);
            update(str); //delegateに処理を委譲する
        }

        // addは使わない(+=で追加するので)
        //public void addObserver(Observer observer)
        //{
        //    this.observer = observer;
        //}
    }
}

これでいいみたいです。これいいですね

  • 余計なインタフェースがいらなくて、処理がすっきりする
  • addObserverとかremoveObserverとか書かなくても+=,-=で追加削除ができる
  • SubjectのフィールドをSetとかMapにしなくても
     obj.update += new update(Action1);  //<-C#ではこうやってObserverを追加する
     obj.update += new update(Action2);  //<-C#ではこうやってObserverを追加する
    などとして追加削除ができる

などなどいろいろメリットがありますね

eventを使う

続いてeventを使ってみます。eventは基本的にはdelegateと同じみたいですが、委譲するメソッドとなる

update(str);

を外から直接呼び出せなくなるなど、いくつかイベントハンドラ向けの機構が備わってるみたいです

指定方法は

   public update update;
-> public event update update;

ってするだけですね。呼び出す側のコードはこれまでと同じです

public Program()
{
    Subject obj = new Subject("hogehoge");
    obj.update += new update(Action);
    obj.notifyObservers();
    // obj.update("hoge");  <-これはコンパイルエラーになる。
}

なるほどー

関連リンク


この記事は

選択肢 投票
おもしろかった 0  
そうでもない 0  

現在のアクセス:2804


トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2010-12-11 (土) 22:23:09 (4882d)