設(shè)計(jì)模式最大的作用就是在變化和穩(wěn)定中間尋找隔離點(diǎn),然后分離它們,從而管理變化。將變化像小兔子一樣關(guān)到籠子里,讓它在籠子里隨便跳,而不至于跳出來(lái)把你整個(gè)房間給污染掉。
設(shè)計(jì)思想
將行為想象為一族算法,定義算法族,分別封裝起來(lái),讓他們之間可以互相替換,使得算法的變化獨(dú)立于使用算法的客戶。
業(yè)務(wù)場(chǎng)景
假定現(xiàn)在讓你設(shè)計(jì)一個(gè)鴨子類(lèi),模仿這個(gè)世界上所有的鴨子,你會(huì)怎么做?
你可能會(huì)說(shuō)使用繼承,先定義一個(gè)Duck父類(lèi),然后寫(xiě)一些函數(shù):display表現(xiàn)鴨子的模樣,fly表現(xiàn)鴨子的飛行動(dòng)作,quack表現(xiàn)鴨子的叫聲…然后再寫(xiě)一些類(lèi)去繼承這個(gè)父類(lèi),一個(gè)一個(gè)重寫(xiě)父類(lèi)的函數(shù),模仿每種鴨子不同的長(zhǎng)相,飛行行為和叫聲。
如果你是一個(gè)初學(xué)者,你能想出這些并不奇怪,問(wèn)題也確確實(shí)實(shí)解決了,但卻并不是最佳方法。這種設(shè)計(jì)會(huì)造成大量的函數(shù)重復(fù):比如世界上現(xiàn)在有10種鴨子,有4種鴨子的模樣一模一樣,另外3種一模一樣,剩下的一模一樣,而你卻要一個(gè)一個(gè)去重復(fù)寫(xiě)display函數(shù);這種設(shè)計(jì)也并不利于未來(lái)的業(yè)務(wù)發(fā)展:比如現(xiàn)在你用繼承完成了所有的鴨子設(shè)計(jì),某一天,科學(xué)家又宣布新發(fā)現(xiàn)10種鴨子,而你還是要繼續(xù)改動(dòng)你的代碼,不斷的重寫(xiě),不斷的繼承。很快,你就會(huì)發(fā)現(xiàn),繼承并不是一個(gè)好辦法。
剛開(kāi)始出現(xiàn)繼承這種機(jī)制的時(shí)候,很多程序員便很喜歡用這種方法解決問(wèn)題。因?yàn)檫@很符合我們以往的認(rèn)知習(xí)慣:某某人的兒子可以使用父親手中的資源,這種使用似乎“理所應(yīng)當(dāng)”,很順其自然的一件事。但是,寫(xiě)代碼的時(shí)候你就會(huì)發(fā)現(xiàn)繼承能做的事情,往往組合也能實(shí)現(xiàn),并且有時(shí)候會(huì)比用繼承更好。
我們寫(xiě)程序的一個(gè)目標(biāo)叫軟件復(fù)用,如果你的代碼里出現(xiàn)很多一模一樣的函數(shù),顯然并不是一份很好的設(shè)計(jì)。而正如世界一樣,我們的代碼也需要與時(shí)俱進(jìn),否則就會(huì)死亡。一份程序在剛寫(xiě)好的時(shí)候僅僅是開(kāi)始,后期花在維護(hù),改進(jìn),更新上的時(shí)間要遠(yuǎn)遠(yuǎn)多于剛開(kāi)始開(kāi)發(fā)的時(shí)間,這些就是所謂的“change”,正是這些變化才造成了你不斷的加班,正如前面讓你設(shè)計(jì)鴨子類(lèi)一樣,某天新發(fā)現(xiàn)10種鴨子,而你為了完成設(shè)計(jì),可能就要被迫加班。
那么應(yīng)該采取什么樣的設(shè)計(jì)才能有效的抵御變化,少加班呢?
我們有一個(gè)設(shè)計(jì)原則叫做:找出應(yīng)用中可能需要變化之處,把他們獨(dú)立出來(lái),不要和穩(wěn)定的代碼混在一起。
換句話說(shuō),如果每次新的需求依賴(lài),都會(huì)使某些方面的代碼發(fā)生變化,那么你就可以確定,這部分的代碼需要被抽離,和其他穩(wěn)定的代碼有所區(qū)分。也就是說(shuō)把會(huì)變化的部分取出并封裝起來(lái),以便以后可以輕易地改動(dòng)以擴(kuò)充此部分而不影響其它部分。
這個(gè)概念很簡(jiǎn)單,幾乎是每個(gè)設(shè)計(jì)模式背后的精神所在。所有的設(shè)計(jì)模式都提供了一套方法讓“系統(tǒng)中的某部分改變不會(huì)影響其它部分”。
策略模式代碼案例
封裝飛行行為;
class FlyBehavior
{
public:
virtual void fly() = 0;
};
class FlyWithWings : public FlyBehavior
{
public:
void fly()
{
cout << "Fly with Wings..." << endl;
}
};
class FlyNoway : public FlyBehavior
{
public:
void fly()
{
cout << "i can not fly..." << endl;
}
};
class FlyWithRockets : public FlyBehavior
{
public:
void fly()
{
cout << "Fly with Rockets..." << endl;
}
};
封裝叫聲行為;
class FlyBehavior
{
public:
virtual void fly() = 0;
};
class FlyWithWings : public FlyBehavior
{
public:
void fly()
{
cout << "Fly with Wings..." << endl;
}
};
class FlyNoway : public FlyBehavior
{
public:
void fly()
{
cout << "i can not fly..." << endl;
}
};
class FlyWithRockets : public FlyBehavior
{
public:
void fly()
{
cout << "Fly with Rockets..." << endl;
}
};
duck類(lèi)委托飛行行為與叫聲行為:文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-678706.html
class Duck
{
public:
FlyBehavior* flyBehavior;
QuackBehavior* quackBehavior;
void speak()
{
flyBehavior->fly();
quackBehavior->quack();
}
Duck(FlyBehavior* fly, QuackBehavior* quack)
{
this->flyBehavior = fly;
this->quackBehavior = quack;
}
};
實(shí)現(xiàn)具體的鴨子:文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-678706.html
class Duck1 : public Duck
{
public:
Duck1(FlyBehavior* fly, QuackBehavior* quack) : Duck(fly, quack) {}
};
到了這里,關(guān)于【設(shè)計(jì)模式】Head First 設(shè)計(jì)模式——策略模式 C++實(shí)現(xiàn)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!