1. 程式人生 > 其它 >Java裝飾者模式

Java裝飾者模式

裝飾者模式目標 把許多要實現的功能,載入在子類上,類的繼承,顯得很臃腫,裝飾著模式是在不改變原有類檔案和使用繼承的情況下,通過建立一個包裝物件動態地擴充套件一個物件的功能,相比生成子類更為靈活

裝飾模式的結構<ignore_js_op>

在裝飾模式中的角色有:   ●  抽象構件(Component)角色:給出一個抽象介面,以規範準備接收附加責任的物件。   ●  具體構件(ConcreteComponent)角色:定義一個將要接收附加責任的類。   ●  裝飾(Decorator)角色:持有一個構件(Component)物件的例項,並定義一個與抽象構件介面一致的介面。   ●  具體裝飾(ConcreteDecorator)角色:負責給構件物件“貼上”附加的責任

原始碼
抽象構件角色

[Java] 純文字檢視 複製程式碼 ?
1 2 3 4 5 public interface Component { public void sampleOperation(); }


具體構件角色

[Java] 純文字檢視 複製程式碼 ?
1 2 3 4 5 6 7 8 public class ConcreteComponent implements Component { @Override public void sampleOperation() {
// 寫相關的業務程式碼 } }


裝飾角色

[Java] 純文字檢視 複製程式碼 ?
01 02 03 04 05 06 07 08 09 10 11 12 13 14 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 12 public class ConcreteDecoratorA extends Decorator { public ConcreteDecoratorA(Component component) { super(component); } @Override public void sampleOperation() {      super.sampleOperation(); // 寫相關的業務程式碼 } }
[Java] 純文字檢視 複製程式碼 ?
01 02 03 04 05 06 07 08 09 10 11 12 public class ConcreteDecoratorB extends Decorator { public ConcreteDecoratorB(Component component) { super(component); } @Override public void sampleOperation() {      super.sampleOperation(); // 寫相關的業務程式碼 } }


齊天大聖的例子

孫悟空有七十二般變化,他的每一種變化都給他帶來一種附加的本領。他變成魚兒時,就可以到水裡游泳;他變成鳥兒時,就可以在天上飛行。   本例中,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 8 9 public class Monkey implements TheGreatestSage { @Override public void move() { //程式碼 System.out.println("Monkey Move"); } }


抽象裝飾角色“七十二變”

[AppleScript] 純文字檢視 複製程式碼 ?
01 02 03 04 05 06 07 08 09 10 11 12 13 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 12 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 12 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 12 13 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。