09/11/23 16:58:10
クラスの設計がよくわからなくなってきたので助けてください。
■前提
複数のミニブログ(例えばTwitterとはてなハイク)のタイムラインを一つのリストにまとめて表示する
プログラムを作るとします。
基本的な機能は一緒なので、最大公約数的な抽象クラスを作り、画面の方でも抽象クラスで提供
されているプロパティに従って最大公約数的な画面表示を行なっていました。
例)
名前 - メッセージ - 日付 - システム
-----------------------------
太郎 - ほげほげ - 12 days ago in Twitter
次郎 - ふがふが - 30 days ago in HatenaHaiku
■質問
ここで、各ミニブログ特有の機能も画面上に反映させたくなった場合、画面側の方で
例えば if(message is TwitterMessage)... else if (message is HatenaHaikuMessage)みたいに
どのサブクラスのインスタンスか一々調べて処理を書くしかないのでしょうか?
例) HatenaHaiku の場合、キーワードも表示されるようにする
名前 - メッセージ - 日付 - システム
-----------------------------
太郎 - ほげほげ - 12 days ago in Twitter
次郎 - [独り言] ふがふが - 30 days ago in HatenaHaiku
322:デフォルトの名無しさん
09/11/23 17:03:10
制御のモデルを変える。
メッセージに描画させればいい。
323:デフォルトの名無しさん
09/11/23 17:03:30
固有メッセージ追加とかカスタマイズ用のメソッドとかインターフェースとか
そういうのを追加する。
細かいところのやり方はいろいろだけど。
324:デフォルトの名無しさん
09/11/23 17:04:46
それが一般的な機能なら、クラス側に機能(インターフェイス)を持たせちゃうな。
で。Twitter 用のクラスでは何もしない、と。
特殊な機能なら、UI 側での判定もありじゃない?
325:デフォルトの名無しさん
09/11/23 17:07:56
>>320
同期処理かつメインスレッドが所有するListViewを処理するのに
わざわざ非同期のBeginInvokeはねえよw
EndUpdateまで待つためにlockかWaitHandleまで必要になるぞ
326:デフォルトの名無しさん
09/11/23 17:09:30
>>321
Decorator パターンで考える。
Decorate する必要がない時は空の ConcreteDacorator で代用。
327:デフォルトの名無しさん
09/11/23 17:09:39
>>322
なるほど、各メッセージ自身が自分自身の描画方法を知っている形にするってわけですね。
そういった場合でモデルと画面描画を分離させたい場合は間にもう1クラスぐらいかませるようなやり方で
良いでしょうか?
[データモデル]
MessageModel
+ Name : string
+ Message : string
TwitterMessageModel → MessageModel
+ HashCode : string
HatenaHaikuMessageModel → MessageModel
+ Keyword : string
[画面表示用のコンポーネント]
MessageComponent
+ Draw() : bool
TwitterMessageComponent → MessageComponent
- model : TwitterMessageComponent
HatenaHaikuComponent → MessageComponent
- model : HatenaHaikuMessageComponent
328:デフォルトの名無しさん
09/11/23 17:13:32
そういうクラスを考えるのは楽しいんだけどさ。
あんまり役に立たないよね。
329:307
09/11/23 17:13:43
とりあえずC#をボチボチ勉強します。
330:デフォルトの名無しさん
09/11/23 17:15:23
>>326
すまん、空の ConcreteDacorator で代用する必要はないか。
ConcreteComponent をそのまま使えばいいんだ。
・・・ってもう解決しそうだから、どうでもいいか
331:デフォルトの名無しさん
09/11/23 17:15:31
>>323
各システム固有の何かをする、ってメソッドを追加する、みたいな解釈でしょうか?
なるほど・・・
>>324
抽象クラスにメソッドを持たせるということですよね。
この場合、特殊な機能が少ないうちは良さそうなんですが、
増えていくと抽象クラスが煩雑になりそうで・・・
#そもそもそんなに特殊機能がばらばらなのを抽象化して良いのか?って問題もあるけど。
>>326
Decoratorパターンを良く理解していないので調べてみます。
デザインパターンちゃんと勉強しないといけないなぁ・・・
332:デフォルトの名無しさん
09/11/23 17:16:36
interface IExtraMessageField
{
public ExtraMessageField Type { get; } // {Name,Message,Date,System}
public string Message { get; }
}
class TwitterMessage{
}
class HatenaHaikuMessage: IExtraMessageField
{
public ExtraMessageField { get{ return ExtraMessageField.Message; } }
public string Message { get{ return ''[' +Keyword+ ']; } }
}
333:デフォルトの名無しさん
09/11/23 17:16:53
>>328
switch とか if 連打の方がわかりやすかったり工数少なかったりするよなw
334:デフォルトの名無しさん
09/11/23 17:19:50
初心者程抽象化したがるからなぁ
335:デフォルトの名無しさん
09/11/23 17:19:58
そこまで拡張する必要性に迫られたことないし
336:デフォルトの名無しさん
09/11/23 17:21:09
この場合の正しい解は、画面側で"is"使ってインスタンス判定、固有の処理をするだよ。
337:デフォルトの名無しさん
09/11/23 17:21:59
仕事がありません
誰か下さい
338:デフォルトの名無しさん
09/11/23 17:24:22
俺の仕事をあげようか
給料は俺がもらっとくけど
339:デフォルトの名無しさん
09/11/23 17:26:25
うーん、何が正しいんだかよくわからなくなってきました・・・
設計難しいなぁ。
泥臭く書くだけならいくらでもできるんだけど
綺麗に書くとなるとさーっぱりだ・・・
こういう場合に >>336 みたいに「こういう場合はこれが正しい」って断言出来るようになるには
どんだけ経験つめばいいんでしょうね。
340:デフォルトの名無しさん
09/11/23 17:27:58
断言したいだけなら、今すぐにもできるだろw
341:デフォルトの名無しさん
09/11/23 17:32:01
>>336 は馬鹿すぎだろいくらなんでも。
オブジェクト指向言語使ってる意味ないよ。
Twitterがverupして機能増えた・・・なんて時に改修場所がいたるところにちらばるでしょ、それじゃ。
ちゅーことで断言するやつは疑ってかかった方がいいんじゃないかと思う。