Head First設計模式——策略模式
阿新 • • 發佈:2019-02-05
《Head First設計模式》是一本介紹設計模式的書籍,書中的設計模式主要是用Java語言進行實現,由於本人對C++比較熟悉,因此在閱讀這本書籍時,儘自己所能,用C++重新去實現書中所涉及到的設計模式。若有錯誤或需要進一步討論之處,望閱覽者不吝賜教!
策略模式——定義了演算法族,分別封裝起來,讓它們之間可以互相替換,此模式讓演算法的變換獨立於使用演算法的客戶。
需求:一家公司需要設計一款模擬鴨子游戲的電子軟體。遊戲中會出現各種鴨子,比如橡皮鴨、誘餌鴨、鴨等,這些鴨子會有不同的行為,比如有的會叫、有的不會叫、有的會飛、有的不會飛等。為了適應不同的鴨子物件和鴨子行為,可以用策略模式進行整個框架的構建。
1、設計一個鴨子類Duck,一個飛行行為介面類(C++裡面沒有介面的的說法,這裡套用Java裡的說法,更容易理解)FlyBehavior,一個叫聲介面類QuackBehavior,這是第一個設計模式,所以沒有考慮周全,將這三個類放到了一個.h檔案裡;一般而言,應該分開為三個.h檔案。Duck.h、Duck.cpp檔案具體程式碼如下:
#pragma once #include<iostream> using namespace std; class FlyBehavior; class QuackBehavior; class CDuck { public: CDuck(); ~CDuck(); virtual void display() {} virtual void performFly(); virtual void performQuack(); void setFlyBehavior(FlyBehavior *fb); void setQuackBehavior(QuackBehavior *qb); void swim(); protected: FlyBehavior* flyBehavior; QuackBehavior* quackBehavior; }; class FlyBehavior { public: FlyBehavior() {} ~FlyBehavior() {} virtual void fly() {} private: }; class QuackBehavior { public: QuackBehavior() {} ~QuackBehavior() {} virtual void quack(){} private: }; class FlyWithWings:public FlyBehavior //第一個具體飛行行為類 { public: FlyWithWings() {} ~FlyWithWings() {} void fly() { cout << "I'm flying!!" << endl; } private: }; class FlyNoWay :public FlyBehavior //第二個具體飛行行為類 { public: FlyNoWay() {} ~FlyNoWay() {} void fly() { cout << "I can't fly!!" << endl; } private: }; class FlyRocketPowered:public FlyBehavior //第三個具體飛行行為類 { public: FlyRocketPowered(){} ~FlyRocketPowered(){} void fly() { cout << "I'm flying with rocket!!" << endl; } private: }; class Quack:public QuackBehavior //第一個具體叫聲類 { public: Quack() {} ~Quack() {} void quack() { cout << "Quack" << endl; } private: }; class MuteQuack :public QuackBehavior //第二個具體叫聲類 { public: MuteQuack() {} ~MuteQuack() {} void quack() { cout << "<< Silence >>" << endl; } private: }; class Squeak :public QuackBehavior //第三個具體叫聲類 { public: Squeak() {} ~Squeak() {} void quack() { cout << "Squeak" << endl; } private: };
#include "Duck.h" CDuck::CDuck() { } CDuck::~CDuck() { } void CDuck::performFly() { flyBehavior->fly(); } void CDuck::performQuack() { quackBehavior->quack(); } void CDuck::swim() { cout << "All ducks float,even decoys!!" << endl; } void CDuck::setFlyBehavior(FlyBehavior* fb) { flyBehavior = fb; } void CDuck::setQuackBehavior(QuackBehavior *qb) { quackBehavior = qb; }
2、建立兩個具體鴨子類:MallardDuck、ModelDuck,MallardDuck.h、MallardDuck.cpp、ModelDuck.h、ModelDuck.cpp檔案具體程式碼如下:
#pragma once
#include "Duck.h"
class CMallardDuck :public CDuck
{
public:
CMallardDuck();
~CMallardDuck();
void display();
};
#include "MallardDuck.h"
CMallardDuck::CMallardDuck()
{
quackBehavior = new Quack();
flyBehavior = new FlyWithWings();
}
CMallardDuck::~CMallardDuck()
{
}
void CMallardDuck::display()
{
cout << "I'm a real Mallard duck!!" << endl;
}
#pragma once
#include "Duck.h"
class CModelDuck :
public CDuck
{
public:
CModelDuck();
~CModelDuck();
void display();
};
#include "ModelDuck.h"
CModelDuck::CModelDuck()
{
flyBehavior = new FlyNoWay();
quackBehavior = new Quack();
}
CModelDuck::~CModelDuck()
{
}
void CModelDuck::display()
{
cout << "I'm a model duck!!" << endl;
}
3、測試程式碼和結果如下:
/*
策略模式:定義了演算法族,分別封裝起來,讓它們之間可以相互替換,此模式讓
演算法的變化獨立於使用演算法的客戶
*/
#include "Duck.h"
#include "MallardDuck.h"
#include "ModelDuck.h"
int main()
{
CDuck* mallard = new CMallardDuck();
mallard->performFly();
mallard->performQuack();
CDuck* model = new CModelDuck();
model->performFly();
model->setFlyBehavior(new FlyRocketPowered());
model->performFly();
delete mallard;
delete model;
return 0;
}
在講述策略模式時,書中涉及到了三個OO原則:
1、封裝變化,即將框架中易於變化的部分抽象出來,形成獨立的類;
2、多用組合,少用繼承,即類與類之間儘量處於合作關係,而不是依賴關係;
3、針對介面程式設計,不針對具體實現程式設計,即對介面程式設計,當需要進行變動時,只需變動介面即可。