Java設計模式中裝飾者模式應用詳解

編程是一門藝術,大批量的改動顯然是非常醜陋的做法,用心的琢磨寫的代碼讓它變的更美觀。

在現實生活中,常常需要對現有產品增加新的功能或美化其外觀,如房子裝修、相片加相框等,都是裝飾器模式。

在軟件開發過程中,有時想用一些現存的組件。這些組件可能隻是完成瞭一些核心功能。但在不改變其結構的情況下,可以動態地擴展其功能。所有這些都可以釆用裝飾器模式來實現。

1.裝飾器模式(Decorator)的定義

裝飾器模式:是指在不改變現有對象結構的情況下,動態地給該對象增加一些職責(即增加其額外功能)的模式,它屬於對象結構型模式。

2.裝飾者設計模式的優點與不足

裝飾者設計模式優點:

  • 裝飾器是繼承的有力補充,比繼承靈活,在不改變原有對象的情況下,動態的給一個對象擴展功能,即插即用
  • 通過使用不用裝飾類及這些裝飾類的排列組合,可以實現不同效果
  • 裝飾器模式完全遵守開閉原則

其主要缺點是:裝飾器模式會增加許多子類,過度使用會增加程序得復雜性。

3.裝飾器模式的實現思路

通常情況下,擴展一個類的功能會使用繼承方式來實現。但繼承具有靜態特征,耦合度高,並且隨著擴展功能的增多,子類會很膨脹。如果使用組合關系來創建一個包裝對象(即裝飾對象)來包裹真實對象,並在保持真實對象的類結構不變的前提下,為其提供額外的功能,這就是裝飾器模式的目標。

4.裝飾者代碼示例

實例場景介紹:采摘水果,然後進行包裝,這是主流程,然後需要對包裝進行功能增強,比如:增加防偽標識、長途加固、標記加急。

/**
 * 包裝接口
 */
public interface Bag {
    void pack();
}
/**
 * 這個是裝飾者的基類
 */
public abstract class BagDecorator implements Bag {
    /**
     * 維持一個對 抽象構件對象的引用
     * 這個是想要增強的功能對象 將想要增強的功能對象傳進來,然後才能進行功能增強
     */
    private Bag bag;
    /**
     * 註入一個抽象構件類型的對象
     * 將之前的對象傳遞進來,進行功能增強
     * @param bag
     */
    public BagDecorator(Bag bag) {
        this.bag = bag;
    }
    @Override
    public void pack() {
        bag.pack();
    }
}
/**
 * 增加防偽標識
 */
public class CheckedBagDecorator extends BagDecorator{
    public CheckedBagDecorator(Bag bag) {
        super(bag);
    }
    @Override
    public void pack() {
        super.pack();  
        checked();   
    }
    public void checked() {
        System.out.println("打印上防偽標識");
    }
}
/**
 * 加固增強
 */
public class ReinforceBagDecorator extends BagDecorator {
    public ReinforceBagDecorator(Bag bag) {
        super(bag);
    }
    public void pack() {
        super.pack();   
        reinforce();
    }
    public void reinforce() {
        System.out.println("加固瞭包裝");
    }
}
/**
 * 加急功能增強
 */
public class SpeedDecorator extends BagDecorator {
    public SpeedDecorator(Bag bag) {
        super(bag);
    }
    @Override
    public void pack() {
        super.pack();
        speedy();
    }
    public void speedy() {
        System.out.println("打上加急標識");
    }
}
   public static void main(String[] args){
        AbstractFactory factory = new AppleFactory();
        /*得到水果*/
        Fruit fruit = factory.getFruit();
        fruit.draw();
        /*得到包裝*/
        Bag bag = factory.getBag();
        /*下面是對包裝進行裝飾的過程(也就是功能增強的過程)*/
        /*現需要增加防偽標識*/
        bag = new CheckedBagDecorator(bag);
        /*加固功能*/
        bag = new ReinforceBagDecorator(bag);
        /*加急功能*/
        bag = new SpeedDecorator(bag);
        bag.pack();
    }

BagDecorator:功能增強基類,實現瞭待增強功能的行為接口,並持有一個包裝接口成員變量,這個變量通過構造方法註入進來,這個成員變量就是上一個增強之後的結果,一定要在上一個增強的結果之上進行功能增強,否則,就將之前的功能丟失瞭,所以這個成員變量很關鍵。

還有就是每次進行包裝pack的時候,一定要先調用super方法,先之前之前的包裝,然後再進行增強。

5.裝飾器模式的應用場景

裝飾器模式通常在以下幾種情況使用:

  • 當需要給一個現有類添加附加職責,而又不能采用生成子類的方法進行擴充時。例如,該類被隱藏或者該類是終極類或者采用繼承方式會產生大量的子類。
  • 當需要通過對現有的一組基本功能進行排列組合而產生非常多的功能時,采用繼承關系很難實現,而采用裝飾器模式卻很好實現。
  • 當對象的功能要求可以動態地添加,也可以再動態地撤銷時。

裝飾者設計模式,在Java中非常經典的例子是:

InputStream 的子類 FilterInputStream,OutputStream 的子類 FilterOutputStream,Reader 的子類 BufferedReader 以及 FilterReader,還有 Writer 的子類 BufferedWriter、FilterWriter 以及 PrintWriter 等,它們都是抽象裝飾類。

到此這篇關於Java設計模式中裝飾者模式應用詳解的文章就介紹到這瞭,更多相關Java裝飾者模式內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: