traits 讓你的設(shè)計更加靈活

?? 自從畢業(yè)后就沒有再寫過東西拢锹,原先的博客地址也被CSDN給封禁了舆绎,可惜了我當(dāng)年寫的研究生畢業(yè)致謝胞锰,那絕對是浩瀚致謝中的一股清流~~。言歸正傳葬凳,昨天閑暇時間瀏覽了坐在我旁邊胖子的一本書(被他看到估計會揍我一頓绰垂,畢竟我現(xiàn)在還沒他那樣的噸位~~)其中講到了traits。最近在開發(fā)一新功能的時候也碰巧使用到尤其在測試代碼中火焰,于是心血來潮準(zhǔn)備寫些東西劲装。

??traits最早是由Nathan Myers提出:Traits class: A class used in place of template parameters. As a class, it aggregates useful types and constants; as a template, it provides an avenue for that "extra level of indirection" that solves all software problems (Traits class:一種被用來取代 template parameters 的 class。作為一個 class,它聚合了有用的類型和常數(shù);作為一個 template,它為解決所有軟件提供了一條康莊大道)【摘自C++ template】昌简。

?? 對于上述評價可能有人會認(rèn)為有些夸大占业,不過當(dāng)你看過STL的源代碼后你就不會有這種想法(后面有時間會對traits在STL中的應(yīng)用詳細(xì)介紹)。平時開發(fā)過程中最讓人頭疼的就是標(biāo)記江场、開關(guān)纺酸,這類隨處改變流程處理方式的devil。為了保持代碼的整潔址否、可讀性就必須提供其他可替代的方式餐蔬,個人認(rèn)為traits算是其中之一碎紊。


下面我們使用最近參加過的一個技術(shù)認(rèn)證的題目做一下展示。

具體題目可以參考:報數(shù)游戲-實戰(zhàn)簡單設(shè)計樊诺。
??題目本身不存在什么難度仗考,難度在于變化。各種變化可能會導(dǎo)致你的代碼需要重寫词爬,碰巧當(dāng)時也使用了traits秃嗜,所以就使用該題對其進(jìn)行闡述。

1顿膨,抽取規(guī)則

實現(xiàn)過程中將不同的規(guī)則進(jìn)行分離锅锨,方便我們對規(guī)則進(jìn)行組合(在此只展示當(dāng)時的設(shè)計框架不討論實現(xiàn)細(xì)節(jié))。

規(guī)則1:

template<typename ReportTraits>

struct Rule1
{
    typedef ReportTraits traits;
    bool operator()(int inputNum, Result & result)
    {
        return isMatchRule(inputNum,result);
    }

private:
    bool isMatchRule(int inputNum, Result & result)
    {
        ... ...
    }

};

規(guī)則2:

template<typename ReportTraits>
struct Rule2
{

    typedef ReportTraits traits;
    bool operator()(int inputNum, Result & result)
    {
        return isMatchRule(inputNum,result);
    }

private:
    bool isMatchRule(int inputNum, Result & result)
    {
        ... ...
    }

};

上述規(guī)則的定義很簡單恋沃,使用“*仿函數(shù)“做接口兼容必搞,唯一的區(qū)別在于匹配過程的不同。

2囊咏、上報方式抽取

struct ReportTraits1{};
struct ReportTraits2{};

std::string doActualReport(Result &result, ReportTraits1)
{
    ... ...
}

std::string doActualReport(Result &result, ReportTraits2)
{
    ... ...
}

上述我們定義了不同的上報規(guī)則恕洲,兩個空的結(jié)構(gòu)體不帶來任何負(fù)擔(dān),目的很單純主要是為了使用traits激活重載機(jī)制梅割。

3霜第,上報框架的設(shè)計

template<typename RULE1, typename RULE2>
struct CountOff
{
    std::string report(int Num)
    {
        Result re;
        if(RULE1()(Num,re))
        {
            return doActualReport(re, typename RULE1::traits());
        }

        if(RULE2()(Num,re))
        {
            return doActualReport(re, typename RULE2::traits());
        }
        return "";
    }

};

上述我們對規(guī)則進(jìn)行了組合使用,當(dāng)然如果規(guī)則較多我們可以使用變長模板户辞。調(diào)用上報接口時我們使用了各自規(guī)則的特性激活重載機(jī)制泌类,沒有過多的條件判斷。這樣就顯得很簡潔5琢恰D┦摹!

4书蚪,使用方式

    CountOff<Rule1<ReportTraits1>, Rule2<ReportTraits2> >().report(2);

??以上實現(xiàn)通過仿函數(shù)進(jìn)行規(guī)則接口適配,通過每種規(guī)則所持有的traits迅栅,在利用重載機(jī)制進(jìn)行上報方式的匹配殊校,從而實現(xiàn)靈活的規(guī)則組合,而不需要任何的條件判斷读存。(不過這種實現(xiàn)現(xiàn)場好像反響不是很好~~~)为流。那么traits的具體含義是什么呢?說實話我也沒看透让簿,不過大家可以去看下《C++ template》敬察。其中將traits又區(qū)分為:traits和policy。 traits個人理解為不含動作的特性尔当,policy是有動作莲祸。
??很多人可能會質(zhì)疑說上述方式通過多態(tài)也能實現(xiàn)蹂安,確實當(dāng)時現(xiàn)場大部分人也是這樣實現(xiàn)的,不過運行效率如何呢锐帜?有人就把traits的這種方式稱為靜態(tài)多態(tài)田盈,也就是在編譯期就已經(jīng)確定的實現(xiàn)而動態(tài)多態(tài)則不然。唯一的劣勢在于模板的傳染性缴阎,不過.tcc的使用不就是為了解決這個問題么允瞧?所以哪種方式更好這個大家仁者見人吧。

??上述只是通過簡單的例子蛮拔,展示了traits的基本使用還沒有涉及特性的萃取述暂,也就是說其威力還沒有真實的展示,后面會再次通過STL對其進(jìn)行闡述建炫∑杈拢總之traits是一個很強大的編程技巧。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末踱卵,一起剝皮案震驚了整個濱河市廊驼,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌惋砂,老刑警劉巖妒挎,帶你破解...
    沈念sama閱讀 216,591評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異西饵,居然都是意外死亡酝掩,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,448評論 3 392
  • 文/潘曉璐 我一進(jìn)店門眷柔,熙熙樓的掌柜王于貴愁眉苦臉地迎上來期虾,“玉大人,你說我怎么就攤上這事驯嘱∠獍” “怎么了?”我有些...
    開封第一講書人閱讀 162,823評論 0 353
  • 文/不壞的土叔 我叫張陵鞠评,是天一觀的道長茂蚓。 經(jīng)常有香客問我,道長剃幌,這世上最難降的妖魔是什么聋涨? 我笑而不...
    開封第一講書人閱讀 58,204評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮负乡,結(jié)果婚禮上牍白,老公的妹妹穿的比我還像新娘。我一直安慰自己抖棘,他們只是感情好茂腥,可當(dāng)我...
    茶點故事閱讀 67,228評論 6 388
  • 文/花漫 我一把揭開白布狸涌。 她就那樣靜靜地躺著,像睡著了一般础芍。 火紅的嫁衣襯著肌膚如雪杈抢。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,190評論 1 299
  • 那天仑性,我揣著相機(jī)與錄音惶楼,去河邊找鬼。 笑死诊杆,一個胖子當(dāng)著我的面吹牛歼捐,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播晨汹,決...
    沈念sama閱讀 40,078評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼豹储,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了淘这?” 一聲冷哼從身側(cè)響起剥扣,我...
    開封第一講書人閱讀 38,923評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎铝穷,沒想到半個月后钠怯,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,334評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡曙聂,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,550評論 2 333
  • 正文 我和宋清朗相戀三年晦炊,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片宁脊。...
    茶點故事閱讀 39,727評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡断国,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出榆苞,到底是詐尸還是另有隱情稳衬,我是刑警寧澤,帶...
    沈念sama閱讀 35,428評論 5 343
  • 正文 年R本政府宣布坐漏,位于F島的核電站宋彼,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏仙畦。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,022評論 3 326
  • 文/蒙蒙 一音婶、第九天 我趴在偏房一處隱蔽的房頂上張望慨畸。 院中可真熱鬧,春花似錦衣式、人聲如沸寸士。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,672評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽弱卡。三九已至乃正,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間婶博,已是汗流浹背瓮具。 一陣腳步聲響...
    開封第一講書人閱讀 32,826評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留凡人,地道東北人名党。 一個月前我還...
    沈念sama閱讀 47,734評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像挠轴,于是被迫代替她去往敵國和親传睹。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,619評論 2 354