在MVC的Design pattern慣例下,一般都會建立一個Config class去統一儲存所有的選項,像是以下的程式碼就很普遍。
class SimpleConfig { public: void save(); void load(); void setOptionA(int val); int getOptionA(); void setOptionB(double val); double getOptionB(); void setOptionC(bool val); bool getOptionC(); private: int optionA; double optionB; bool optionC; };
我也寫過類似的,不過很快就發覺那樣做很傻,每次增加選項都要c&p一堆代碼,然後當選項增至百來項時……嘿, 擁有數百個成員函數的Class看起來跟怪物沒二樣。
自從見識過幾次後,我就痛定思痛決不讓怪物再次出現。
事實上要改良以上的代碼其不困難,只要懂得使用Variant及Enum type。
Variant type
Variant type本身是一種資料類型,卻沒有固定的儲存方法,它可以是int、也可是double,就算是String或其他複雜資料類型也沒問題,雖然執行效率會比primitive type為低,使用起來卻非常方便,不過可惜C/C++並不支援。
故這得依懶其他library framework去實現,像gtk+及Qt這類都有各自的Variant type,除非堅持要寫純C++,否則就別自尋煩惱吧。
Enum type
為每個選項加入setter/getter會無可避免地令Class變得臃腫, 如果把Enum及Variant配合使用,就能大大簡化程式碼的複雜度:
class SimpleConfigImproved { public: enum Option {
OptionA, OptionB, OptionC, Last } ; void save(); void load(); QVariant get(Option option); void set(Option option,QVariant val); private: map <Option,QVariant> table; };
註:QVariant為Qt的variant type
所有選項都用一個Enum的值去代表,只有一個setter及一個getter,每次增加選項都只不過是在宣告裏加一行代碼而已,這比之前的版本簡潔許多。
儲存
另外有一個以上未有考慮的事情就是儲存的方法,每個選項都要有一個名字,通常都會跟程式一樣,例如以上的程式碼可能會這樣儲存:
OptionA=0問題是C/C++並沒有提供直接的方法可以讓你把Enum的值變成文字,你必須要找一個辦法讓程式碼中的”OptionA”能轉化成文字,否則就可以要寫下那麼愚蠢的程式:
OptionB=0.0
OptionC=false
write(“OptionA”,table[OptionA]);
write(“OptionB”,table[OptionB]);
write(“OptionC”,table[OptionC]);
每加一個選項時記得再C&P一次......
關於這個問題有許多的方法去解決,基於我是個懶人,而最近也在寫Qt,在Qt裏只要加上Q_ENUMS宣告就能幫你把Enum的值變成QString,用很簡單的程式碼就能完成儲存的工作:
for (int i = OptionA ; i < Last ; i++ ){ write( nameOfOption( (Option) i) ); }
加多少選項都不用重寫儲存的程式碼!
宣告
class ConfigQt : public QObject { Q_OBJECT Q_ENUMS(Option) public: enum Option { OptionA, OptionB, OptionC, Last } ; void save(); void load(); QVariant get(Option option); void set(Option option,QVariant val); static QString nameOfOption(Option val); private: QMap <Option,QVariant> table; }; QString ConfigQt::nameOfOption(ConfigQt::Option val) { QMetaEnum metaEnum = staticMetaObject.enumerator(0); return metaEnum.key(val); }
1 則留言:
通常我會用 Serialize 的方法變成 JSON object 就最簡單方便了
發佈留言