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

歡迎訪問 生活随笔!

生活随笔

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

java

Java设计模式(学习整理)---策略模式

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

? ?1. 模式定義
???????  ?把會變化的內容取出并封裝起來,以便以后可以輕易地改動或擴充部分,而不影響不需要變化的其他部分;     

 2.模式本質:

    ?少用繼承,多用組合,簡單地說就是:固定不變的信息封裝在一個類中,變化的信息我們使用接口,抽象定義,那么使用的時候:繼承不變的,自定義實現變化的那 ? ? ? ? ? ? ?部分!

 3.舉例分析:    

    

示例:

   一個鴨子類型: 抽象類型

? /*抽象的鴨子類*/
1
public abstract class Duck { 2 //所有的鴨子均會叫以及游泳,所以父類中處理這部分代碼 3 public void quack() { 4 System.out.println("嘎嘎嘎....."); 5 } 6 7 public void swim() { 8 System.out.println("游啊游......."); 9 } 10 11 //因為每種鴨子的外觀是不同的,所以父類中該方法是抽象的,由子類型自己完成。 12 public abstract void display(); 13 }

?

?  具體鴨子的繼承子類:

1 public class MallardDuck extends Duck { 2 //野鴨外觀顯示為綠頭 3 public void display() { 4 System.out.println("我是綠頭鴨子......"); 5 } 6 } 7 8 public class RedHeadDuck extends Duck { 9 //紅頭鴨顯示為紅頭 10 public void display() { 11 System.out.println("我是紅頭鴨子......"); 12 } 13 } 14 15 public class RubberDuck extends Duck { 16 //橡皮鴨叫聲為嘎嘎嘎叫,所以重寫父類以改寫行為 17 public void quack() { 18 System.out.println("嘎嘎嘎......."); 19 } 20 21 //橡皮鴨顯示為黃頭 22 public void display() { 23 System.out.println("我是黃頭鴨子......."); 24 } 25 }

?

??

/***************************【分析說明】***************************************/ 上述代碼,初始實現得非常好。現在我們如果給Duck.java中加入fly()方法的話,那么在子類型中均有了該方法,于是我們看到了 會飛的橡皮鴨子,你看過嗎?當然,我們可以在子類中通過空實現重寫該方法以解決該方法對于子類型的影響。但是父類中再增加其它的方法呢?通過繼承在父類中提供行為,會導致以下缺點:a. 代碼在多個子類中重復;b. 運行時的行為不容易改變;c. 改變會牽一發動全身,造成部分子類型不想要的改變;/******************************************************************************/

?

?  好啦,還是剛才鴨子的例子,你也許想到使用接口,將飛的行為、叫的行為定義為接口,然后讓Duck的各種子類型實現這些接口。

這時侯代碼類似于:

?

1 public abstract class Duck { 2 //將變化的行為 fly() 以及quake()從Duck類中分離出去定義形成接口,有需求的子類中自行去實現 3 4 public void swim() { 5 System.out.println("游啊游......."); 6 } 7 8 public abstract void display(); 9 } 10 11 //變化的 fly() 行為定義形成的接口 12 public interface FlyBehavior { 13 void fly(); 14 } 15 16 //變化的 quack() 行為定義形成的接口 17 public interface QuackBehavior { 18 void quack(); 19 } 20 21 //野鴨子會飛以及叫,所以實現接口FlyBehavior, QuackBehavior 22 public class MallardDuck extends Duck implements FlyBehavior, QuackBehavior{ 23 public void display() { 24 System.out.println("我是綠頭鴨......."); 25 } 26 27 public void fly() { 28 System.out.println("Fly."); 29 } 30 31 public void quack() { 32 System.out.println("嘎嘎嘎:綠鴨子叫........"); 33 } 34 } 35 36 //紅頭鴨子會飛以及叫,所以也實現接口FlyBehavior, QuackBehavior 37 public class RedHeadDuck extends Duck implements FlyBehavior, QuackBehavior{ 38 public void display() { 39 System.out.println("我是紅頭鴨......"); 40 } 41 42 public void fly() { 43 System.out.println("飛呀飛......."); 44 } 45 46 public void quack() { 47 System.out.println("嘎嘎嘎:紅鴨子叫"); 48 } 49 } 50 51 //橡皮鴨不會飛,但會嘎嘎嘎叫,所以只實現接口QuackBehavior 52 public class RubberDuck extends Duck implements QuackBehavior{ 53 //橡皮鴨叫聲為嘎嘎嘎叫 54 public void quack() { 55 System.out.println("嘎嘎嘎:橡皮鴨叫......"); 56 } 57 58 //橡皮鴨顯示為黃頭 59 public void display() { 60 System.out.println("我是黃頭鴨......"); 61 } 62 }

?

?

?

?分析:

上述代碼雖然解決了一部分問題,讓子類型可以有選擇地提供一些行為(例如 fly() 方法將不會出現在橡皮鴨中).但我們也看到,野鴨子MallardDuck.java和紅頭鴨子RedHeadDuck.java的一些相同行為代碼不能得到重復使用。很大程度上這是從一個火坑跳到另一個火坑。在一段程序之后,讓我們從細節中跳出來,關注一些共性問題。不管使用什么語言,構建什么應用,在軟件開發上,一直伴隨著的不變的真理是:需要一直在變化。不管當初軟件設計得多好,一段時間之后,總是需要成長與改變,否則軟件就會死亡。我們知道,繼承在某種程度上可以實現代碼重用,但是父類(例如鴨子類Duck)的行為在子類型中是不斷變化的,讓所有子類型都有這些行為是不恰當的。我們可以將這些行為定義為接口,讓Duck的各種子類型去實現,但接口不具有實現代碼,所以實現接口無法達到代碼復用。這意味著,當我們需要修改某個行為,必須往下追蹤并在每一個定義此行為的類中修改它,一不小心,會造成新的錯誤。

?

?設計原則:?

設計原則:
  把應用中變化的地方獨立出來,不要和那些不需要變化的代碼混在一起。這樣代碼變化引起的不經意后果變少,系統變得更有彈性。按照上述設計原則,我們重新審視之前的Duck代碼。
1) 分開變化的內容和不變的內容Duck類中的行為 fly(), quack(), 每個子類型可能有自己特有的表現,這就是所謂的變化的內容。Duck類中的行為 swim() 每個子類型的表現均相同,這就是所謂不變的內容。我們將變化的內容從Duck()類中剝離出來單獨定義形成接口以及一系列的實現類型。將變化的內容定義形成接口可實現變化內容和不變內容的剝離。其實現類型可實現變化內容的重用。這些實現類并非Duck.java的子類型,而是專門的一組實現類,稱之為"行為類"。由行為類而不是Duck.java的子類型來實現接口。這樣,才能保證變化的行為獨立于不變的內容。

?

于是我們有:

1 //變化的 fly() 行為定義形成的接口 2 public interface FlyBehavior { 3 void fly(); 4 } 5 6 //變化的 fly() 行為的實現類之一 7 public class FlyWithWings implements FlyBehavior { 8 public void fly() { 9 System.out.println("飛呀飛......"); 10 } 11 } 12 13 //變化的 fly() 行為的實現類之二 14 public class FlyNoWay implements FlyBehavior { 15 public void fly() { 16 System.out.println("我翅膀受傷了,飛不了......"); 17 } 18 }

?

1 //變化的 quack() 行為定義形成的接口 2 public interface QuackBehavior { 3 void quack(); 4 } 5 6 //變化的 quack() 行為實現類之一 7 public class Quack implements QuackBehavior { 8 public void quack() { 9 System.out.println("嘎嘎嘎......"); 10 } 11 } 12 13 //變化的 quack() 行為實現類之二 14 public class Squeak implements QuackBehavior { 15 public void quack() { 16 System.out.println("吱吱吱......."); 17 } 18 } 19 20 //變化的 quack() 行為實現類之三 21 public class MuteQuack implements QuackBehavior { 22 public void quack() { 23 System.out.println("啞巴,不會叫......."); 24 } 25 }

?

通過以上設計,fly()行為以及quack()行為已經和Duck.java沒有什么關系,可以充分得到復用。而且我們很容易增加新的行為, 既不影響現有的行為,也不影響Duck.java。但是,大家可能有個疑問,就是在面向對象中行為不是體現為方法嗎?為什么現在被定義形成類(例如Squeak.java)?在OO中,類代表的"東西"一般是既有狀態(實例變量)又有方法。只是在本例中碰巧"東西"是個行為。既使是行為,也有屬性及方法,例如飛行行為,也需要一些屬性記錄飛行的狀態,如飛行高度、速度等。

?

?整合變化的內容和不變的內容:

1 public abstract class Duck { 2 //將行為類聲明為接口類型,降低對行為實現類型的依賴 3 FlyBehavior flyBehavior; 4 QuackBehavior quackBehavior; 5 6 public void performFly() { 7 //不自行處理fly()行為,而是委拖給引用flyBehavior所指向的行為對象 8 flyBehavior.fly(); 9 } 10 11 public void performQuack() { 12 quackBehavior.quack(); 13 } 14 15 public void swim() { 16 System.out.println("游啊游......"); 17 } 18 19 public abstract void display(); 20 }

?

?Duck.java不關心如何進行 fly()以及quack(), 這些細節交由具體的行為類完成。

?

1 public class MallardDuck extends Duck{ 2 public MallardDuck() { 3 flyBehavior=new FlyWithWings(); 4 quackBehavior=new Quack(); 5 } 6 7 public void display() { 8 System.out.println("Green head."); 9 } 10 }

?

?

?

???測試類:

?

1 public class DuckTest { 2 public static void main(String[] args) { 3 Duck duck=new MallardDuck(); 4 duck.performFly(); 5 duck.performQuack(); 6 } 7 }

?

?

?

4.思想重點:


  (1)策略思想:繼承,可以實現靜態代碼的復用;
     組合,可以實現代碼的彈性維護;
     使用組合代替繼承,可以使代碼更好地適應軟件開發完后的需求變化。

? (2)策略模式的本質:
      少用繼承,多用組合

?

轉載于:https://www.cnblogs.com/newwind/p/5653097.html

總結

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

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