- - PR -
オブジェクトが特定のプロパティを持っているか調べる方法
投稿者 | 投稿内容 | ||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2005-09-28 14:21
>継承という強力な武器を持っているのに、型チェックするというのはやはり勿体無い気がしますね。
最初は継承構造でうまくいっていたのですが、だんだんうまくいかなくなってきました。 たとえばこんなことです。 描画クラスから文字枠のクラスと絵のクラスを派生しました。 絵のクラスからタイトルとふちのある絵を派生しました。 絵のクラスは背景色を持ちませんが、 タイトルとふちのある絵のクラスは背景色を持ちます。 どうしても継承構造とは関係なく背景色を塗ることのできるという インタフェースのチェックが必要になります。 で、この例の場合は背景色という単純なパターンなので、 タイトルとふちのある絵のクラスに内在クラス?として 文字枠のクラスを作ってそれがドロップ操作を受け取るなんてことでよいのですが 論理的な意味合いをもつオブジェクトだとなかなかそういうわけにはいかなくなるんです。 的確な実例を示せずに申し訳ありません。 そもそも、特定のプロパティをチェックするというのは、たまたま特定のプロパティが そういう役割を持っていたから、安直に考えたに過ぎなくて その目的からいって完全に間違った方法であるわけです。おはずかしい。 きちんとインタフェースを定義していこうと思っています。 いろいろありがとうございました。 | ||||||||||||||||||||
|
投稿日時: 2005-09-28 15:48
ジブです。
本論とは関係ないのですが 先ほどの複数インタフェースを持つかどうかのコードに誤りがありましたので 訂正いたします。 Public Shared Function InterfaceCheck(ByVal obj As Object, ByVal Types() As Type) As Boolean Dim t_Type As System.Type If obj Is Nothing Then Return False End If For Each t_Type In Types If t_Type.IsAssignableFrom(obj.GetType) Then Return True End If Next Return False End Function です。Equalsでは、だめなんですね。 失礼しました。 | ||||||||||||||||||||
|
投稿日時: 2005-09-28 20:26
むむ? “描画クラス”が、“背景色プロパティ”を持っているべきでは? “絵クラス”に“背景色プロパティ”が不要なら、無視してしまえばいいだけでは? または、“透明色”のある“絵”であれば、“背景色プロパティ”が必要なのでは? _____________________________________________________________________________ □ Posted by Jitta on 2005/09/28 □ じったのノート □ Microsoft MVP :Visual Developer ASP/ASP.NET Oct.2004-Sept.2005 _________________ 検索のコツ・質問のコツ [ メッセージ編集済み 編集者: Jitta 編集日時 2005-09-28 20:27 ] | ||||||||||||||||||||
|
投稿日時: 2005-10-01 12:41
じったさん、みなさんこんにちは。
どうも私の示した例はうまい例ではなかったみたいです。 (実際、私のケースですと描画クラスは背景色を持っているのですが 最初にBackColorなどを例にしてしまったので、無理やり例を考えてみたのです) でも他にうまい例え話も思いつかないのでそのまま進めたいと思います。 今回の例で皆様だったらどのように実装されるのか興味があったりします。 さて、私だったらですが
”線”なんかもあるわけで、中間のクラスが必要なのかな。 なにより基本の基本クラスは出来るだけ簡素にしたいです。
はい。無視というより無効にというかシャドーするケースは多いです。 その場合、有効か無効かを個別ではなく目的別に知る手段として インタフェースの概念はとても有効であると思っています。
“透明色”のある“絵”であれば、背景色を塗ってはいけないはずです。 コンテナの色が消えてしまいますから。 いかがなものでしょうか [ メッセージ編集済み 編集者: ジブ 編集日時 2005-10-01 12:43 ] | ||||||||||||||||||||
|
投稿日時: 2005-10-01 16:52
それはオブジェクト思考設計がまずいですよ。外部でオブジェクトの種類や状態を意識しなくてはならなくなるという事は、設計の基本となるはずのカプセル化が不十分だと言うことです。
オブジェクトの種類や方を調べて描画の仕方を変えるのではなく、描画の仕方を含むオブジェクト固有のものをクラスの中にカプセル化する様に考えないと。私ならDraw(graphics g)と言うメソッドをひとつ用意して、そのクラスに描画に関する処理も収めます。どうしてもデータと描画を分離したいなら、描画を行うクラスを生成するBuilderインターフェースを作ります。 | ||||||||||||||||||||
|
投稿日時: 2005-10-01 17:18
こんにちは。
今回の例の場合、「描画クラス」というのが描画関係クラス全部のスーパークラスになっているわけですね。 「描画クラス」から、「線」「文字枠」「絵」といったクラスができるわけですね。 このような階層になるならば、「描画クラス」に背景色プロパティを持たせることは不自然であることも納得できます。 「描画クラス」は「描画する」といった「振る舞い」を持ち、属性は基本的に持たない方向でどうでしょうか。もちろん、「基本的な描画をする」という行為に必要であれば「描画クラス」に持たせれば良いでしょう。 「線クラス」を扱うクライアントは、「線」を初期化するときは、「線クラス」を扱っているということを分かっているはずです。 「線」に太さや、スタイルといった属性を設定できるでしょう。 で、描画を行うクライアントは、今描画しようとしているオブジェクトが「描画クラス」であることは分かっても、「線クラス」であることは知りません。 しかし、「線クラス」自身は、自分自身の描画の仕方を知っています。 だから、描画を行うクライアントは、「描画する」という振る舞いを呼び出すだけで、「線クラス」の事は知らなくても、描画できます。 「背景色が塗ることができるクラス」であるとか「ふちを描画できるクラス」であるとかは、クライアントにしたら知っちゃ事ではないわけです。 判断する必要もありません。 クライアントは「描画できる」という事のみ知ればよい、という事です。
| ||||||||||||||||||||
|
投稿日時: 2005-10-01 18:11
こんにちは。ジブです。
甕星さん
IPaintableとかいういうインタフェースを作り、そこにPaintメソッドを定義 基本クラスは抽象クラスにしてIPaintableをインプリメントする そんな感じになっています。 囚人さん
はい。もちろんクライアントには関係ない話です。friendな世界の話です。
内部のツールでは「描画できる」かどうか判断の必要はありませんが 「バックグラウンドを塗れる」かの判断が必要になります。 例えばIPaintableCollectionは「描画できる」オブジェクトを管理していますが そのなかで「バックグラウンドを塗る」ツールがそのItemtが 「バックグラウンドを塗れる」かを判断しなければなりません。 マウスポジションのヒットテストを実施して「バックグラウンドを塗れる」となれば そういうシグナルをユーザーに示したいと考えています。 例えばイメージとしては、こんな感じです。
あとからペイントの処理で
こんなイメージなんですが、ご意見をいただけますでしょうか | ||||||||||||||||||||
|
投稿日時: 2005-10-01 18:51
これはどういう意味でしょう?
「描画できる」の判断ではなく、IPaintable だから、判断する必要もなく全て「描画できる」です。 どうしても「バックグラウンドを塗れる」かどうかの判断をしたいのであれば、IPaintable が判断しなくてはいけないでしょう。(IPaintable に対して行っているから)
各派生クラスは、EnablePaintBackGround をオーバーライドして、「バックグラウンドを塗れる」かどうかを返せばよいです。 #編集 C# になって申し訳ないです。VB は書き慣れていないもので^^; [ メッセージ編集済み 編集者: 囚人 編集日時 2005-10-01 18:54 ] |