文章目錄
-
- 1. 裝飾者模式的簡介
- 2. 執行個體講解
- 3. 在java.io中的應用
1. 裝飾者模式的簡介
裝飾者模式(Decorator Pattern)允許向一個現有的對象添加新的功能,同時又不改變其結構。這種類型的設計模式屬于結構型模式,它是作為現有的類的一個包裝。
這種模式建立了一個裝飾類,用來包裝原有的類,并在保持類方法簽名完整性的前提下,提供了額外的功能。
2. 執行個體講解
這裡以吃火鍋為例進行講解:
說明:火鍋是一個抽象類,鍋底和菜品都繼承了它,然後在點了一個具體的鍋底以後,可以添加菜品,由于可以添加多個菜品,這個時候就得考慮怎麼樣設計我們的代碼了,是以有了今天的主角==>裝飾者模式
如上所述,鍋底一個就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());
}
}
運作結果如圖:
簡單總結一下:裝飾者模式是建立在繼承之上的,但是比繼承更加靈活,從以上代碼可以看到,可以非常友善動态的增加我們的菜品
3. 在java.io中的應用
首先看一幅圖:
再結合源碼:
由此我們可以發現,
InputStream
使用了裝飾者模式,其中
InputStream
是被裝飾者,
FilterInputStream
是裝飾者,而
ByteArrayInputStream
等就類似于我們的鍋底,
DataInputStream
等就類似于我們的菜品