轉載-Java設計模式之Decorator

Red88Army發表於2020-04-06
今天學員在學習java的時候提到了Decorator其設計模式,在網找到了這樣一個案例,還不錯,給學員分享一下!
Decorator裝飾器,顧名思義,就是動態地給一個物件新增一些額外的職責,就好比為房子進行裝修一樣。因此,裝飾器模式具有如下的特徵:

它必須具有一個裝飾的物件。
它必須擁有與被裝飾物件相同的介面。
它可以給被裝飾物件新增額外的功能。
用一句話總結就是:保持介面,增強效能。
裝飾器通過包裝一個裝飾物件來擴充套件其功能,而又不改變其介面,這實際上是基於物件的介面卡模式的一種變種。它與物件的介面卡模式的異同點如下。
相同點:都擁有一個目標物件。
不同點:介面卡模式需要實現另外一個介面,而裝飾器模式必須實現該物件的介面。



Sourcable類的原始碼如程式 12-22 所示,其定義了一個介面函式 operation() 。
程式12-22 源介面 Sourcable.java

Java程式碼
1.package pattern.decorator;
2.
3.public interface Sourcable {
4. public void operation();
5.
6.}
package pattern.decorator;

public interface Sourcable {
public void operation();

}

(2 ) Source.java 是 Sourcable.java 的一個實現,其函式 operation() 負責往控制檯輸出一個字串:原始類的方法。其原始碼如程式 12-23 所示。
程式12-23 源類 Source.java
Java程式碼
1.package pattern.decorator;
2.
3.public class Source implements Sourcable {
4.
5. public void operation() {
6. System.out.println("原始類的方法");
7. }
8.
9.}
package pattern.decorator;

public class Source implements Sourcable {

public void operation() {
System.out.println("原始類的方法");
}

}

(3 )裝飾器類 Decorator1.java 採用了典型的物件介面卡模式,它首先擁有一個 Sourcable 物件 source ,該物件通過構造函 數進行初始化。然後它實現了 Sourcable.java 介面,以期保持與 source 同樣的介面,並在重寫的 operation() 函式中呼叫 source 的 operation() 函式,在呼叫前後可以實現自己的輸出,這就是裝飾器所擴充套件的功能。其原始碼如程式 12-24 所示。
程式12-24 裝飾器類 Decorator1.java
Java程式碼
1.package pattern.decorator;
2.
3.public class Decorator1 implements Sourcable {
4.
5. private Sourcable sourcable;
6. public Decorator1(Sourcable sourcable){
7. super();
8. this.sourcable=sourcable;
9. }
10.
11. public void operation() {
12. System.out.println("第一個裝飾器前");
13. sourcable.operation();
14. System.out.println("第一個裝飾器後");
15.
16. }
17.
18.}
package pattern.decorator;

public class Decorator1 implements Sourcable {

private Sourcable sourcable;
public Decorator1(Sourcable sourcable){
super();
this.sourcable=sourcable;
}

public void operation() {
System.out.println("第一個裝飾器前");
sourcable.operation();
System.out.println("第一個裝飾器後");

}

}

裝飾器類Decorator2.java 是另一個裝飾器,不同的是它裝飾的內容不一樣,即輸出了不同的字串。其原始碼如程式 12-25 所示。
程式12-25 裝飾器類 Decorator2.java
Java程式碼
1.package pattern.decorator;
2.
3.public class Decorator2 implements Sourcable {
4.
5. private Sourcable sourcable;
6. public Decorator2(Sourcable sourcable){
7. super();
8. this.sourcable=sourcable;
9. }
10. public void operation() {
11. System.out.println("第二個裝飾器前");
12. sourcable.operation();
13. System.out.println("第二個裝飾器後");
14.
15. }
16.
17.}
package pattern.decorator;

public class Decorator2 implements Sourcable {

private Sourcable sourcable;
public Decorator2(Sourcable sourcable){
super();
this.sourcable=sourcable;
}
public void operation() {
System.out.println("第二個裝飾器前");
sourcable.operation();
System.out.println("第二個裝飾器後");

}

}

裝飾器類Decorator1.java 是第三個裝飾器,不同的是它裝飾的內容不一樣,即輸出了不同的字串。其原始碼如程式 12-26 所示。
程式12-26 裝飾器類 Decorator3.java
Java程式碼
1.package pattern.decorator;
2.
3.public class Decorator3 implements Sourcable {
4.
5. private Sourcable sourcable;
6. public Decorator3(Sourcable sourcable){
7. super();
8. this.sourcable=sourcable;
9. }
10. public void operation() {
11. System.out.println("第三個裝飾器前");
12. sourcable.operation();
13. System.out.println("第三個裝飾器後");
14.
15. }
16.
17.}
package pattern.decorator;

public class Decorator3 implements Sourcable {

private Sourcable sourcable;
public Decorator3(Sourcable sourcable){
super();
this.sourcable=sourcable;
}
public void operation() {
System.out.println("第三個裝飾器前");
sourcable.operation();
System.out.println("第三個裝飾器後");

}

}

這時,我們就可以像使用物件的介面卡模式一樣來使用這些裝飾器,使用不同的裝飾器就可以達到不同的裝飾效果。如程式12-27 所示,首先需要建立一 個源類物件 source ,然後根據將物件使用 Decorator1 來裝飾,並以此使用 Decorator2 、 Decorator3 進行裝飾,裝飾後的物件 同樣具有與 source 同樣的介面。
程式12-27 測試類 DecoratorTest.java
Java程式碼
1.package pattern.decorator;
2.
3.public class DecoratorTest {
4.
5. /**
6. * @param args
7. */
8. public static void main(String[] args) {
9. Sourcable source = new Source();
10.
11. // 裝飾類物件
12. Sourcable obj = new Decorator1(new Decorator2(new Decorator3(source)));
13. obj.operation();
14. }
15.
16.}
package pattern.decorator;

public class DecoratorTest {

/**
* @param args
*/
public static void main(String[] args) {
Sourcable source = new Source();

// 裝飾類物件
Sourcable obj = new Decorator1(new Decorator2(new Decorator3(source)));
obj.operation();
}

}

執行該程式的輸出如下:
第1 個裝飾器裝飾前
第2 個裝飾器裝飾前
第3 個裝飾器裝飾前
原始類的方法
第3 個裝飾器裝飾後
第2 個裝飾器裝飾後
第1 個裝飾器裝飾後
從輸出的結果可以看出,原始類物件source 依次被 Decorator1 、 Decorator2 、 Decorator3 進行了裝飾

相關文章