故事是這樣的,wendy老鳥寫了兩個 class GamePlayer & IResourceLoader, IResourceLoader有一些基本resource check跟 load跟debug的功能,而我們這小咖的任務是base在 IResourceLoader的架構,作一個特製的PolygonLoader(),如下。
class PolygonLoader : public IResourceLoader {
public:
void load(GamePlayer& p) {
p.PolygunRESID = 128; // Compiler error!!
}
};
問題來了,PolygonLoader不是GamePlayer的朋友,上面error怎麼辦? 簡單的說法: wendy 你的class有bug,你看我這邊有error耶 ,應該把這member搬到public吧 !(瞬殺)
還好的說法: wendy 可不可以你麻煩幫忙在IResourceLoader修改,加一個GetResID(){return pGamePlayer.PolygunRESID}; or SetResID() 之類的東西呢? (但是用到IResourceLoader的部門可能都會面臨重新compiler module)。
其實透過inner class的技巧 wendy已經在GamePlayer為我們的需求開了條路。
class GamePlayer{
public:
enum SpecialTypeClass {
Mage = 0,
Paladin ,
War ,
Shaman ,
Thief,
TalentNum
};
friend class IResourceLoader;
template class PrivateAccessor;
//GamePlayer(int classType);
GamePlayer(SpecialTypeClass seed);
void Attack();
GamePlayer();GamePlayer& operator = (const GamePlayer&);
private:
GamePlayer(const GamePlayer&);
static const int NumTurns = 5;
int PolygunRESID;
SpecialTypeClass Talent;
int scores[NumTurns];
};
在implement PolygonLoader時就可以透過實際implement PrivateAccessor/////PolygonLoader.h//////
class PolygonLoader : public IResourceLoader {
public:
void load(GamePlayer& player) ;
};
template<>
class GamePlayer::PrivateAccessor{
public:
static int& ResID(GamePlayer& player){
return player.PolygunRESID;
}
};
/////PolygonLoader.cpp//////
typedef GamePlayer::PrivateAccessor Accessor;
void PolygonLoader::load(GamePlayer& player){
//modify private member here!
Accessor::ResID(player) = 1234;
};
比較覺得可以討論的部分是,難道當Create一個class的時候,開個後門(PrivateAccess)是一個良好的習慣嗎?有沒有其他更好的作法可以盡量維持原架構不變,達到擴充的目的。Reference link: 還是簡單點好
“但是用到IResourceLoader的部門可能都會面臨重新compiler module”
回覆刪除我覺得這句話是關鍵
"難道當Create一個class的時候,開個後門(PrivateAccess)是一個良好的習慣嗎?"
所以我覺得是否定的
除了發現inner class跟private member的技巧以外,會提這篇是這個案例提供了我們"需求"。基本上我不是很喜歡這篇提到的設計。但是如何設計一個讓別人好用,擴充性強又不需要常修改的class,腦子裡沒有更好的作法。
回覆刪除欠的意思是不是覺得也不必這麼刻意避開修正IResourceLoader?有需求就應該改。
ps: 這篇對我還有個暗示,trace 別人的code debug時別太鐵齒,private member還是有可能因為某個public 的 inner class被其他人更動到的 XD
我的意思是 “但是用到IResourceLoader的部門可能都會面臨重新compiler module” 是一個很好的出發點,並且是這個範例所要解決的真正問題。
回覆刪除