作者loveme00835 (朴髮箍)
看板C_and_CPP
標題Re: [問題] Strategy/State Pattern in C++
時間Sat Apr 23 22:50:55 2011
※ 引述《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)