C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[8]: イベントの分け方の指針は?


(過去ログ 34 を表示中)

[トピック内 9 記事 (1 - 9 表示)]  << 0 >>

■17013 / inTopicNo.1)  イベントの分け方の指針は?
  
□投稿者/ れい (484回)-(2008/04/15(Tue) 08:51:35)

分類:[.NET 全般] 

れいです。
お世話になっています。

たとえば。

C言語などのオブジェクト指向をサポートしてくれない言語で、
オブジェクト指向な組み方をする場合、
構造体にXXXTypeとかXXXCodeといったフィールドを用意し、
switchで場合分けすることがよくあります。

あるクラスのフィールドをReadOnlyにしたい場合、
ReadOnly専用のクラスを作る場合と、
フラグか何かでReadOnlyに切り替わるようなクラスに変更する方法と、二つあります。

このように、「型」と「フィールド」と「場合分け」は
データとメタデータの関係で密接に関わっていて、
そのうまい切り方もセンスのひとつだと思うわけですが。

----マエフリここまで----

C#とVBのイベントの実装に関して、皆さんの実装の指針を教えてください。

イベントをどこまでどうやって分解するべきかわからない場合の
指針が欲しいと思っています。

MouseClickとFormLoadのように、
意味もパラメーターも違うのならイベントを分けべきなのはすぐにわかるのですが、
微妙な場合は困ります。
たとえば、KeyUp/KeyDownは.Netでは違うイベントですが、
OS内部では同じイベントでパラメーターが違うだけです。
これを「分ける」と決めた理由が欲しいと思います。

イベントの場合、メタデータを含めると
「イベント名」と「イベント引数の型」と「イベント引数内のフィールド」の、
3つに情報を保持できますので、パターンがいっぱいあります。
たとえば以下のようにイベントを分けることができます。


#1 イベント名を分ける場合
public class EventRaiserClass {
  public event EventHandler<AAAEventArgs> AAA;
  public event EventHandler<AAAEventArgs> BBB;
  public event EventHandler<AAAEventArgs> CCC;
  public event EventHandler<AAAEventArgs> DDD;
}
public class AAAEventArgs : EventArgs {};

#2 イベント引数内のプロパティで分ける場合
public class EventRaiserClass {
  public event EventHandler<AAAEventArgs> AAA;
}
public class AAAEventArgs : EventArgs {
  public EventType Type;
}
public enum EventType {
  AAA, BBB, CCC, DDD
}

#3 イベント引数の型だけで分ける場合
public class EventRaiserClass {
  public event EventHandler<EventArgs> AAA;
}
public class AAAEventArgs : EventArgs {};
public class BBBEventArgs : EventArgs {};
public class CCCEventArgs : EventArgs {};
public class DDDEventArgs : EventArgs {};


もちろんこれらを組み合わせることも可能で、

#4 イベントとイベント引数の型で分ける場合
public class EventRaiserClass {
  public event EventHandler<AAAEventArgs> AAA;
  public event EventHandler<BBBEventArgs> BBB;
  public event EventHandler<CCCEventArgs> CCC;
  public event EventHandler<DDDEventArgs> DDD;
}
public class AAAEventArgs : EventArgs {};
public class BBBEventArgs : EventArgs {};
public class CCCEventArgs : EventArgs {};
public class DDDEventArgs : EventArgs {};

とか、いろいろ(2^3=8通り)作れます。

いままで本能の赴くまま作っていたのですが、
他人に説明できなくて困ります。

時と場合による、というのはわかっていますが、
その時と場合とをできるだけ分解して、
適切な実装を得るための指針を得たいと思っています。

たとえば、

・全部ひとつのイベントにまとめる
・EventArgsをできるだけ使いまわしできるように分ける
・イベントハンドラで場合わけしなくていい程度に分ける
・イベント名が長くならないように分ける

など、いろいろ考えられると思います。

みなさんは何を意識して組んでいるのか、
何を意識して組むべきだと思っているのか、
こうやったらうまくいった、という事例など、
教えてください。

引用返信 編集キー/
■17015 / inTopicNo.2)  Re[1]: イベントの分け方の指針は?
□投稿者/ ま (13回)-(2008/04/15(Tue) 11:11:52)
No17013 (れい さん) に返信
> たとえば、
>
> ・全部ひとつのイベントにまとめる

異なる(同系)オブジェクトの同イベントはひとつに纏めます。

> みなさんは何を意識して組んでいるのか、

常に向上心。1行でも100行でもより良い書き方を追求しています。
※レベルをあげようとしない会社の体質に常に意見していますが全然通りません。


> こうやったらうまくいった、という事例など、
> 教えてください。

フローチャート書かせる。Javaでフローチャート。周りに笑われました。
今はコボルでフローチャート書かせています。これは周りも賛同しています。

リミットぎりぎりまで手を出さない。というか、手を出さない方がいいですよね。






引用返信 編集キー/
■17021 / inTopicNo.3)  Re[2]: イベントの分け方の指針は?
□投稿者/ ネタ好き (95回)-(2008/04/15(Tue) 13:42:46)
2008/04/15(Tue) 14:07:21 編集(投稿者)
2008/04/15(Tue) 14:06:31 編集(投稿者)
2008/04/15(Tue) 14:02:26 編集(投稿者)
2008/04/15(Tue) 13:43:20 編集(投稿者)

れいさん何時もお世話になっています。
興味深いお題ですね。
私も発明品を作っている時よく判断に困ります。
仰るように、情報粒度によって作るイベントの数が変わってしまいます。
私の指針としては、管理コストを抑えるために極力数を増やさない方針で作っています。
私がオブジェクト指向の機能を使っているわけは、オブジェクトの数を減らし管理しやすくするためです。
ですから、その情報がどの情報に属するべきなのかという点【情報従属性】と、
そのイベントで何をしたいのかという【目的】を考慮して作っています。
具体的な例を挙げれば分かりやすいと思いますが、発明に属するものなので出来ません。

追記
分かりずらいと思いますので、自分が心がけているポイントを列挙してみます。
・万能にならずちゃんとイベントが使う状況が特定できる事。
イベントを使う状況が特定できないと、後で使うとき難儀します。
また、全ての正常処理が想像できないのでバグを生む可能性が高まってしまいます。
・そのイベントから渡される情報(EventArgs)が本当に役に立つ事。
使わない情報が多すぎてもいけないし、逆に少なすぎて他のイベントを必要とする場合、イベントのオブジェクトの設計を見直します。
・EventArgsが保持する情報の関連性を説明できるようにしなくてはなりません。
他者に説明できないときは、関係の無い情報が一つのオブジェクトになっている可能性が高いです。
引用返信 編集キー/
■17034 / inTopicNo.4)  Re[3]: イベントの分け方の指針は?
□投稿者/ れい (485回)-(2008/04/15(Tue) 21:11:47)
No17015 (ま さん) に返信
> 異なる(同系)オブジェクトの同イベントはひとつに纏めます。

No17021 (ネタ好き さん) に返信
> 私の指針としては、管理コストを抑えるために極力数を増やさない方針で作っています。

EventもEventArgもなるべく少なく、ということですね。
しかし、たとえばControls.MouseUp/MouseDownは
MouseEventArgの中にBoolean IsUpといったフィールを作れば
ひとつに纏めることもできたはずですが、そうなっていません。

何を基準に分ける・分けないを決めたのでしょう…。

> ・万能にならずちゃんとイベントが使う状況が特定できる事。
> イベントを使う状況が特定できないと、後で使うとき難儀します。
> また、全ての正常処理が想像できないのでバグを生む可能性が高まってしまいます。

「万能」はダメ、と。

> ・そのイベントから渡される情報(EventArgs)が本当に役に立つ事。
> 使わない情報が多すぎてもいけないし、逆に少なすぎて他のイベントを必要とする場合、イベントのオブジェクトの設計を見直します。

イベントを分ければ無駄な情報を一切持たないEventArgを作れますが、
場合によっては無駄な情報、というのは多少はあってもいいという方針ですか…。

> ・EventArgsが保持する情報の関連性を説明できるようにしなくてはなりません。
> 他者に説明できないときは、関係の無い情報が一つのオブジェクトになっている可能性が高いです。


> フローチャート書かせる。Javaでフローチャート。周りに笑われました。

あー。そういえばUMLにもそんなのがありましたね。

> 常に向上心。1行でも100行でもより良い書き方を追求しています。

これは…、私には無理ですね。


「万能性」はいらない。
「関連性」はいる。
「なるべく纏める」。
「情報の有用性」。
「フロー」。

そう言われればこれらは重要な気がします。

いつも作る時に悩みませんから、何か指針が頭の中にあるはずなんですが、
それがどんな内容なのか、自分でわからないです。
具体例をインプットしたときのみ答えが得られるという…。


引用返信 編集キー/
■17048 / inTopicNo.5)  Re[4]: イベントの分け方の指針は?
□投稿者/ ネタ好き (97回)-(2008/04/16(Wed) 01:38:19)
2008/04/16(Wed) 02:07:08 編集(投稿者)
2008/04/16(Wed) 02:06:15 編集(投稿者)

>しかし、たとえばControls.MouseUp/MouseDownは
MouseEventArgの中にBoolean IsUpといったフィールを作れば
ひとつに纏めることもできたはずですが、そうなっていません。

私も同じ事を悩んだ事があります。
マイクソフト開発チームの気持ちは推測するしか無いのですが、
「情報のベクトル」と「将来性」に注目したのだと思います。
例えばこの例ですと、マウスのボタンが押されてそれがアップするまでに、
新しい情報が追加出来ると便利だと思います。
私は勝手にそう考え、情報のベクトルが違う場合はなるべく分けて作っています。
一見この方針は「増やさない」に反していると感じると思いますが、
その情報が関連していれば、覚えるのは簡単ですし小回りが利きます。


>具体例をインプットしたときのみ答えが得られるという…。

私もこういう時が多いです。
この直感は案外馬鹿に出来ません。
直感とは経験から導き出されている場合があるからです。
明らかに可笑しい時以外は、ちょっと実装してみて、
後で情報の整理をするという方法も私は多用しております。
ただしチーム開発の場合は、体制によっては無理かもしれませんね。
引用返信 編集キー/
■17167 / inTopicNo.6)  Re[5]: イベントの分け方の指針は?
□投稿者/ ネタ好き (109回)-(2008/04/18(Fri) 03:57:00)
2008/04/18(Fri) 03:57:44 編集(投稿者)

私もイベントの事で気になった事があります。
それは派生させるべきイベントの判断基準です。
イベントオブジェクトだから当然派生できます。
となれば、新しいイベントを作るべきか、
派生オブジェクトを作るべきかという判断も必要になってくると思います。
それも含めて考えると奥が深いテーマですね。

引用返信 編集キー/
■17221 / inTopicNo.7)  Re[6]: イベントの分け方の指針は?
□投稿者/ れい (490回)-(2008/04/18(Fri) 21:28:22)
No17167 (ネタ好き さん) に返信
> となれば、新しいイベントを作るべきか、
> 派生オブジェクトを作るべきかという判断も必要になってくると思います。
> それも含めて考えると奥が深いテーマですね。

派生させて新たなEventArgsをつくるのも、
そこに情報を持たせることになります。

同じEventArgsでも、イベント名が違えばそれも情報です。

イベントの場合、あちこちに情報を埋め込むことができて、
指針がないとぐちゃぐちゃになってしまいそうなのです。

が、
散々考えて、過去のコードなども見てみましたが、
いい指針は思いつきませんでした。

ひとつだけ。

イベントをもらってすぐに
Selectとかswitchで分けなきゃいけないような
実装は比較的ダメな気がします。

とりあえず、解決してないけど閉めときます。
解決済み
引用返信 編集キー/
■17232 / inTopicNo.8)  Re[7]: イベントの分け方の指針は?
□投稿者/ επιστημη (941回)-(2008/04/19(Sat) 09:20:57)
επιστημη さんの Web サイト
> イベントをもらってすぐに
> Selectとかswitchで分けなきゃいけないような
> 実装は比較的ダメな気がします。

ハンドラをひとつにまとめたのがそもそもの間違い
ってことでしょか?

解決済み
引用返信 編集キー/
■17243 / inTopicNo.9)  Re[8]: イベントの分け方の指針は?
□投稿者/ れい (493回)-(2008/04/20(Sun) 00:57:53)
No17232 (επιστημη さん) に返信
>>イベントをもらってすぐに
>>Selectとかswitchで分けなきゃいけないような
>>実装は比較的ダメな気がします。
>
> ハンドラをひとつにまとめたのがそもそもの間違い
> ってことでしょか?
>

public class Neko {
public event EventHandler<NekoActionEventArgs> Act;
protected void OnAct(NekoActionEventArgs e) { if (Act != null) Act.Invoke(this, e); }
}
public enum ActionType {
Move, Eat, Meow, TailWag
}
public class NekoActionEventArgs : EventArgs {
private ActionType Type;
}

public class Kitten {
public event EventHandler<EventArgs> Move;
public event EventHandler<EventArgs> Eat;
public event EventHandler<EventArgs> Meow;
public event EventHandler<EventArgs> TailWag;
protected void OnMove(NekoActionEventArgs e) { if (Move != null) Move.Invoke(this, e); }
protected void OnEat(NekoActionEventArgs e) { if (Eat != null) Eat.Invoke(this, e); }
protected void OnMeow(NekoActionEventArgs e) { if (Meow != null) Meow.Invoke(this, e); }
protected void OnTailWag(NekoActionEventArgs e) { if (TailWag != null) TailWag.Invoke(this, e); }
}

Nekoはダメ、KittenはOKかと。
この例なら当たり前なんですが。

もっとダメパターンとかOKパターンをたくさんあつめて、
どう優先順位をつけてどうわけたらいいか、
指針が欲しいです。

まぁ、結局オブジェクトをどうわけるのかといった、
よくある議論と同じなのですが、
イベントという概念まで議論をしているケースが
なかなかないのですよね。
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -