1. 程式人生 > >設計模式:裝飾模式特點、與繼承比較分析總結

設計模式:裝飾模式特點、與繼承比較分析總結

目錄

一、裝飾模式簡介

二、裝飾模式的角色

三、裝飾模式編碼實現

四、裝飾模式與繼承的比較

五、裝飾模式應用場景


一、裝飾模式簡介

裝飾模式(Decorator)又名裝飾者模式模式。

什麼是裝飾模式?裝飾模式有哪些 特點?

1、動態的將責任附加到物件上,若要擴充套件功能,裝飾者提供比繼承更具彈性的替代方案。

2、裝飾模式以對客戶透明的方式動態的給一個物件附加上更多的責任。換言之,客戶端並不會覺得物件在裝飾前和裝飾後有什麼不同。

3、裝飾模式可以在不創造更多子類的情況下、將物件的功能加以擴充套件。

4、裝飾模式把客戶端的呼叫委派到被裝飾類。裝飾模式的關鍵在於這種擴充套件完全是透明的。

5、裝飾模式是在不必改變原類檔案和使用繼承的情況下,動態的擴充套件一個物件的功能。它是通過建立一個包裝物件,也就是裝飾來包裹真實 物件。

6、裝飾物件和真實物件有相同的介面,裝飾物件包含一個真實物件的引用,負責將請求轉發給真實的物件。

7、裝飾物件可以在轉發這些請求前後增加一些附加自定義功能。

 

二、裝飾模式的角色

·抽象構件角色(Component) :給出一個抽象介面,以規範準備接收附加責任的物件。
·具體構件角色(Concrete Component) :定義一個將要接收附加責任的類。
·裝飾角色(Decorator) :持有一個構件(Component)物件的引用,並定義一個與抽象構件介面一致的介面
·具體裝飾角色(Concrete Decorator) :負責給構件物件“貼上”附加的責任。

三、裝飾模式編碼實現

package sjms.pattern.decorator;

/**
 * Description:
 * User: zhurong
 * Date: 2018-10-24  21:51
 */
public interface Component {
    void helloWorld();
}
package sjms.pattern.decorator;

/**
 * Description:
 * User: zhurong
 * Date: 2018-10-24  22:07
 */
public class ConcreateComponent implements Component {
    @Override
    public void helloWorld() {
        System.out.println("ConcreateComponent");
    }
}
package sjms.pattern.decorator;

/**
 * Description:
 * User: zhurong
 * Date: 2018-10-24  21:52
 */
public class Decorator implements Component {
    private Component component;

    public Decorator(Component component) {
        this.component = component;
    }

    @Override
    public void helloWorld() {
        component.helloWorld();
    }
}
package sjms.pattern.decorator;

/**
 * Description:
 * User: zhurong
 * Date: 2018-10-24  21:53
 */
public class ConcreateDecorator1 extends Decorator {

    public ConcreateDecorator1(Component component) {
        super(component);
    }

    @Override
    public void helloWorld() {
        super.helloWorld();
        this.doOtherThing();
    }

    private void doOtherThing() {
        System.out.println("功能1");
    }
}
package sjms.pattern.decorator;

/**
 * Description:
 * User: zhurong
 * Date: 2018-10-24  21:53
 */
public class ConcreateDecorator2 extends Decorator {

    public ConcreateDecorator2(Component component) {
        super(component);
    }

    @Override
    public void helloWorld() {
        super.helloWorld();
        this.doOtherThing();
    }

    private void doOtherThing() {
        System.out.println("功能2");
    }
}
package sjms.pattern.decorator;

/**
 * Description:
 * User: zhurong
 * Date: 2018-10-24  21:53
 */
public class ConcreateDecorator3 extends Decorator {

    public ConcreateDecorator3(Component component) {
        super(component);
    }

    @Override
    public void helloWorld() {
        super.helloWorld();
        this.doOtherThing();
    }

    private void doOtherThing() {
        System.out.println("功能3");
    }
}
package sjms.pattern.decorator;

/**
 * Description:
 * User: zhurong
 * Date: 2018-10-24  22:00
 */
public class Client {

    public static void main(String[] args) {
        Component component = new ConcreateDecorator3(
                new ConcreateDecorator2(
                        new ConcreateDecorator1(new ConcreateComponent())));

        component.helloWorld();
    }


}

四、裝飾模式與繼承的比較

三、裝飾模式和繼承有啥不同 
1、裝飾模式:
   (1)、用來擴充套件特定物件的功能。
   (2)、不需要子類。
   (3)、動態,執行時分配職責。靈活。
   (4)、一個給定的物件,同時可能有不同的裝飾物件。
2、繼承
    (1)、用來擴充套件一類物件的功能
    (2)、不需要子類
    (3)、靜態
    (4)、編譯的時候分配職責,缺乏靈活。
    (5)、導致很多子類產生,混雜。

 

五、裝飾模式應用場景

1、Java的1O庫提供了一個稱做連結的機制,可以將一個流與另一個流首尾相接,形成一個流管道的連結。
這種機制實際上是一種被稱為Decorator(裝飾)設計模式的應用。
2、通過流的連結,可以動態的增加流的功能,而這種功能的增加是通過組合一些流的基本功能而動態獲取的。
我們要獲取一個1/O物件,往往需要產生多個/O物件,這也是Java 1/0庫不太容易掌握的原因,但在1O庫中
Decorator模式的運用,給我們提供了實現上的靈活性。

I/O 系統用了哪些設計模式?為什麼要這麼做?

裝飾模式保持io體系功能健全的同時避免了更多子類產生。