經過前幾天的內容,以上都了解後,應該也可以順利地組合出最終UML的樣子了:(參考原書以draw.io繪製)
可以看到會變的部分被封裝了起來,其他行為再怎麼改,都不會影響到原本鴨子的部分!
是否有一點感覺了呢?再重新看一次before& after的關係,大概就可以掌握策略模式了。
我們也來同步看看程式碼的對應實作成果:(以C++改寫原書程式碼)FlyBehavior
與Duck
前兩天都有了,就來看看QuackBehavior
與MallardDuck
吧
QuackBehavior
class QuackBehavior // interface of quack
{
public:
virtual void quack()=0;
};
class QuackWithQuack: public QuackBehavior
{
public:
void quack() override
{
cout << "quack!" << endl;
}
};
MallardDuck
與其他的鴨子們class MallardDuck: public Duck
{
public:
MallardDuck ()
{
flyBehavior = new FlyInSky();
quackBehavior = new QuackWithQuack();
}
void display () override
{
cout << "a green head duck" << endl;
}
};
class AAADuck: public Duck
{
public:
AAADuck ()
{
flyBehavior = new FlyNoWay();
quackBehavior = new QuackWithQuack();
}
void display () override
{
cout << "AAA duck" << endl;
}
};
實際執行看看:
int main()
{
Duck *mallard = new MallardDuck();
mallard->display();
mallard->performFly();
mallard->performQuack();
Duck *aaa = new AAADuck();
mallard->display();
mallard->performFly();
mallard->performQuack();
return 0;
}
// -----output-----
a green head duck
quack!
fly in sky!
AAA duck
quack!
cannot fly!
試試昨天說的,動態改變鴨子的行為!
int main()
{
Duck *mallard = new MallardDuck();
mallard->display();
mallard->performFly();
mallard->performQuack();
Duck *aaa = new AAADuck();
aaa->display();
aaa->performFly();
aaa->performQuack();
cout<<"---mallard duck wings are hurt---"<<endl;
mallard->setFlyBehavior(new FlyNoWay());
mallard->display();
mallard->performFly();
mallard->performQuack();
return 0;
}
// -----output-----
a green head duck
quack!
fly in sky!
AAA duck
quack!
cannot fly!
---mallard duck wings are hurt---
a green head duck
quack!
cannot fly!
輸出一如預期~!
再回到上面的UML,此時本書再提到了第三個原則:
多用"組合",少用"繼承"
從上面的圖中可以看到把鴨子與兩個行為類別組合起來的關係是使用 組合(HAS-A) 關係,就避免了 繼承(IS-A) 的行為需要在一開始就定義好,可以在執行其改變行為,而很多設計模式都利用了"組合"的特性。
終於終於,我們跟著實作完了整個策略模式的範例!來看看策略模式的定義!
策略模式可以定義和封裝一系列的演算法,並且讓它們是可替換的,讓你在不影響用戶端的情況下獨立改變演算法。
這幾天的內容大概就是第一章的部份。主要把握OO基本概念、三個原則與策略模式的定義,就可以繼續來看下一個模式了~ 本章提到的是非常基礎的概念,且可以輕易應用在軟體開發的過程中;下次開發時不妨把這幾個原則與定義放在心裡,作為設計程式的大原則。
本章最後還有提到為什麼要將設計模式分門別類並學習,以及正確的心態,留待明天繼續。