設(shè)計(jì)模式之策略模式

需求:

1:模擬鴨子項(xiàng)目

從項(xiàng)目"模擬鴨子游戲"開始。

鴨子都會(huì)叫、會(huì)游泳。有的鴨子是紅頭的、有的鴨子是綠頭的。

分析:

從OO(Object?Oriented,面向?qū)ο?的角度設(shè)計(jì)這個(gè)項(xiàng)目。

鴨子的父類:

抽象的

1.都會(huì)gaga叫

2.抽象的外形(如:紅頭鴨、綠頭鴨等)

3.都會(huì)游泳

綜上所述,我們得到鴨子父類:

public?abstract?class?Duck?{

public??Duck(){};

//1:鴨子都會(huì)叫

public?void?quack(){

System.out.println("~嘎嘎叫~");

}

//2:抽象的外形

public?abstract?void??display();

//3:鴨子都會(huì)游泳

public?void?swim(){

System.out.println("~~swiming?~~");

}

}

具體實(shí)現(xiàn):

綠頭鴨:

public?class?GreenHeadDuck??extends??Duck{

@Override

public?void?display()?{

System.out.println("~~?i'm??GreenHeadDuck?~~?gaga");

}

}紅頭鴨:

public?class?RedHeadQuck?extends??Duck{

@Override

public?void?display()?{

System.out.println("~~?i'm??Read?~~?gaga");

}

}

新需求:

添加鴨子會(huì)飛的功能。

思考:

這個(gè)fly功能是放在父類中還是放到單個(gè)里面?

如果放到父類中,那么問(wèn)題來(lái)了。并不是所有的鴨子都會(huì)飛。如果放到父類中,就成了所有鴨子都會(huì)飛了。這個(gè)是不對(duì)的。

所以,我們從這里就可以看出如果使用繼承會(huì)導(dǎo)致的問(wèn)題;

對(duì)類的局部改變,尤其是父類的局部改變,會(huì)影響其他部分。這種影響會(huì)有溢出的效應(yīng)。

如果非要使用繼承方法,也是可以的。我們?cè)谧宇愔懈采w父類的方法。

如在綠頭鴨中將fly()方法覆蓋類。

public?void?Fly()?{

System.out.println("~~no?fly~~");

}

這個(gè)時(shí)候,又來(lái)新需求了了。需要一個(gè)石頭鴨子。我們知道石頭鴨子是不會(huì)飛、不會(huì)叫、不會(huì)游泳的

我們?nèi)绻^承了Duck類。那么,就要不停的去填坑的。

所以,我們可以看出這種需求下如果還是用OO面向?qū)ο笤瓌t來(lái)的話,會(huì)出現(xiàn):

父類挖的一個(gè)坑,每個(gè)子類都要來(lái)填坑。增加了工作量。其復(fù)雜度是O(N^2).這這種需求下,如果是這樣設(shè)計(jì)的話就不是一個(gè)好的設(shè)計(jì)方式。

我們就要思考,需要新的設(shè)計(jì)模式,來(lái)應(yīng)對(duì)項(xiàng)目的擴(kuò)展性,降低項(xiàng)目的復(fù)雜度。

1)分析項(xiàng)目變化于不變化的部分,提取變化部分、抽象成接口+實(shí)現(xiàn);

根據(jù)上面原則,我們?cè)趤?lái)看看鴨子游戲項(xiàng)目:

鴨子哪些功能會(huì)根據(jù)新需求變化呢?

如鴨子叫、飛行等等。

這個(gè)時(shí)候,我們可以設(shè)計(jì)如下接口:

鴨子飛行為的接口:

interface?FlyBehaviro{

void?fly();

}

鴨子叫行為的接口:

interface?Quackehavior{

void?quack();

}

有了這兩個(gè)接口之后,鴨子想飛實(shí)現(xiàn)飛行為的接口、鴨子想叫實(shí)現(xiàn)叫的接口。這樣組合起來(lái)更方便。

這樣做的好處:

新增行為簡(jiǎn)單了,行為類更好的被復(fù)用了,組合更方便了,既有繼承帶來(lái)的復(fù)用好處,而其還沒(méi)有挖坑。

根據(jù)上面分析,我們重新設(shè)計(jì)鴨子模式:

1:將行為提取成抽象接口

FlyBeahavior

QuackBehavior

2:在父類Duck中,將各個(gè)抽象接口作為屬性

@Data

public?abstract?class?Duck?{

public??Duck(){}

/**

*?飛行行為

*/

FlyBehavior?myFlyBehavior;

QuackBehavior?myQuackBehavior;

public?void?fly(){

myFlyBehavior.fly();

}

public?void?quack(){

myQuackBehavior.QuackBehavior();

}

public?abstract?void?display();

}

3:在創(chuàng)建具體鴨子對(duì)象的時(shí)候,將行為實(shí)例化到構(gòu)造器中。如下:

public?class?GreenHeadDuck??extends?Duck?{

public?GreenHeadDuck(){

myFlyBehavior?=?new?GoodFlyBehavior();

myQuackBehavior?=?new?GaGaQuackBehavior();

}

@Override

public?void?display()?{

System.out.println("~~?i'm??GreenHeadDuck?~~?gaga");

}

}

在測(cè)試方法中,父類實(shí)例化使用子類對(duì)象。如下:

Duck?greenHeadDuck?=?new?GreenHeadDuck();

greenHeadDuck.display();

greenHeadDuck.fly();

greenHeadDuck.quack();

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 客戶需求 程序設(shè)計(jì) 1、直接利用繼承如何? 將以上四種行為全部寫到Duck這個(gè)基類中,然后子類重寫飛和叫的行為。但...
    BlainPeng閱讀 534評(píng)論 2 7
  • 定義:定義了算法簇,分別封裝起來(lái),讓他們之間可以相互替換,此模式讓算法的變化獨(dú)立于使用算法的客戶。 優(yōu)點(diǎn):代碼的復(fù)...
    彼訫閱讀 129評(píng)論 0 0
  • 策略模式,是我們接觸到的第一個(gè)設(shè)計(jì)模式,也是較容易理解的一個(gè)模式。我們可以給它下一個(gè)定義:** 定義了算法族,分別...
    六尺帳篷閱讀 848評(píng)論 0 8
  • 策略模式的定義 策略模式(Strategy Pattern):定義一系列算法,將每一個(gè)算法封裝起來(lái),并讓它們可以相...
    戴先森Davi閱讀 1,115評(píng)論 0 2
  • 1感恩團(tuán)隊(duì)的互相配合,早上成功募捐到300元。 2感恩夢(mèng)婷完成任務(wù)的過(guò)程中不斷的給團(tuán)隊(duì)的人加油打氣。 3感恩波姐把...
    睿智女人林裕絲閱讀 117評(píng)論 0 0

友情鏈接更多精彩內(nèi)容