看板 C_and_CPP 關於我們 聯絡資訊
※ 引述《iamstudent (stu)》之銘言: 吃掉... : 所以方法變成只有兩種:(如果還有更多,請指教) : 方法a: 大class去friend所有的state子類別 : 方法b: 大class設計好低階的public介面函數,然後抽出去的類別只用這些介面存取 : 問題是這兩個方法感覺都不夠好 : 方法a會有超多的friend敘述 : 而方法b有的時候還真的設計不出來 : OOAD版上有人提供了方法c:把大class的所有成員物件改public : 這個也不是我要的 : 因為等於直接暴露整個內容出去了 : 那麼還有其他方法嗎? 應該由「需求」來決定該使用何種設計模式. 如果兩個 concrete strategies 需要存取到 Context 的屬性, 那 麼存取到的部份一定也相同, 否則他們就不該實作相同的 Strategy 介面. 使用策略模式, 有時是為了讓客戶端能夠輕易擴充自己的程式, 讓 他們選擇性的實作某種Strategy. 這時候就不該考慮完全曝露的方 法(甚至也破壞了抽象化能力), 或是加上新的 friend. 綜合以上建議, 我覺得你要了解: 1.需要存取的理由 2.開放之後帶來的風險 3.如何提供合適的介面(其實以屬性為單位的 setter/getter 也不少見) 介面難想通常是需求、責任不明確使然, 雖說要套用策略模式到你 的架構也不無可能, 以下是我的作法: // 對應到你本來很大的 class class Context { friend class FullyAccessor; int first, second, third; // Strategy 介面指標s... public: // 其他介面 }; // 實作者內部使用的類別, 預設擁有最大權限 class FullyAccessor { // ... public: FullyAccessor( Context* ); int getFirst(); void setFirst( int ); int getSecond(); void setSecond( int ); int getThird(); void setThird( int ); }; 你可能有一種策略需要存取 Context 全部屬性, 則需要繼承(視情 況開放部分介面): class UseAllAttributes : private FullyAccessor { public: UseAllAttributes( Context* ); protected: using FullyAccessor::getFirst; using FullyAccessor::setFirst; using FullyAccessor::getSecond; using FullyAccessor::setSecond; using FullyAccessor::getThird; using FullyAccessor::setThird; }; 只存取部份屬性則繼承: class UseFirstOnly : private FullyAccessor { public: UseFirstOnly( Context* ); protected: using FullyAccessor::getFirst; using FullyAccessor::setFirst; }; 然後策略的介面像是這樣: class Strategy : public UseFirstOnly { public: Strategy( Context* ); virtual void act() = 0; }; // 客戶端程式碼 class ConcreteStrategy : public Strategy { public: ConcreteStrategy( Context* ); virtual void act() { cout << getFirst() << endl; cout << getSecond() << endl; // compile error } }; 其他用法依此類推. 補上類別圖: ┌────┐ ┌───────┐ │ Context│←──◇│ FullyAccessor│ └────┘ └───────┘ ┌───┴───┐ ┌────┴──┐ ┌──┴─────┐ │ UseFirstOnly │ │UseAllAttributes│ └───────┘ └────────┘ │ ┌────┐ └──→ │ Strategy │   └─────┘   △   ┌────┴────┐    │ ConcreteStrategy │ └─────────┘ 着色部份就是常見的策略模式結構. -- ▂▂ ▄▂ T.T.L Listen 2 http://ppt.cc/jIUk ˇ ˇˇ ˇ 說什麼結束 ▃▃ http://ppt.cc/zQtB ψ髮箍 -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 140.121.197.115
hateexam:感覺版主好聰明 好厲害... 04/24 01:18
iamstudent:大推這一篇呀,受教了 04/24 01:23
iamstudent:我的方法如果有另外一種strategy的繼承體系就完蛋了 04/24 01:23
iamstudent:不過感覺這樣改,我要增加超多Get與Set函數 囧 04/24 01:25
iamstudent:可能需要依據需求設計數種不同的Accessor 04/24 01:27
iamstudent:這個感覺有點Proxy Pattern的味道在 04/24 01:28
iamstudent:另外,利用private繼承+using選用需要的method很酷 04/24 01:39
iamstudent:這樣就可以關閉部份的功能性 04/24 01:41
iamstudent:要寫出新的Accessor完全不用更動其他class 04/24 01:43
tomap41017:我覺得版主真神人也... 04/24 01:43
iamstudent:我覺得沒看到這篇之前,我都不算真的會用strategy... 04/24 01:48
tomap41017:我覺得看到版主這篇,都不知道該怎麼畢業了... 04/24 01:54
110424 修改類別圖, 補上關聯 ※ 編輯: loveme00835 來自: 140.121.197.115 (04/24 03:30)