設計模式六大原則----------開閉原則

設計模式總覽


遵循開閉原則設計出的模塊具有兩個主要特徵:
(1)對於擴展是開放的(Open for extension)。這意味着模塊的行爲是可以擴展的。當應用的需求改變時,我們可以對模塊進行擴展,使其具有滿足那些改變的新行爲。也就是說,我們可以改變模塊的功能。
(2)對於修改是關閉的(Closed for modification)。對模塊行爲進行擴展時,不必改動模塊的源代碼或者二進制代碼。模塊的二進制可執行版本,無論是可鏈接的庫、DLL或者.EXE文件,都無需改動。

注意:這裏的修改指的是因功能拓展而引起的修改!!!!


實現方法:抽象出所有變化的部分。


EVP要求在做系統設計的時候,對系統所有可能發生的變化部分進行評估和分類,每一個可變的因素都單獨進行封裝。


舉例分析:

小狗在不同狀態(心情)下,會有不同的移動方式(狗也是有情緒滴撒)。比如:在開心的時候,跳着跑;傷心的時候低着頭跑;害怕的時候,夾着尾巴跑。

版本一:

if(state == "開心")
    跳着跑;
else if(state == "傷心")
	低着頭跑
else if(state == "害怕")
	夾着尾巴跑;
else
	正常跑
假如這段代碼是作爲sdk發出去的,不允許對其隨便修改!然而現在有新需求,要求在憤怒的時候,咬牙跑。問題來了,打破了開閉原則!

版本二:

IMove __move
void setMoveStage(IMove move)
{
	__move = move
}

void move()
{
	__move()
}

client:
if(dog.state == "開心")
	dog.setMoveStage(跳着跑)
else if(dog.state == "傷心")
	dog.setMoveStage(低着頭跑)
else if(dog.state == "害怕")
	dog.setMoveStage(夾着尾巴跑;)
else if(dog.state == "憤怒")
	dog.setMoveStage(咬牙跑)
else
	dog.setMoveStage(正常跑)
將變化的部分抽象出來,不變的部分放在dog中,現在再進行拓展,就不用修改dog的類了,只需要修改客戶端。

版本二的方法已經解決了開閉原則問題,並且它就是一個簡單的策略模式,但這樣的代碼太醜了,如果你有強迫症,可以再進行修改

版本三

void registMove(State state, IMove move)
{
	dictionary[state] = move;
}

void setState(State state)
{
	mState = state;
	mMove = dictionary[state];
}
client:
dog.setState("開心")

這樣,只需要在開始時,註冊好所有的移動方式,然後在每次改變心情時,自動的修改了相應的move方式。如果要進行拓展,添加新的移動方式,也只需要修改客戶端啓動時,註冊move的地方。


下面是個計算器的例子:

以簡單的計算器程序來說。假如讓你設計一個支持+、-、*、%的計算器,那麼在設計的時候肯定會想到以後會不會有拓展?拓展到支持平方、冪運算、開方等運算?那麼,這裏的運算功能就是一個可變部分,所以要對這個可變部分進行抽象。如圖:


當要拓展新的運算時,只需要根據操作數的個數添加相應的實體類就行了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章