日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java 设计模式之策略模式

發布時間:2024/9/30 java 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java 设计模式之策略模式 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、了解策略模式

1.1 什么是策略模式

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

1.2 策略模式組成結構

  • 環境 (Context):持有一個策略類的引用,最終給客戶端調用。
  • 抽象策略 (Strategy): 策略類,通常是一個接口或者抽象類。
  • 具體策略 (ConcreteStrategy):實現了策略類中的策略方法,封裝相關的算法和行為。

1.3 策略模式 UML 圖解

1.4 策略模式應用場景

  • 多個類只區別在表現行為不同,可以使用 Strategy 模式,在運行時動態選擇具體要執行的行為。
  • 需要在不同情況下使用不同的策略 (算法),或者策略還可能在未來用其它方式來實現。
  • 對客戶隱藏具體策略 (算法) 的實現細節,彼此完全獨立。

二、策略模式具體應用

2.1 問題描述

模擬鴨子游戲:游戲中會出現各種鴨子,一邊游泳戲水、一邊呱呱叫,為了提高游戲的樂趣,加入了讓鴨子飛的功能。但是考慮到并不是所有的鴨子都會飛,比如下面這種橡皮鴨。現在讓你利用 OO 技術,設計鴨子相關的類。



2.2 使用繼承

我們可能想到使用繼承,在超類 Duck 中定義鴨子的相關方法,并實現其對應的動作,這樣就能讓所有鴨子都可以對應其 fly() 的動作。在定義橡皮鴨時,只需要覆蓋其父類 (Duck) 中的 fly() 方法即可。

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



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

  • 代碼在多個子類中重復。
  • 運行時的行為不容易改變。
  • 很難知道鴨子的全部行為。
  • 改變會牽一發動全身,造成其他鴨子不想要的改變。

2.3 使用接口

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

通過接口的方式是可以完成任務,但是這也確實是一個很笨的方式。因為對于很多種鴨子來說,它們大部分都會飛與呱呱叫,但是我們在定義它們類的時候都要去實現 Flyable 和 Quackable 接口,這樣一來重復的代碼更多了。

2.4 問題歸零

到這里我們知道使用繼承并不能很好的解決問題,因為鴨子的行為在子類中是不斷變化的,并且讓所有的鴨子都具有這些行為是不恰當的,比如橡皮鴨不具有飛的行為。通過接口的方式似乎還不錯,但是 Java 接口并不具備實現代碼,所以繼承接口并不能達到代碼復用的目的,一不小心,就可能造成新的錯誤!

幸運的是,有一個設計原則,恰好適用于這種狀況:找出應用中可能需要變化之處,把它們獨立出來,不要和那些不需要變化的代碼混在一起。這樣以來,代碼變化引起的后果變少,系統將更有彈性。

2.5 策略模式登場

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

比如說,我們要產生一個綠頭鴨的實例,并制定特定“類型”的飛行行為給它。我們可以在鴨子類中包含設定行為的方法,這樣就可以在“運行時”動態地“改變”綠頭鴨的飛行行為。

有了這些實現目標,于是就有了第二個設計原則:針對接口編程,而不是針對實現編程。

這里我們使用接口代表每個行為,比如說,FlyBehavior 與 QuackBehavior,而行為的每個實現都將實現其中一個接口。所以這次鴨子類不會去實現 Flyable 和 Quackable 接口,反而是由我們制造一組其他類專門實現 FlyBehavior 與 QuackBehavior,這就稱為“行為”類。由行為類而不是 Duck 類來實現該接口。

(1)策略模式設計圖

改造原來的鴨子類

(2) 代碼實現

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

接口 QuackBehavior

package com.jas.strategy;public interface QuackBehavior {void quack(); }

接口 QuackBehavior 實現類 Quack(實現鴨子呱呱叫)

package com.jas.strategy;public class Quack implements QuackBehavior {@Overridepublic void quack() {System.out.println("Quack!");} }

接口 QuackBehavior 實現類 SQuack(實現鴨子橡皮吱吱叫)

package com.jas.strategy;public class SQuack implements QuackBehavior {@Overridepublic void quack() {System.out.println("SQuack!");} }

接口 QuackBehavior 實現類 MuteQuack(實現鴨子不會叫)

package com.jas.strategy;public class MuteQuack implements QuackBehavior {@Overridepublic void quack() {System.out.println("Silence!");} }

接口 FlyBehavior

package com.jas.strategy;public interface FlyBehavior {void fly(); }

接口 FlyBehavior 實現類 FlyWithWings(實現鴨子飛)

package com.jas.strategy;public class FlyWithWings implements FlyBehavior {@Overridepublic void fly() {System.out.println("I'm flying!");} }

接口 FlyBehavior 實現類 FlyNoWay(實現鴨子不會飛)

package com.jas.strategy;public class FlyNoWay implements FlyBehavior {@Overridepublic 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;}}

測試類 RubberDuck

package com.jas.strategy;public class RubberDuck extends Duck {@Overridepublic void display() {System.out.println("Rubber Duck");}public static void main(String[] args) {Duck rubberDuck = new RubberDuck(); //橡皮鴨實例rubberDuck.setQuackBehavior(new SQuack()); //橡皮鴨吱吱叫rubberDuck.setFlyBehavior(new FlyNoWay()); //橡皮鴨不會飛rubberDuck.performQuack();rubberDuck.performFly();} }//輸出 //SQuack! //I can't fly!

2.6 從策略模式組成結構對問題進行總結

三、策略模式總結

3.1 策略模式的優缺點

優點

1、 策略模式提供了管理相關的算法族的辦法,從而避免重復的代碼。
2、 策略模式提供了可以替換繼承關系的辦法。因為繼承使得動態改變算法或行為變得不可能。
3、 使用策略模式可以避免使用多重條件轉移語句。

缺點

1、客戶端必須知道所有的策略類,并自行決定使用哪一個策略類。
2、 策略模式造成很多的策略類,每個具體策略類都會產生一個新類。

PS:點擊了解更多設計模式 http://blog.csdn.net/codejas/article/details/79236013

四、參考文獻

《Head First 設計模式》

總結

以上是生活随笔為你收集整理的Java 设计模式之策略模式的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。