作者sfp (Fru:z)
看板OOAD
標題Re: [問題] 類別之間的關係
時間Sun Nov 18 23:45:51 2007
※ 引述《H45 (!H45)》之銘言:
: 好!那麼該選擇哪一種比較好?
: 就目前線索的答案應該是:都可以
: 如果吉娃娃未來可以咬其他的東西,不僅僅是長今
: 那麼第一種方法的吉娃娃需要增加很多方法:
: 吉娃娃.咬(長今);
: 吉娃娃.咬(第二種東西);
: 吉娃娃.咬(第三種東西);
: 這種情況最好把「咬」放在被咬的類別裡面
: 也就是:
: 長今.被咬(古娃娃);
: 第二種東西.被咬(吉娃娃);
: 第三種東西.被咬(吉娃娃);
: 如此一來,每次有新的東西要被咬,就不需要更改已經寫好的類別。
[部份恕刪]
我覺得這邊反而不是我有問題的部份...
假如吉娃娃要咬很多其他的物件, 我可能會做個《interface 可以被咬》,
然後有可能被咬的, 都去繼承這個可以被咬的interface.
這樣我就只要用一個方法
吉娃娃.咬(I可以被咬的東西);
反過來說, 如果會咬別人的, 不止吉娃娃一個,
那我可能就做一個 《interface 會咬人的》, 然後會咬人的都去繼承它.
繼承的都要實作 咬 這個method
我真正的問題是
class 醫女 : I可以被咬
{
// 可以被咬可能表示這有個性質 例如 HP
// 被咬時, HP -= 受到的傷害;
}
class 狗 : I會咬人
{
public void 咬人(I可以被咬)
{
// 看要怎麼咬
}
}
然後當我在用這兩個類別時
醫女 長今 = new 醫女();
狗 吉娃娃 = new 狗();
狗.咬(長今);
這時候 狗要直接去操作長今的HP嗎?
站在 data hiding的立場 是不是長今應該提供一個 被咬 的method?
可能長這樣
public void 被咬()
{
HP -= 10;
}
或許還另外提供一個
public bool IsDead() // 看有沒有被咬死
{
if(HP == 0)
return true;
return false;
}
如果這樣寫的話 長今似乎不在乎誰咬她 她的職責是在判斷自己有沒有被咬死
又或者 如果需要反咬回去的話 可能寫成
public void 被咬(看是誰咬她)
{
if(!IsDead())
咬回去(看是誰咬她);
// 當然這裡的 "看是誰咬她" 同時繼承
// 1. I會咬人 2. I會被咬 兩個interface
}
好像離題太遠了...
所以 不管是 吉娃娃.咬(長今);
或者是 吉娃娃去call 長今.被咬(); //可能在吉娃娃內部有一個可以被咬的handle
長今內部都要做一個 被咬 的method
public void 被咬();
這樣對嗎?
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 61.229.55.199
→ H45:呵!我看到 HP 了,如果是多對多的問題可以建立表格來管理 11/18 23:48
推 H45:另外有一件我一直很在意的事情,為什麼被咬的方法沒有參數輸入 11/18 23:54
推 abcdefghi:如果是吉娃娃和長今是tight couple,那兩個都直接實作 咬 11/19 00:17
→ abcdefghi:和 被咬, 然後直接呼叫就好. 如果是loose couple,就做一 11/19 00:19
→ abcdefghi:個listener的object,吉娃娃咬長今時,長今要有反應,就註 11/19 00:20
→ abcdefghi:冊,實作這個listener,同時設為長今的friend,而長今 被咬 11/19 00:21
→ abcdefghi:的反應,就寫在這個listener或是listener再去呼叫長今的 11/19 00:23
→ abcdefghi:被咬 這個private method. 如果吉娃娃和長今一直互咬,pk 11/19 00:24
→ abcdefghi:那吉娃娃也得在初始化時,對長今註冊一個listener,把各種 11/19 00:25
→ abcdefghi:長今動作的反應都寫進這個listener. 11/19 00:26
→ abcdefghi:我想,實務上只能儘量把需求收集清楚,但最後還是看自己的 11/19 00:27
→ abcdefghi:口味和未來的眼光. 11/19 00:29
→ abcdefghi:對了,如果能用aggregate代替繼承,就儘量少用繼承. 11/19 00:30
推 sfp:我對java不太熟 請問listener是不是就是observer pattern 11/19 01:40
→ sfp:中的 subscriber? 11/19 01:41
推 abcdefghi:是的. 11/19 06:07