1. 程式人生 > >王者榮耀之「裝飾者模式」

王者榮耀之「裝飾者模式」

我要buff

前言

之前寫過一篇英雄聯盟之「策略模式」,居然有人說沒玩過,那麼今天給大家帶來一篇王者榮耀篇,如果還沒玩過,那就去玩玩,畢竟學習是需要付出成本的!

問答環節

在王者榮耀中buff對於整場比賽起著至關重要的作用,那麼如果用OO思想來設計這些buff?

小明:簡單,繼承原來的英雄類加個buff屬性就好了。

厲害了,我的明,看到你這多類,我心好累!你這還是一個英雄,那麼多個英雄就多少個類?還有如果遊戲再新增一個黃buff呢?那你又要新增多少個不同的buff類?

小明:你這麼一說,好像確實不對勁,雖然是copy程式碼,但是作為準高階工程師的我來說還是需要改進的。這樣吧我在所有英雄的基類新增buff屬性好了,這樣一來就一勞永逸了,完美的解決了你上面提到的2個問題,無論多少英雄,無論多少buff,從此再也不要新增類了。是不是很強勢?快誇我!


這樣確實不需要新增類了,但是你有沒有考慮到buff是可以疊加的,比如你有紅buff了還可以有籃buff,這樣新增一個新的buff就會新增成本的方法數,而且每次新增buff就需要修改原有的程式碼,這樣維護真的好嗎?

開閉原則:類應該對擴充套件開發,對修改關閉。

小明:那可怎麼辦呀?這也不行,那也不行!

給你個提示吧,上次我們提到了一個設計原則:多用組合,少用繼承。你往這方面想想,別腦子裡只有繼承。

小明:我知道了,其實可以新建一個“裝飾類”,把 紅buff,籃buff,龍buff,可以看成一件衣服,需要的時候就用相應的衣服穿上去給相應的英雄,這樣一來新增一個buff我只需要新增一個類就好了,並且不需要修改原有的程式碼。
李白:還有誰?


這樣就對了,程式碼上起來!

程式碼環節

抽象父類

public abstract class 英雄 {
  public abstract int 攻擊()
  public abstract int 冷卻()
   ........
}

實現英雄的李白。

public class 李白 extends 英雄 {
   @Override
   public int 冷卻(){
      return 5;
  }
   ........
}

Buff抽象類

public abstract Buff extends 英雄 {
   public abstract
int 攻擊() public abstract int 冷卻() ........ }

不同Buff的實現類。

public 紅buff extends Buff {

   private 英雄 英雄;
   publicbuff(英雄 英雄){
        this.英雄 = 英雄;
    }
     @Override
   public int 攻擊() {
     return 英雄.攻擊() + 紅buff額外攻擊;
   }
   .........

}
public 藍buff extends Buff {

   private 英雄 英雄;
   publicbuff(英雄 英雄){
        this.英雄 = 英雄;
    }

    @Override
   public int 冷卻() {
     return 英雄.冷卻()  + 籃buff額外減少的冷卻值;
   }
   .........

}

客戶端

public class Client {
    public static void main(String[] args) {
        // 沒有buff的英雄
        英雄 無buff李白 = new 李白();

        // 打了紅
        紅buff 紅buff李白 = new 紅buff(無buff李白);

        // 再來個籃
        籃buff 紅藍buff李白 = new 籃buff(紅buff李白);

    }
}

總結

《Head first 設計模式》
這就是「裝飾者模式」,在不必改變原類檔案(英雄類)和使用繼承的情況下,動態地擴充套件一個物件(李白)的功能。它是通過建立一個包裝物件(buff類:紅buff,籃buff, …),也就是裝飾來包裹真實的物件。

最後為了讓大家感受下BUFF對於整場比賽起著重要性,送上「王者榮耀 鬼畜神曲《我拿BUFF》

穩住,我們能贏!

以上程式碼塊用中文編寫類名、變數名是為了讓大家更好的理解,在實戰過程中記得替換成相對應的英文。