小熊進階之Java編程大牛帶你學習設計模式

編程語言 設計模式 Java 軟件 小熊學IT 2017-04-25

小熊進階之Java編程大牛帶你學習設計模式

小熊進階之Java編程大牛帶你學習設計模式

  • 為什麼要學習設計模式

1、軟件開發越來越複雜,對軟件設計的要求也越來越高。而軟件設計和架構的入門功夫就是深入理解和掌握設計模式。因此,設計模式的重要性就不言而喻了。

2、設計模式已經成為軟件開發人員的“標準詞彙”

3、學習設計模式是個人提高的捷徑。為什麼這麼說呢?因為設計模式其本質是很多前輩(大牛級人物)經驗的積累,都是一些相對優秀的解決方案,而且很多問題都是典型的有代表性的問題。我們可以透過設計模式去學習到這些牛人的解決方法,看看人家是怎麼解決的。我們學習設計模式就可以學習到眾多前輩的經驗,吸收和領會他們的設計思想。掌握他們解決問題的辦法。變相就相當於你跟牛人在學習了。這時候就相當於站在這些巨人的肩膀上,可以讓自己的能力得到快速的提升。雖然說學習設計模式有一定的難度,但絕對是快速提高個人能力的捷徑。有句話叫強將將手下無弱兵。雖然我們可能達不到這些牛人的水平,但我們可以吸收他們的一些精華;吸收他們一部分思想;吸收他們解決問題的方式和方法。其實無形當中自己的水平也會提高不少。

4、不用重複發明輪子。設計模式本身就是解決特定問題的方式和方案,當我們遇到這些問題的時候,就可以直接使用這些設計模式了。這樣可以節省我們大量的時間,而不用在花時間去找解決方案了。

好的,接下來進入正題。下面主要介紹下策略模式:

什麼是策略模式呢?

小熊進階之Java編程大牛帶你學習設計模式

小熊進階之Java編程大牛帶你學習設計模式

策略模式定義了算法族,分別封裝起來,讓它們之間可以相互替換,此模式讓算法分別獨立於使用算法的用戶。

上面的定義你明白了嗎?

我覺得聰明伶俐的你肯定已經明白了,那你看看我是怎麼理解的吧。

就是將一個基類中一些行為進行分類,然後在應用到具體的類中選擇這些具體的類別,下面我們舉個例子來看看。

深入理解策略模式

假如現在有個需求,要求你寫一個鴨子基類,這個鴨子基類要求有三個方法,分別是quak、fly、display,具體的鴨子種類繼承這個基類。

根據這個需求,首先想到的應該是這樣的

public class Duck { 
 private String color; 
 public Duck(String color) { 
 super(); 
 this.color = color; 
 } 
 public String getColor() { 
 return color; 
 } 
 public void setColor(String color) { 
 this.color = color; 
 } 
 public void quake() { 
 System.out.println("嘎嘎嘎..."); 
 } 
 public void display() { 
 System.out.println("我是一隻" + color + "的鴨子"); 
 } 
 public void fly() { 
 System.out.println("飛啊飛啊..."); 
 }
}

這個基類完成後,其他的具體鴨子繼承這個基類,然後在寫其他的特有屬性或方法。

但是呢?這是不是存在一些問題呢?所有的鴨子都是‘嘎嘎嘎’的叫嗎,所有的鴨子都能飛嗎?我覺得肯定有一些比較奇葩的鴨子...所以呢我們這個設計存在這問題,此時應該怎麼解決呢?這時候你應該會想到吧這個定義成一個接口,讓其他的子類去實現它。具體代碼應該如下:

public interface BaseDuck { 
 void quak(); 
 void display(); 
 void fly();

或者我們也可以定義一個抽象類,將一些不怎麼需要變化的方法在基類實現,而另外一些方法由子類去實現,示例如下:

public abstract class AbstractDuck { 
 private String color;
 public String getColor() {
 return color;
 }
 public void setColor(String color) {
 this.color = color;
 }
 public abstract void quak();
 public void display() {
 System.out.println("我是一隻" + color + "的鴨子");
 }
 public abstract void fly();
}

這時候這個代碼還行,但是它真的沒有缺陷了嗎?可能忽略了一個問題,那就是我們這種設計是為了適應那些比較奇葩的鴨子種類。其他大部分鴨子應該都是一樣的叫聲和是可以進行飛行的。那麼我們在寫子類的時候就會寫很多冗餘的代碼,那麼我們如何解決這個問題呢?

小熊進階之Java編程大牛帶你學習設計模式

小熊進階之Java編程大牛帶你學習設計模式

策略模式就是解決這種問題的,它是如何實現的呢?先分析這個基類,quak和fly這兩個是容易變化的,客戶說不定那一天就要你加一個玩具鴨什麼的。所以就這兩個行為寄抽取出來,單獨進行編寫。先定義兩個接口QuakBehavior和FlyBehavior,然後在根據需求編寫一些子類,如能飛和不能飛、‘嘎嘎嘎’和‘吱吱吱’和不會叫等。示例代碼如下:

下面代碼是多個文件

//QuackBehavior.java
 public interface QuackBehavior { 
 void quak();
 }
 //FlyBehavior.java
 public interface FlyBehavior { 
 void fly();
 }
 //Quack.java
 public class Quack implements QuackBehavior { 
 @Override 
 public void quak() { 
 System.out.println("嘎嘎嘎..."); 
 }
 }
 //Squeak.java
 public class Squeak implements QuackBehavior { 
 @Override 
 public void quak() { 
 System.out.println("吱吱吱..."); 
 }
 }
 //QuackNoWay.java
 public class QuackNoWay implements QuackBehavior { 
 @Override 
 public void quak() { 
 System.out.println("我不會叫..."); 
 }
 }
 //FlyWithWings.java
 public class FlyWithWings implements FlyBehavior { 
 @Override 
 public void fly() { 
 System.out.println("飛啊飛啊..."); 
 }
 }
 //FlyNoWay.java
 public class FlyNoWay implements FlyBehavior { 
 @Override 
 public void fly() { 
 System.out.println("我不會飛..."); 
 }
 }

基類應該這樣設計:

package model.strategy.v2;
public class Duck { 
 private String color; //添加行為接口的字段
 private QuackBehavior quackBehavior; 
 private FlyBehavior flyBehavior; 
 public Duck() {
 } 
 public Duck(String color, QuackBehavior quackBehavior, FlyBehavior flyBehavior) { 
 super(); 
 this.color = color; 
 this.quackBehavior = quackBehavior; 
 this.flyBehavior = flyBehavior;
 } 
 public String getColor() { 
 return color;
 } 
 public void setColor(String color) { 
 this.color = color;
 } 
 public void quake() {//調用接口方法
 quackBehavior.quak();
 } public void display() {
 System.out.println("我是一隻" + color + "的鴨子");
 } public void fly() {//調用接口方法
 flyBehavior.fly();
 }
}

現在想想這個問題是不是很好的解決了!如果新的需求來了,我們只要定義一個新的接口實現了,而不需要修改這個基類中的代碼。

-----------------------------------------

如果喜歡請轉發,小小支持一下。

相關推薦

推薦中...