// 下階層用テンプレート
#topicpath
----
//ここにコンテンツを記述します。
#contents
JavaではイベントハンドラなどObserver/Subjectなパタンは下記のようなコードになりますが、C#ではdelegateやeventなど言語レベルでいろいろサポートされてるみたいです
** まずはJavaで [#i8c4ed03]
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っぽく [#w907eec3]
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を使ってみる [#hd16a74c]
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を使う [#t8f4f79b]
続いて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"); <-これはコンパイルエラーになる。
}
なるほどー
**関連リンク [#ycdd5284]
-[[イベント>http://wisdom.sakura.ne.jp/programming/cs/cs56.html]]
-[[[Examples] Log of /trunk/ObserverSampleC/ObserverSample/Program2.cs>http://www.masatom.in/viewvc/Examples/trunk/ObserverSampleC/ObserverSample/Program2.cs?view=log]]
----
この記事は
#vote(おもしろかった,そうでもない)
#comment
#topicpath
SIZE(10){現在のアクセス:&counter;}