設計模式詳解|裝飾器模式

目錄

裝飾器模式

裝飾模式概述

裝飾模式結構與實現

具體案例


裝飾器模式

裝飾模式可以在不改變一個對象本身功能的基礎上給對象增加額外的新行爲,在現實生活中,這種情況也到處存在,例如一張照片,我們可以不改變照片本身,給它增加一個相框,使得它具有防潮的功能,而且用戶可以根據需要給它增加不同類型的相框,甚至可以在一個小相框的外面再套一個大相框。

裝飾模式概述

裝飾模式是一種用於替代繼承的技術,它通過一種無須定義子類的方式來給對象動態增加職責,使用對象之間的關聯關係取代類之間的繼承關係。在裝飾模式中引入了裝飾類,在裝飾類中既可以調用待裝飾的原有類的方法,還可以增加新的方法,以擴充原有類的功能。

裝飾模式定義如下:

裝飾模式(Decorator Pattern):動態地給一個對象增加一些額外的職責,就增加對象功能來說,裝飾模式比生成子類實現更爲靈活。裝飾模式是一種對象結構型模式。

裝飾模式結構與實現


模式結構
在裝飾模式中,爲了讓系統具有更好的靈活性和可擴展性,我們通常會定義一個抽象裝飾類,而將具體的裝飾類作爲它的子類,裝飾模式結構如下圖所示:


 

在裝飾模式結構圖中包含如下幾個角色:

  • Component(抽象構件):它是具體構件和抽象裝飾類的共同父類,聲明瞭在具體構件中實現的業務方法,它的引入可以使客戶端以一致的方式處理未被裝飾的對象以及裝飾之後的對象,實現客戶端的透明操作。
  • ConcreteComponent(具體構件):它是抽象構件類的子類,用於定義具體的構件對象,實現了在抽象構件中聲明的方法,裝飾器可以給它增加額外的職責(方法)。
  • Decorator(抽象裝飾類):它也是抽象構件類的子類,用於給具體構件增加職責,但是具體職責在其子類中實現。它維護一個指向抽象構件對象的引用,通過該引用可以調用裝飾之前構件對象的方法,並通過其子類擴展該方法,以達到裝飾的目的。
  • ConcreteDecorator(具體裝飾類):它是抽象裝飾類的子類,負責向構件添加新的職責。每一個具體裝飾類都定義了一些新的行爲,它可以調用在抽象裝飾類中定義的方法,並可以增加新的方法用以擴充對象的行爲。


由於具體構件類和裝飾類都實現了相同的抽象構件接口,因此裝飾模式以對客戶透明的方式動態地給一個對象附加上更多的責任,換言之,客戶端並不會覺得對象在裝飾前和裝飾後有什麼不同。

裝飾模式可以在不需要創造更多子類的情況下,將對象的功能加以擴展。

具體案例

抽象構件

public interface Component {
    void show();
}

具體構件

public class Person implements Component{
    String name;

    public String getName() {
        return name;
    }

    public Person(String name) {
        this.name = name;
    }

    @Override
    public void show() {
        System.out.println(this.getName()+":");
    }
}

裝飾器

public class Decorator implements Component{
    Component component;

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

    @Override
    public void show() {
        component.show();
    }
}

具體裝飾器

褲子:

public class Kuzi extends Decorator {
    public Kuzi(Component component) {
        super(component);
    }

    @Override
    public void show() {
        super.show();
        System.out.println("褲子");
    }
}

T-shirt

public class Tshirt extends Decorator {

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

    @Override
    public void show() {
        this.component.show();
        System.out.println("T-shirt");
    }
}

客戶端調用

public class Client {
    public static void main(String[] args) {
        Component p=new Person("張三");
        Component d=new Kuzi(p);
        d.show();
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章