Java裝飾者模式

裝飾者模式目標
把許多要實現的功能,加載在子類上,類的繼承,顯得很臃腫,裝飾着模式是在不改變原有類文件和使用繼承的狀況下,經過建立一個包裝對象動態地擴展一個對象的功能,相比生成子類更爲靈活
裝飾模式的結構
在裝飾模式中的角色有:
  ●  抽象構件(Component)角色:給出一個抽象接口,以規範準備接收附加責任的對象。
  ●  具體構件(ConcreteComponent)角色:定義一個將要接收附加責任的類。
  ●  裝飾(Decorator)角色:持有一個構件(Component)對象的實例,並定義一個與抽象構件接口一致的接口。
  ●  具體裝飾(ConcreteDecorator)角色:負責給構件對象「貼上」附加的責任
源代碼
抽象構件角色
[Java] 純文本查看 複製代碼
?
1
2
3
4
5
public interface Component {設計模式

public void sampleOperation();

}
具體構件角色
[Java] 純文本查看 複製代碼
?
1
2
3
4
5
6
public class ConcreteComponent implements Component {ide

@Override
public void sampleOperation() {
    // 寫相關的業務代碼
}

}
裝飾角色
[Java] 純文本查看 複製代碼
?
01
02
03
04
05
06
07
08
09
10
11
12
13
public class Decorator implements Component{性能

private Component component;
 
public Decorator(Component component){
    this.component = component;
}
@Override
public void sampleOperation() {
    // 委派給構件
    component.sampleOperation();
}

}
具體裝飾角色
[Java] 純文本查看 複製代碼
?
01
02
03
04
05
06
07
08
09
10
11
public class ConcreteDecoratorA extends Decorator {this

public ConcreteDecoratorA(Component component) {
    super(component);
}
 
@Override
public void sampleOperation() {

     super.sampleOperation();設計

// 寫相關的業務代碼
}

}
[Java] 純文本查看 複製代碼
?
01
02
03
04
05
06
07
08
09
10
11
public class ConcreteDecoratorB extends Decorator {code

public ConcreteDecoratorB(Component component) {
    super(component);
}
 
@Override
public void sampleOperation() {

     super.sampleOperation();component

// 寫相關的業務代碼
}

}
齊天大聖的例子
孫悟空有七十二般變化,他的每一種變化都給他帶來一種附加的本領。他變成魚兒時,就能夠到水裏游泳;他變成鳥兒時,就能夠在天上飛行。
  本例中,Component的角色便由鼎鼎大名的齊天大聖扮演;ConcreteComponent的角色屬於大聖的本尊,就是猢猻本人;Decorator的角色由大聖的七十二變扮演。而ConcreteDecorator的角色即是魚兒、鳥兒等七十二般變化對象

源代碼
抽象構件角色「齊天大聖」接口定義了一個move()方法,這是全部的具體構件類和裝飾類必須實現的。
[Java] 純文本查看 複製代碼
?
1
2
3
4
5
//大聖的尊號
public interface TheGreatestSage {繼承

public void move();

}
具體構件角色「大聖本尊」猢猻類
[Java] 純文本查看 複製代碼
?
1
2
3
4
5
6
7
public class Monkey implements TheGreatestSage {接口

@Override
public void move() {
    //代碼
    System.out.println("Monkey Move");
}

}
抽象裝飾角色「七十二變」
[Java] 純文本查看 複製代碼
?
01
02
03
04
05
06
07
08
09
10
11
12
public class Change implements TheGreatestSage {

private TheGreatestSage sage;
 
public Change(TheGreatestSage sage){
    this.sage = sage;
}
@Override
public void move() {
    // 代碼
    sage.move();
}

}
具體裝飾角色「魚兒」
[Java] 純文本查看 複製代碼
?
01
02
03
04
05
06
07
08
09
10
11
public class Fish extends Change {

public Fish(TheGreatestSage sage) {
    super(sage);
}
@Override
public void move() {
    // 代碼
    System.out.println("Fish Move");
}

}
具體裝飾角色「鳥兒」
[Java] 純文本查看 複製代碼
?
01
02
03
04
05
06
07
08
09
10
11
public class Bird extends Change {

public Bird(TheGreatestSage sage) {
    super(sage);
}
@Override
public void move() {
    // 代碼
    System.out.println("Bird Move");
}

}
客戶端類
[Java] 純文本查看 複製代碼
?
01
02
03
04
05
06
07
08
09
10
11
public class Client {

public static void main(String[] args) {
    TheGreatestSage sage = new Monkey();
    // 第一種寫法
    TheGreatestSage bird = new Bird(sage);
    TheGreatestSage fish = new Fish(bird);
    // 第二種寫法
    //TheGreatestSage fish = new Fish(new Bird(sage));
    fish.move(); 
}

}
「大聖本尊」是ConcreteComponent類,而「鳥兒」、「魚兒」是裝飾類。要裝飾的是「大聖本尊」,也即「猢猻」實例。
  上面的例子中,系統把大聖從一隻猢猻裝飾成了一隻鳥兒(把鳥兒的功能加到了猢猻身上),而後又把鳥兒裝飾成了一條魚兒(把魚兒的功能加到了猢猻+鳥兒身上,獲得了猢猻+鳥兒+魚兒)。

如上圖所示,大聖的變化首先將鳥兒的功能附加到了猢猻身上,而後又將魚兒的功能附加到猢猻+鳥兒身上。
設計模式在JAVA I/O庫中的應用
裝飾模式在Java語言中的最著名的應用莫過於Java I/O標準庫的設計了。
  因爲Java I/O庫須要不少性能的各類組合,若是這些性能都是用繼承的方法實現的,那麼每一種組合都須要一個類,這樣就會形成大量性能重複的類出現。而若是採用裝飾模式,那麼類的數目就會大大減小,性能的重複也能夠減至最少。所以裝飾模式是Java I/O庫的基本模式。
  Java I/O庫的對象結構圖以下,因爲Java I/O的對象衆多,所以只畫出InputStream的部分。

根據上圖能夠看出:  ●  抽象構件(Component)角色:由InputStream扮演。這是一個抽象類,爲各類子類型提供統一的接口。  ●  具體構件(ConcreteComponent)角色:由ByteArrayInputStream、FileInputStream、PipedInputStream、StringBufferInputStream等類扮演。它們實現了抽象構件角色所規定的接口。  ●  抽象裝飾(Decorator)角色:由FilterInputStream扮演。它實現了InputStream所規定的接口。  ●  具體裝飾(ConcreteDecorator)角色:由幾個類扮演,分別是BufferedInputStream、DataInputStream以及兩個不經常使用到的類LineNumberInputStream、PushbackInputStream。

相關文章
相關標籤/搜索