成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

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

張率功 / 1964人閱讀

摘要:抽象策略策略類,通常是一個(gè)接口或者抽象類。策略模式設(shè)計(jì)圖改造原來的鴨子類代碼實(shí)現(xiàn)這里我們將類定義成抽象類,并把方法定義成抽象方法。策略模式提供了可以替換繼承關(guān)系的辦法。使用策略模式可以避免使用多重條件轉(zhuǎn)移語句。四參考資料設(shè)計(jì)模式

一、了解策略模式

1.1 什么是策略模式

策略模式 (Strategy Pattern) 是指對(duì)一系列的算法定義,并將每一個(gè)算法封裝起來,而且使它們還可以相互替換。此模式讓算法的變化獨(dú)立于使用算法的客戶。

1.2 策略模式組成結(jié)構(gòu)

環(huán)境 (Context):持有一個(gè)策略類的引用,最終給客戶端調(diào)用。

抽象策略 (Strategy): 策略類,通常是一個(gè)接口或者抽象類。

具體策略 (ConcreteStrategy):實(shí)現(xiàn)了策略類中的策略方法,封裝相關(guān)的算法和行為。

1.3 策略模式 UML 圖解

1.4 策略模式應(yīng)用場(chǎng)景

多個(gè)類只區(qū)別在表現(xiàn)行為不同,可以使用 Strategy 模式,在運(yùn)行時(shí)動(dòng)態(tài)選擇具體要執(zhí)行的行為。

需要在不同情況下使用不同的策略 (算法),或者策略還可能在未來用其它方式來實(shí)現(xiàn)。

對(duì)客戶隱藏具體策略 (算法) 的實(shí)現(xiàn)細(xì)節(jié),彼此完全獨(dú)立。

二、策略模式具體應(yīng)用

2.1 問題描述

模擬鴨子游戲:游戲中會(huì)出現(xiàn)各種鴨子,一邊游泳戲水、一邊呱呱叫,為了提高游戲的樂趣,加入了讓鴨子飛的功能。但是考慮到并不是所有的鴨子都會(huì)飛,比如像小孩子游泳時(shí)玩的橡皮鴨?,F(xiàn)在讓你利用 OO 技術(shù),設(shè)計(jì)鴨子相關(guān)的類。

2.2 使用繼承


我們可能想到使用繼承,在超類 Duck 中定義鴨子的相關(guān)方法,并實(shí)現(xiàn)其對(duì)應(yīng)的動(dòng)作,這樣就能讓所有鴨子都可以對(duì)應(yīng)其 fly() 的動(dòng)作。在定義橡皮鴨時(shí),只需要覆蓋其父類 (Duck) 中的 fly() 方法即可。

如果我們還想加入誘餌鴨,這種鴨子既不會(huì)叫,也不會(huì)飛,那么我們就要繼承 Duck 類,重寫其中的 quack() 、display()fly() 方法。

這種通過繼承的方法是可以解決問題,但是有很多的局限

代碼在多個(gè)子類中重復(fù)。

運(yùn)行時(shí)的行為不容易改變。

很難知道鴨子的全部行為。

改變會(huì)牽一發(fā)動(dòng)全身,造成其他鴨子不想要的改變。

2.3 使用接口

認(rèn)識(shí)到上面繼承的不足,我們可能想到了另一種方式去解決這種問題,通過接口的方式去實(shí)現(xiàn)某些動(dòng)作。把 fly()quack() 方法從 Duck 類中抽取抽取出來,分別放在 FlyableQuackable 接口中。

通過接口的方式是可以完成任務(wù),但是這也確實(shí)是一個(gè)很笨的方式。因?yàn)閷?duì)于很多種鴨子來說,它們大部分都會(huì)飛與呱呱叫,但是我們?cè)诙x它們類的時(shí)候都要去實(shí)現(xiàn) FlyableQuackable 接口,這樣一來重復(fù)的代碼更多了。

2.4 問題歸零

到這里我們知道使用繼承并不能很好的解決問題,因?yàn)轼喿拥男袨樵谧宇愔惺遣粩嘧兓?,并且讓所有的鴨子都具有這些行為是不恰當(dāng)?shù)模热缦鹌啿痪哂酗w的行為。通過接口的方式似乎還不錯(cuò),但是 Java 接口并不具備實(shí)現(xiàn)代碼,所以繼承接口并不能達(dá)到代碼復(fù)用的目的,一不小心,就可能造成新的錯(cuò)誤!

幸運(yùn)的是,有一個(gè)設(shè)計(jì)原則,恰好適用于這種狀況:找出應(yīng)用中可能需要變化之處,把它們獨(dú)立出來,不要和那些不需要變化的代碼混在一起。這樣以來,代碼變化引起的后果變少,系統(tǒng)將更有彈性。

2.5 策略模式登場(chǎng)

除了 fly()quack() 方法之外,Duck 中的其他方法還算一切正常,沒有什么需要經(jīng)常需要變化或修改的地方。所以除了 fly()quack() 方法,我們不打算對(duì) Duck 中的其他方法做太多處理。我們希望一切具有彈性,正是因?yàn)闆]有彈性,上面兩種方法都被我們淘汰掉了。

比如說,我們要產(chǎn)生一個(gè)綠頭鴨的實(shí)例,并制定特定“類型”的飛行行為給它。我們可以在鴨子類中包含設(shè)定行為的方法,這樣就可以在“運(yùn)行時(shí)”動(dòng)態(tài)地“改變”綠頭鴨的飛行行為。

有了這些實(shí)現(xiàn)目標(biāo),于是就有了第二個(gè)設(shè)計(jì)原則:針對(duì)接口編程,而不是針對(duì)實(shí)現(xiàn)編程。

這里我們使用接口代表每個(gè)行為,比如說,FlyBehaviorQuackBehavior,而行為的每個(gè)實(shí)現(xiàn)都將實(shí)現(xiàn)其中一個(gè)接口。所以這次鴨子類不會(huì)去實(shí)現(xiàn) FlyableQuackable 接口,反而是由我們制造一組其他類專門實(shí)現(xiàn) FlyBehaviorQuackBehavior,這就稱為“行為”類。由行為類而不是 Duck 類來實(shí)現(xiàn)該接口。

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

改造原來的鴨子類

(2) 代碼實(shí)現(xiàn)

這里我們將 Duck 類定義成抽象類,并把 display() 方法定義成抽象方法。

接口 QuackBehavior

package com.jas.strategy;

public interface QuackBehavior {
    void quack();
}

接口 QuackBehavior 實(shí)現(xiàn)類 Quack(實(shí)現(xiàn)鴨子呱呱叫)

package com.jas.strategy;

public class Quack implements QuackBehavior {
    @Override
    public void quack() {
        System.out.println("Quack!");
    }
}

接口 QuackBehavior 實(shí)現(xiàn)類 SQuack(實(shí)現(xiàn)鴨子橡皮吱吱叫)

package com.jas.strategy;

public class SQuack implements QuackBehavior {
    @Override
    public void quack() {
        System.out.println("SQuack!");
    }
}

接口 QuackBehavior 實(shí)現(xiàn)類 MuteQuack(實(shí)現(xiàn)鴨子不會(huì)叫)

package com.jas.strategy;

public class MuteQuack implements QuackBehavior {
    @Override
    public void quack() {
        System.out.println("Silence!");
    }
}

接口 FlyBehavior

package com.jas.strategy;

public interface FlyBehavior {
    void fly();
}

接口 FlyBehavior 實(shí)現(xiàn)類 FlyWithWings(實(shí)現(xiàn)鴨子飛)

package com.jas.strategy;

public class FlyWithWings implements FlyBehavior {
    @Override
    public void fly() {
        System.out.println("I"m flying!");
    }
}

接口 FlyBehavior 實(shí)現(xiàn)類 FlyNoWay(實(shí)現(xiàn)鴨子不會(huì)飛)

package com.jas.strategy;

public class FlyNoWay implements FlyBehavior {
    @Override
    public void fly() {
        System.out.println("I can"t fly!");
    }
}

Duck

package com.jas.strategy;

public abstract class Duck {
    private QuackBehavior quackBehavior;
    private FlyBehavior flyBehavior;
    
    public void swim(){
        System.out.println("All ducks float.");
    }
    
    public abstract void display();
    
    public void performQuack(){
        quackBehavior.quack();
    }

    public void performFly(){
        flyBehavior.fly();
    }
    
    public void setQuackBehavior(QuackBehavior quackBehavior){
        this.quackBehavior = quackBehavior;
    }
    
    public void setFlyBehavior(FlyBehavior flyBehavior){
        this.flyBehavior = flyBehavior;
    }
    
}

測(cè)試類 RubberDuck

package com.jas.strategy;

public class RubberDuck extends Duck {

    @Override
    public void display() {
        System.out.println("Rubber Duck");
    }
    
    public static void main(String[] args) {
        
        Duck rubberDuck = new RubberDuck();    //橡皮鴨實(shí)例
        
        rubberDuck.setQuackBehavior(new SQuack());    //橡皮鴨吱吱叫
        rubberDuck.setFlyBehavior(new FlyNoWay());    //橡皮鴨不會(huì)飛
        
        rubberDuck.performQuack();
        rubberDuck.performFly();
    }
}

//輸出
//SQuack!
//I can"t fly!

2.6 從策略模式組成結(jié)構(gòu)對(duì)問題進(jìn)行總結(jié)

三、策略模式總結(jié)

3.1 策略模式的優(yōu)缺點(diǎn)

優(yōu)點(diǎn)

策略模式提供了管理相關(guān)的算法族的辦法,從而避免重復(fù)的代碼。

策略模式提供了可以替換繼承關(guān)系的辦法。因?yàn)槔^承使得動(dòng)態(tài)改變算法或行為變得不可能。

使用策略模式可以避免使用多重條件轉(zhuǎn)移語句。

缺點(diǎn)

客戶端必須知道所有的策略類,并自行決定使用哪一個(gè)策略類。

策略模式造成很多的策略類,每個(gè)具體策略類都會(huì)產(chǎn)生一個(gè)新類。

四、參考資料

《Head First 設(shè)計(jì)模式》

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/77250.html

相關(guān)文章

  • php設(shè)計(jì)模式

    摘要:我們今天也來做一個(gè)萬能遙控器設(shè)計(jì)模式適配器模式將一個(gè)類的接口轉(zhuǎn)換成客戶希望的另外一個(gè)接口。今天要介紹的仍然是創(chuàng)建型設(shè)計(jì)模式的一種建造者模式。設(shè)計(jì)模式的理論知識(shí)固然重要,但 計(jì)算機(jī)程序的思維邏輯 (54) - 剖析 Collections - 設(shè)計(jì)模式 上節(jié)我們提到,類 Collections 中大概有兩類功能,第一類是對(duì)容器接口對(duì)象進(jìn)行操作,第二類是返回一個(gè)容器接口對(duì)象,上節(jié)我們介紹了...

    Dionysus_go 評(píng)論0 收藏0
  • php設(shè)計(jì)模式

    摘要:我們今天也來做一個(gè)萬能遙控器設(shè)計(jì)模式適配器模式將一個(gè)類的接口轉(zhuǎn)換成客戶希望的另外一個(gè)接口。今天要介紹的仍然是創(chuàng)建型設(shè)計(jì)模式的一種建造者模式。設(shè)計(jì)模式的理論知識(shí)固然重要,但 計(jì)算機(jī)程序的思維邏輯 (54) - 剖析 Collections - 設(shè)計(jì)模式 上節(jié)我們提到,類 Collections 中大概有兩類功能,第一類是對(duì)容器接口對(duì)象進(jìn)行操作,第二類是返回一個(gè)容器接口對(duì)象,上節(jié)我們介紹了...

    vspiders 評(píng)論0 收藏0
  • 我的Java設(shè)計(jì)模式-策略模式

    摘要:孫臏心里一萬個(gè)草泥馬在奔騰,差點(diǎn)沒噎死自己滾一邊去,我們這盤跟他賽馬開始,策略模式上場(chǎng)。在設(shè)計(jì)模式之禪中的提出通過策略枚舉和反射機(jī)制對(duì)策略模式進(jìn)行改良,膜拜了但是要添加或淘汰策略,還是得去對(duì)枚舉進(jìn)行修改,也不符合開閉原則。 今天給大家說說田忌賽馬的故事。如有雷同,純屬巧合!話說在戰(zhàn)國(guó)時(shí)期,群雄割據(jù),硝煙四起,茶余飯后還是少不了娛樂活動(dòng)的,其中賽馬是最火爆的。一天,孫臏看到田忌像個(gè)死雞似...

    zilu 評(píng)論0 收藏0
  • Java設(shè)計(jì)模式策略模式詳解

    摘要:下面我們就來介紹怎么用策略模式來解決這個(gè)問題。結(jié)果很快的跳很快的跑紅藍(lán)相間的超人狗不會(huì)跳不會(huì)跑紅藍(lán)相間的超人狗總結(jié)策略模式就是把所有的可變的行為都抽取出來放到接口中,然后定義很多的行為類去實(shí)現(xiàn)接口。 策略模式就是定義了一系列的的算法,將它們都單獨(dú)封裝起來,讓他們之間可以相互替換,可以讓算法的變化獨(dú)立于使用算法的客戶。 首先創(chuàng)建一個(gè)Dog父類,有run方法控制跑,jump方法控制跳,c...

    DevTalking 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<