1. 程式人生 > >《Head First設計模式》之策略模式

《Head First設計模式》之策略模式

設計模式原則總結

封裝變化:找出應用中可能需要變化之處,把它們獨立出來,不要和那些不需要變化的程式碼混在一起。

少用組合,多用繼承。

針對介面程式設計,而不是針對實現程式設計

策略模式定義:

將物件中的某些行為特徵(演算法簇)封裝起來,讓他們之間可以互相替換,此模式讓演算法的變化獨立於使用演算法的客戶物件。

以鴨子的飛行行為舉例,假設有很多的飛行方式,將飛行行為封裝為行為類,可以隨意替換行為類。

鴨子類:

#include "FlyBehavior.h"
//鴨子基類
class CDuck
{
private:

public:
	CFlyBehavior* flybehavior;
	CDuck()
	{
		flybehavior = NULL;
	}
	~CDuck(){}
	void performFly()
	{
		flybehavior->fly();
	}
	virtual void display() = 0;
	void setFlyBehavior(CFlyBehavior *fb)
	{
		flybehavior = fb;
	}
};
//鴨子子類
class CMallardDuck :public  CDuck
{
public:
	CMallardDuck()
	{
		if (NULL != flybehavior)
		{
			delete flybehavior;
		}
			flybehavior = new CFlyWithWings;
	}
	~CMallardDuck()
	{
		delete flybehavior;
	}
	void display()
	{
		std::cout << "I'm a Mallard duck !"<< std::endl;
	}
};
//另一個鴨子子類
class CModelDuck :public  CDuck
{
public:
	CModelDuck()
	{
		if (NULL != flybehavior)
		{
			delete flybehavior;
		}
		flybehavior = new CFlyNoWay;
	}
	~CModelDuck()
	{
		delete flybehavior;
	}
	void display()
	{
		std::cout << "I'm a Model duck !" << std::endl;
	}
};



鴨子行為類
#ifndef _FLYBEHAVIOR_
#define _FLYBEHAVIOR_
#include <iostream>
//行為基類
class CFlyBehavior
{
public:
	virtual void  fly() = 0;
};
//行為類 用翅膀飛
class CFlyWithWings :public CFlyBehavior
{
	void fly()
	{
		std::cout <<"I'm flying with wings !"<< std::endl;
	}
};
//行為類 不能飛
class CFlyNoWay :public CFlyBehavior
{
	void fly()
	{
		std::cout << "I can't fly!" << std::endl;
	}
};
//行為類 利用火箭飛
class CFlyRocketPowered :public CFlyBehavior
{
	void fly()
	{
		std::cout << "I'm flying with a rocket !" << std::endl;
	}
};
#endif _FLYBEHAVIOR_


測試程式碼

#include "Duck.h"
#include "FlyBehavior.h"

int main()
{
	CDuck *mallard = new CMallardDuck;//行為類是 用翅膀飛
	mallard->display();
	mallard->performFly();


	CDuck *model = new CModelDuck;//行為類是 不能飛 
	model->display();
	model->performFly();
	std::cout <<"change behavior" << std::endl;
	model->setFlyBehavior(new CFlyRocketPowered);//替換行為類 利用火箭飛
	model->performFly();

	delete mallard;
	delete model;
	system("pause");
}


結果: