天天看點

設計模式之裝飾者模式及其在java.io中的應用

文章目錄

    • 1. 裝飾者模式的簡介
    • 2. 執行個體講解
    • 3. 在java.io中的應用

1. 裝飾者模式的簡介

裝飾者模式(Decorator Pattern)允許向一個現有的對象添加新的功能,同時又不改變其結構。這種類型的設計模式屬于結構型模式,它是作為現有的類的一個包裝。

這種模式建立了一個裝飾類,用來包裝原有的類,并在保持類方法簽名完整性的前提下,提供了額外的功能。

2. 執行個體講解

這裡以吃火鍋為例進行講解:

設計模式之裝飾者模式及其在java.io中的應用

說明:火鍋是一個抽象類,鍋底和菜品都繼承了它,然後在點了一個具體的鍋底以後,可以添加菜品,由于可以添加多個菜品,這個時候就得考慮怎麼樣設計我們的代碼了,是以有了今天的主角==>裝飾者模式

如上所述,鍋底一個就ok,而菜品可以有多個,是以我們選擇将菜品作為裝飾者,而火鍋作為被裝飾者,具體代碼如下

火鍋、鍋底、菜品的具體代碼:

/**
 * 抽象類火鍋
 */
public abstract class HotPot {

  private String des;
  private float price;

  public String getDes() {
    return des;
  }

  public void setDes(String des) {
    this.des = des;
  }

  public float getPrice() {
    return price;
  }

  public void setPrice(float price) {
    this.price = price;
  }

  public abstract float cost();

}

// 鍋底
public class Bottom extends HotPot {
  @Override
  public float cost() {
    return super.getPrice();
  }
}

// 菜品  裝飾者
public class Dishes extends HotPot {

  // 引入被裝飾者
  private HotPot hotPot;

  public Dishes(HotPot hotPot) {
    this.hotPot = hotPot;
  }

  @Override
  public float cost() {
    // 計算價格
    return super.getPrice() + hotPot.cost();
  }

  @Override
  public String getDes() {
    return des + " " + getPrice() + " " + "&&" + " " + hotPot.getDes();
  }
}
           

鍋底的三個品種:

public class Spicy extends Bottom {
  public Spicy() {
    setDes("麻辣鍋底");
    setPrice(6.0f);
  }
}

public class ThreeFresh extends Bottom{
  public ThreeFresh() {
    setDes("三鮮鍋底");
    setPrice(5.0f);
  }
}

public class ClearSoup extends Bottom {
  public ClearSoup() {
    setDes("清湯鍋底");
    setPrice(4.0f);
  }
}

           

菜品的三種:

public class Beef extends Dishes {
  public Beef(HotPot hotPot) {
    super(hotPot);
    setDes("牛肉");
    setPrice(12.0f);
  }
}

public class Pork extends Dishes{
  public Pork(HotPot hotPot) {
    super(hotPot);
    setDes("豬肉");
    setPrice(11.0f);
  }
}

public class Mutton extends Dishes {
  public Mutton(HotPot hotPot) {
    super(hotPot);
    setDes("羊肉");
    setPrice(10.0f);
  }
}

           

開始吃了:

public class Eat {

  public static void main(String[] args) {
    // 1.點一份三鮮鍋
    HotPot hotPot = new ThreeFresh();
    System.out.println("費用:" + hotPot.getPrice() + "  描述:" + hotPot.getDes());

    // 2.加入一份牛肉
    hotPot = new Beef(hotPot);
    System.out.println("加入一份牛肉之後費用:" + hotPot.cost() + "  描述:" + hotPot.getDes());

    // 3.又加入一份豬肉
    hotPot = new Pork(hotPot);
    System.out.println("加入一份牛肉之後又加入一份豬肉費用:" + hotPot.cost() + "  描述:" + hotPot.getDes());
    
  }

}
           

運作結果如圖:

設計模式之裝飾者模式及其在java.io中的應用

簡單總結一下:裝飾者模式是建立在繼承之上的,但是比繼承更加靈活,從以上代碼可以看到,可以非常友善動态的增加我們的菜品

3. 在java.io中的應用

首先看一幅圖:

設計模式之裝飾者模式及其在java.io中的應用

再結合源碼:

設計模式之裝飾者模式及其在java.io中的應用
設計模式之裝飾者模式及其在java.io中的應用

由此我們可以發現,

InputStream

使用了裝飾者模式,其中

InputStream

是被裝飾者,

FilterInputStream

是裝飾者,而

ByteArrayInputStream

等就類似于我們的鍋底,

DataInputStream

等就類似于我們的菜品

繼續閱讀