どのようすについて説明していただけま、オブザーバーパターンの初心者養成講座を開催します。
-
12-09-2019 - |
質問
現在、私の理解では、以下のすべての符号化の事例のいくつかのオブザーバーパターンです。私の理解では、単純にしているほとんどの契約をもとに更新する他のすべてのイベントの変更が行われた場合には、委譲が登録するしかし、私は非常に不安定で自分の真の理解を利用します。もちろん、一部のgooglingが、そのほとんどは上記のレベルです。
監督-選手コメンをこのパターンと現在の私の宿題をする、真の意味自分のプロジェクトが必要なより良い理解のパターンとかを例に見えます。ならないようにしたい力でこのパターンなのだけを提出しながらプレーする必要がありま理解する目的で、自分の手法に従ってその実しています。私のテキストなんで、つでも配布しています。MSDNた私には難解で、私は初心者です、それをより高度な話題です。
どのようなところこのオブザーバーパターンとその利用にC#る 初心者? 例に保管してくださいコードは非常に簡単な内容を理解することができ、目的以上に複雑なコード断片.ようにしていることの簡単なテキストボックスの文字列操作を委譲のための私の課題でポインタが助かります!
解決
私が思い付くことができる最高の例では、(一例として)メーリングリストのことです。
あなたは、観察者は、メーリングリストを購読すると、あなたは、リストを観察します。あなたは、もはやリストに興味があるときは、退会ません。
このコンセプトは、Observerパターンです。二つ以上のクラスが関与しています。一つ以上のクラスは、通知されますパブリッシャークラス(別の名前がある)、その後、最初のクラス(およびすべてのサブスクライブクラス)に加入する際に、これまで発行者の欲望ます。
これは、私がしばしばプログラミングやデザイン理論についての私のrantingsに耳を傾け、私の妻、それを説明する方法です。それは彼女に意味を成していました。私はこれがあなたのために単純すぎるかもしれません実現が、良いスタートです...
よろしく、
フランク
他のヒント
「デザインパターンヘッドファースト」をチェックしてください - あなたの-額の主要なパターンの説明に従うことは簡単。
オブザーバーのために、1対多の関係を説明し、変更があったときに、他のクラスを伝えるためのサブスクリプションモデルを使用していることを理解することが重要です。これらの線に沿っRSS、Atomの、そしてTwitterの仕事ます。
のオブザーバーがいものに変更で採用になれます。対象を知らない観察者。この重要な一部です。の対象だけを定義するインターフェイス(または代理人)のオブザーバーニーズを更新することができ、登録されます。
短:のオブザーバーパターンでオブザーバを呼び出すことができる、しない介護者のオブザーバーの場合でも存在します。
二つのオブジェクトNOTIFIERとOBSERVERがあります。観察者がNOTIFERがイベントを実装していることを知っていながらNotifierは、OBSERVERについて何も知らない。
OBSERVERは、何かが起こった他のオブジェクトに通知するためにイベントを使用しています。単にイベントはメソッドのリストである話。観察者が何かが起こった場合に通知されることを望んでいるので、観察者がNOTIFERのイベントに、何かが起こる場合に呼び出されるべきメソッドを追加します。
事が起こった場合、そのNotifierは、このイベントを発行しますので、、Notifierはちょうどメソッドのリストの上に歩くと、それらを呼び出します。 OBSERVERで追加されたメソッドが呼び出されると、観察者は事が起こった、これまでこのような場合に必要とされるものを行うことができることを知っている。
ここValueChanged()
イベントに例示通知クラスです。
// Declare how a method must look in order to be used as an event handler.
public delegate void ValueChangedHandler(Notifier sender, Int32 oldValue, Int32 newValue);
public class Notifier
{
// Constructor with an instance name.
public Notifier(String name)
{
this.Name = name;
}
public String Name { get; private set; }
// The event that is raised when ChangeValue() changes the
// private field value.
public event ValueChangedHandler ValueChanged;
// A method that modifies the private field value and
// notifies observers by raising the ValueChanged event.
public void ChangeValue(Int32 newValue)
{
// Check if value really changes.
if (this.value != newValue)
{
// Safe the old value.
Int32 oldValue = this.value;
// Change the value.
this.value = newValue;
// Raise the ValueChanged event.
this.OnValueChanged(oldValue, newValue);
}
}
private Int32 value = 0;
// Raises the ValueChanged event.
private void OnValueChanged(Int32 oldValue, Int32 newValue)
{
// Copy the event handlers - this is for thread safty to
// avoid that somebody changes the handler to null after
// we checked that it is not null but before we called
// the handler.
ValueChangedHandler valueChangedHandler = this.ValueChanged;
// Check if we must notify anybody.
if (valueChangedHandler != null)
{
// Call all methods added to this event.
valueChangedHandler(this, oldValue, newValue);
}
}
}
ここでは一例オブザーバクラスます。
public class Observer
{
// Constructor with an instance name.
public Observer(String name)
{
this.Name = name;
}
public String Name { get; private set; }
// The method to be registered as event handler.
public void NotifierValueChanged(Notifier sender, Int32 oldValue, Int32 newValue)
{
Console.WriteLine(String.Format("{0}: The value of {1} changed from {2} to {3}.", this.Name, sender.Name, oldValue, newValue));
}
}
小テストアプリケーション
class Program
{
static void Main(string[] args)
{
// Create two notifiers - Notifier A and Notifier B.
Notifier notifierA = new Notifier("Notifier A");
Notifier notifierB = new Notifier("Notifier B");
// Create two observers - Observer X and Observer Y.
Observer observerX = new Observer("Observer X");
Observer observerY = new Observer("Observer Y");
// Observer X subscribes the ValueChanged() event of Notifier A.
notifierA.ValueChanged += observerX.NotifierValueChanged;
// Observer Y subscribes the ValueChanged() event of Notifier A and B.
notifierA.ValueChanged += observerY.NotifierValueChanged;
notifierB.ValueChanged += observerY.NotifierValueChanged;
// Change the value of Notifier A - this will notify Observer X and Y.
notifierA.ChangeValue(123);
// Change the value of Notifier B - this will only notify Observer Y.
notifierB.ChangeValue(999);
// This will not notify anybody because the value is already 123.
notifierA.ChangeValue(123);
// This will not notify Observer X and Y again.
notifierA.ChangeValue(1);
}
}
出力は次のようになります。
Observer X: The value of Notifier A changed from 0 to 123. Observer Y: The value of Notifier A changed from 0 to 123. Observer Y: The value of Notifier B changed from 0 to 999. Observer X: The value of Notifier A changed from 123 to 1. Observer Y: The value of Notifier A changed from 123 to 1.<時間>
私はクラスの種類とそれらを比較するつもりデリゲート型を理解するために。
public class Example
{
public void DoSomething(String text)
{
Console.WriteLine(
"Doing something with '" + text + "'.");
}
public void DoSomethingElse(Int32 number)
{
Console.WriteLine(
"Doing something with '" + number.ToString() + "'.");
}
}
我々は2つのメソッドを持つ単純なクラスExample
を定義しました。今、私たちは、このクラスの型を使用することができます。
Example example = new Example();
これは、型が一致しないので、以下は動作しません動作しますが。あなたは、コンパイラエラーを取得します。
Example example = new List<String>();
そして、私たちは、変数example
を使用することができます。
example.DoSomething("some text");
今デリゲート型と同じ。まず、デリゲート型を定義する - これは前にクラス定義のような単なる型定義である
。public delegate void MyDelegate(String text);
今、私たちは、デリゲート型を使用することができますが、我々は、通常のデリゲート型の変数のデータが、メソッドを保存することはできません。
MyDelegate method = example.DoSomething;
現在のオブジェクトDoSomething()
の方法example
を格納しています。私たちは、デリゲートは1つの文字列パラメータを取り、voidを返すようMyDelegate
を定義したので、次は動作しません。 DoSomethingElse
はvoidを返していますが、コンパイラのエラーを取得するように、整数パラメータを取ります。
MyDelegate method = example.DoSomethingElse;
そして最後に、あなたは変数method
を使用することができます。あなたは、変数に格納するので何のデータが、メソッドをデータ操作を行うことはできません。しかし、あなたは変数に保存されているメソッドを呼び出すことができます。
method("Doing stuff with delegates.");
これは、私たちが変数に格納されたメソッドを呼び出します - 。example.DoSomething()
を
オブザーバーパターンは、それが聞こえるだけのようである -
これは、いくつかのオブジェクトが変更のためにそれを観察し、オブジェクトを鑑賞するための手段です。
イベントは、基本的にオブザーバーパターンを実装する言語固有の手段であるので、C#では、これは、多少簡単になります。あなたは今までのイベントを使用している場合は、オブザーバーパターンを使用しました。
他の言語では、これが内蔵されていないので、これを扱うためのアプローチを形式化するために多くの試みがなされてきています。
オブザーバーは、通信の直接ラインのようなものです。持っているというよりも、あなたが病気の書き込みにカードを取得し、興味を持っている誰もがそれ(またはコピー)を取得するときに、すべてのあなたの親戚は、あなたがどのように見つけるためにあなたを呼び出します。あなたが良くなるとき、あなたはカードを送り出します。あなたのつま先をスタブするとき、あなたはカードを送り出します。あなたがAを取得すると、あなたはカードを送っています。
気に誰もがあなたのマスメーリングリストに取得し、彼らが合うが応答することができます。
この依存性は、UIに最適です。私は、(例えば)遅いプロセスを持っている場合、それは進歩が行われた場合でも発射できます。プログレスバーの要素はそれを観察し、その適用範囲を更新することができます。 OKボタンはそれを観察し、100%でアクティブになる可能性があります。カーソルが進行するまでアニメーションが100%であることを観察することができました。これらの観測者はいずれも、お互いについて知る必要はありません。さらに、これらの要素のどれもが、厳密にどちらかそれらを駆動しているかを知る必要はありません。
このパターンは世界中で最も基本的ない場合には最も基本的なパターンがあります。
があり"人"に関;の 出版社 の 契約者/オブザーバー.
オブザーバーを尋ねて、出版社に通知した場合は"ニュース". ニュースでも重要です。できる空気の温度はできるので、新しい投稿、ウェブサイト上で可能です。
おそらく、あなたは適切なインタフェースを定義しているとのトラブルを抱えている事。インタフェースは、サブスクライバとパブリッシャとの間の相互作用を定義します。
まず
C#のWinFormsのアプリケーションを作りますこのようなセットアップのProgram.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
interface IObserver
{
void Refresh(List<string> DisplayList);
}
class ObserverList : List<IObserver>
{
public void Refresh(List<String> DisplayList)
{
foreach (IObserver tItem in this)
{
tItem.Refresh(DisplayList);
}
}
}
}
ここでは二つのことを行っています。加入者が実装する最初のインターフェイス。すべてのサブスクライバを保持するために、出版社のために、リストます。
そして、その後、テキストボックスを追加する二つのボタン、1つの標識された様式2及びその他の標識された形態3でフォーム1にし、その後、別のボタンラベルの追加
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
private List<string> DataList= new List<string>();
private ObserverList MyObservers = new ObserverList();
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Form2 frmNewForm = new Form2();
MyObservers.Add(frmNewForm);
frmNewForm.Show();
MyObservers.Refresh(DataList);
}
private void button2_Click(object sender, EventArgs e)
{
Form3 frmNewForm = new Form3();
MyObservers.Add(frmNewForm);
frmNewForm.Show();
MyObservers.Refresh(DataList);
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void button3_Click(object sender, EventArgs e)
{
DataList.Add(textBox1.Text);
MyObservers.Refresh(DataList);
textBox1.Text = "";
}
}
}
私は意図的にForm2をボタンとフォームの各タイプの複数のコピーを作成するたForm3ボタンを設定します。たとえば、一度に12アップを持つことができます。
あなたは、各フォームを作成した後、私はオブザーバーリストに入れていることがわかります。 Form2をしてたForm3の両方がIObserverを実装するので、私はこれを行うことができると思います。私は、新しいフォームが最新のデータで更新されるように、私はオブザーバーリストにリフレッシュを呼び出すフォームを表示した後。私はIObserverの変数にキャストし、ちょうどそのフォームを更新している可能性があります。私はできるだけ簡潔になろうとしています。
は、[追加]ボタン「ボタン3」のため、私は私のDataListコントロールにテキストボックスストアからそれをテキストを引き、その後、すべてのオブザーバを更新します。
その後のForm2を作ります。リストボックスと次のコードを追加します。
システムを使用して、
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form2 : Form,IObserver
{
public Form2()
{
InitializeComponent();
}
private void Form2_Load(object sender, EventArgs e)
{
}
void IObserver.Refresh(List<string> DisplayList)
{
this.listBox1.Items.Clear();
foreach (string s in DisplayList)
{
this.listBox1.Items.Add(s);
}
this.listBox1.Refresh();
}
}
}
続いたForm3、コンボボックスを追加し、次のコードを追加します。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form3 : Form,IObserver
{
public Form3()
{
InitializeComponent();
}
private void Form3_Load(object sender, EventArgs e)
{
}
void IObserver.Refresh(List<string> DisplayList)
{
this.comboBox1.Items.Clear();
foreach (string s in DisplayList)
{
this.comboBox1.Items.Add(s);
}
this.comboBox1.Refresh();
}
}
}
あなたはそれぞれの形式が若干異なるIObserverインターフェースのリフレッシュ方法を実装していることがわかります。一つは、コンボボックスの他のリストボックスです。インタフェースの使用は、ここで重要な要素である。
現実世界のアプリケーションでは、この例では、より複雑になります。たとえば、代わりの更新インターフェイスの文字列のリストを渡します。これは、任意のパラメータを持っていないでしょう。代わりに、パブリッシャ(この例では、Form1が)発行者のインタフェースを実装し、それらが初期化されているようオブザーバーに自身を登録します。各観察者は、それの初期化ルーチンで出版社を受け入れることができるだろう。それが更新されたとき、それは、インターフェイスを介して公開されたメソッドを経由して出版社のうち、文字列リストを引くでしょう。
複数の種類のデータと、より複雑なアプリケーションでは、これはあなたがIObserverを実装するフォームは、出版社から撤退されるデータをカスタマイズすることができます。
もちろん、あなたが唯一のオブザーバーは、文字列のリストまたは特定のデータを表示できるようにしたい場合。そして、パラメータの一部としてそれを渡します。インターフェイスは、それぞれの層が何をしたいのか明示的になります。今から5年後には、コードとコード「ああ、それが何をしているか。」
を見ることができますこの方法 の
<サブ>(ソース: headfirstlabs.com の)サブ>
チェックアウトと述べ、「ヘッドファーストを:デザインパターンを」彼らはまた、いくつかの<のhref = "HTTPを持っている://フォーラム.oreilly.com /カテゴリ/ 48 / HEAD-ファーストデザインパターン/ "のrel = "nofollowをnoreferrer">ブックのに関するフォーラムや<のhref =" http://www.headfirstlabs.com/図書/ HFDP / dm.html」のrel = "nofollowをnoreferrer">デザイン瞑想するます。
Observerパターンは、ハリウッドの原則に従ってください。
「私たちはあなたを呼び出す私たちを呼んではいけません」 パターンのためのグッドサイト http://www.dofactory.com/Patterns/PatternObserver.aspxする
これは非常に簡単に言えだ、二つの成分があります:。オブザーバーと観測されたが、
外部的には、観測が追加(登録)し、オブザーバーを削除する方法が必要です。
内部的には、観測が登録オブザーバーのリストを必要とします。
観察者(通知)又は通知などのパブリックメソッドを必要とする(paramsは)。
特定のものが観察に起こるときはいつでも、それ意志リストをループごとに登録された観測者に()を呼び出し通知します。
最も単純なケースでは、それが「ねえ、オブザーバー、私のデータが変更され、自分自身を来て、リフレッシュする」というシンプルな通知です より複雑なバージョンでは、パラメータは、観察者が変更されたかを知るせ過ぎてすることができます。
データを保持している何か -モデル - ビュー - コントローラで、観測は通常、エンティティオブジェクトです。コントローラがオブザーバーです。これは、モデルの変化を監視し、それが変更に関心がある場合、それ自体を更新するには、[View]を指示します。
Javaイベントリスナーは、このパターンの現実世界の実装です。
あなたはその動作(または状態)あなたが観察したいオブジェクトを持っていることを想像してみてください。フィールドAの値が10に当たったときたとえば、あなたが実際にあなたが観察したいこの複雑なオブジェクトの実装の詳細と相まって取得せずに、そのイベントに通知を取得したいです。 フィールドAが10あなたのオブザーバーに当たるときは、インターフェイスを定義し、それは順番にオブザーバーによって呼び出されますオブジェクトがあるオブザーバーを登録し、登録を解除するには、少なくとも2つのメソッドを持っている必要があり、観察可能それを呼び出すと、あなたの目標は、このインタフェースを実装してみましょう単に登録(および完了時に登録解除)するために観察可能呼び出します。観察可能な通常オブザーバーのリストを維持し、同時にそれらを通知し、またはあなたが喜ばとして。また、同期または非同期で実行することができ、それはあなた次第です。これは、コードを記述することなく、非常に単純化した説明です。あなたはそれを理解すれば、実装は、特定のニーズに合わせて細部が異なることができます。
のオブザーバー(パブリッシュ/サブスクライブ)する
オブジェクトの状態が変わると、それは実行時に関心を登録している他のオブジェクトに通知します。 通知オブジェクト(出版社)、そのすべてのオブザーバ(加入者)にイベント(出版物)を送信します。
一言
オブジェクトの対象です)できるその他のオブジェクト(オブザーバーを通知を選択するフィルタ。
実用例:
ということかなんかのアプリび出すためのものではありませんしよう♪その他の構築です。
きPluginSubjectクラス、メソッドで呼NotifyOrderCreated.新しい注文を作成するためには、画面で電話PluginSubject.NotifyOrderCreated.
このようなPluginSubject取得しますリストのPluginObservers通話PluginObserver.通知にそれぞれ、メッセージを記述するイベントです。
を可能にするいくつかの本整可能です。
より知りたい
ったことがあるかどうか分かりませんが引き付けて言うならば、一歩深め-必要な場合は、オブザーバーを実施する特別インタフェースということかIPluginObserverを使用でき反射歩の種類に組み立て、インスタンスを生成のプラグインができます。
それを許可するにはユーザーに自分のアセンブリ(すい店舗一覧の組み立て名前をどこかに、徒歩で、bamなんかの拡張性!
オブザーバーは、2つのオブジェクト間の接続を緩め、即ち、デカップリングする手段です。あなたはそれが維持するために、あなたのコードがすっきりし、より容易にするためにことをしたいです。それはほとんどすべてのデザインパターンの目標です:コードを維持しやすく、読みやすくなります。
。 パブリッシャとオブザーバー:このパターンでは、次の2つのクラス、2つのオブジェクトを持っています。出版社は、実際にいくつかの作業を行うクラスである、それは時々それについて、それらを伝えるために任意のオブザーバーのメソッドを呼び出します。それは加入オブザーバーのリストを保持しているため、呼び出すためにどのクラスを知っています。
だからあなたの出版社は次のようになります。
class Publisher
{
List<Observer> observers = new List<Observer>();
public Add(Observer o)
{
observers.Add(o);
}
private AlertObservers()
{
foreach(Observer o in observers)
{
o.Alert();
}
}
出版社は実際にほとんどの作業を行います。すべてのオブザーバーは何をする必要がリストに追加され、呼び出されたメソッドを実装しますされています。これと同様ます:
class Observer
{
public Observer(Publisher pub)
{
pub.Add(this);
}
public Alert()
{
System.Console.WriteLine("Oh no, stuff is happening!");
}
}
それはそれがどのように動作するかのかわいいベアボーンアイデアです。さて、なぜそれが価値がありますか?かなりよくハァッアップ接続されたルックス?私は私がオブザーバー機能で多くのクラスを設定できるようになるインターフェイスを使用していない、と出版社は、彼らが警告()の呼び出しを受け取ることができることを除いて、それらについての詳細は何も分からない必要があるため、その理由の一つです。また、出版社は、それが何を持っていない場合でも、それが持っている任意およびすべてのオブザーバーにアラートを呼び出そうとすることに注意してください。
さて、C#の世界では、言語はそれのイベントオブジェクトを通して、このパターンのバージョンに組み込まれています。イベントは非常に強力であり、別のメソッド呼び出しのパラメータとしてメソッドを渡す方法です代表者、を利用します。彼らはいくつかの深刻なデカップリングを可能に、私は新しい質問のためにそれを保存したい。
非常に少数の実時間例:
- 新聞-雑誌/メーリングリスト 契約又は契約一般
- タグ付けの同僚、MS Office コミュニケーター
た人はこのイベントです。純真の実装は、オブザーバーパターンはなくエクセルのバージョン;これは本当です。どこで実際に作品の両面からの高レベルな視点でのより実装固有の詳細、また利用したいと思い、例えですね。
思いを新聞出版社より刊行。にOOP条件で思いの新聞として 観察可能な いことです。がどのような仕組みになっているのか。明の実施内容の新聞もここに例えるならばジャーナリスト、作家、編集者など。すべての労働の事務所の新聞)は公開されている。人(オブザーバー ませんが集まり、従業員の新聞出版社やっています。できるだけではなく い ることがありますのでプロトコル(または インタ いろいろいます。
こうしていただきます(読む)新聞:ご契約いただいています。お客様の氏名一覧をご契約者がその論文の出版社を知ってお届けしお客様がすぐそばにあります。ない場合などを観察したい(でも、退会;お客様の名 off この一覧です。
現在、このような抽象的な類似;しかし、実際には "ほぼ完璧に平行な方法です。ネイベントの仕事.
もたらされたクラスを観察可能な、その実施一般的に知らなくてもよい。しかし、いかなく、特定の種類のインターフェースを公開し、そのインタフェースはイベントです。コード欲しい"と、このイベントは本質的に登録して加入者の場合:
// please deliver this event to my doorstep
myObject.SomeEvent += myEventHandler;
この同じコードを決定しない通知されるのはこのイベントなので、unsubscribes:
// cancel my subscription
myObject.SomeEvent -= myEventHandler;
この迅速な議論の代表団はこのようなコードを実際に作品。委譲、または存じないかもしれませんが、基本的に変数のアドレスのメソッドになっています。通常、この変数には、型のよう 値 変数として宣言された int
, double
, string
, など。ています。の場合は委譲型では、この型が定義されたメソッド 署名;そのパラメータとその戻り値です。委譲の特定のタイプすることができ 他の 方法を実行する 他の 行動をとる方法は、適切な署名を表します。
うちの新聞ナ成するため、購読新聞いて、実際に従い、特定のパターンです。具体的には、を提供する必要がありますの有効なアドレスまたは新聞。だけではできない"と言うえ送信しました。" いろいベーコンのチーズバーガー." 教えていただけると嬉しいの出版社の情報をできる有意義にするのに用いられております。世界中です。ネイベントには、この変換を必要と供給のイベントハンドラの正しい署名を表します。
ほとんどの場合、この署名になってしまってい何らかの方法のようになります:
public void SomeEventHandler(object sender, EventArgs e) {
// anything could go in here
}
である、上記の方法で保管する委譲変数の型 EventHandler
.より具体的に例があり、一般 EventHandler<TEventArgs>
委譲タイプdesribes方法上記と同様のもと e
パラメータの型 由来のもの EventArgs
.
にあたり、その代表者は本当に変数を指示すなく最終的に接続す。ネイベントや新聞にも参加できます。のイベントを実施することができる リスト の代表者は、かかる項目の追加と削除されます。このように新聞出版社のリストの契約者名を受けた場合は、コピーに新聞を配布します。
とにかく、このたす、オブザーバーパターンを幾分強含んでいる。その他の多くの種類のこれらのコールバックメソッドのパターンはもちろん、たします。※ネイベントはパラダイムの大半です。NET開発者は慣れるように思うので良い出発点からの開発の理解下さい。