1. 程式人生 > >設計模式的藝術 結構性模式之裝飾模式

設計模式的藝術 結構性模式之裝飾模式

不懂使用為學過,說出用途,繪製結構為了解,不會靈活使用基本等於沒學。

前言

我們大多數時候買的新房都是毛坯房,想要入住的話無疑需要進行一次裝修自己才能高高興興的入住,雖然裝修了,但是並沒有改變房子的本質,但這樣會讓你更樂於到房子裡面去入住,在軟體設計中,也有這麼一種技術可以對已有的物件的功能進行擴充套件,以此來獲得更加符合使用者需求的物件,使得物件具有更加強大的功能,這是一種被稱之為裝飾模式的設計模式

什麼是裝飾模式 Decorator Pattern

動態的給一個物件增加一些額外的職責,就增加物件功能來說,裝飾模式比生成子類的實現更加靈活,裝飾模式是一種物件結構型模式

裝飾模式的優點

(1)、對於擴充套件一個物件的功能,裝飾模式對比繼承而言更加具有靈活性,不會導致類的個數急劇的增加。

(2)、可以通過一種動態的方式來擴充套件一個物件的功能,通過配置檔案可以在執行時選擇不同的具體裝飾類,從而實現不同的行為。

(3)、可以對一個物件進行多次的裝飾,通過使用不同的具體裝飾類以及這些裝飾類的排列組合,可以創造出很多不同行為的組合,得到功能更加強大的物件

(4)、具體構件類與具體裝飾類可以獨立變化,使用者可以根據需要增加具體的構件類或者具體的裝飾類,原有類庫程式碼無須改變,符合開閉原則和里氏替換原則

裝飾模式的缺點

(1)、使用裝飾模式進行系統設計時將產生很多小物件,這些物件之間的區別在於它們之間相互連線的方式有所不同,而不是它們的類或者屬性值的不同,大量的小物件的產生勢必會影響到程式的效能,畢竟佔據了一部分的系統的資源

(2)、裝飾模式提供了一種比繼承更為靈動的解決方案,但同時也意味著比繼承更加容易出錯,排查錯誤比較困難,對於多次裝飾的物件,除錯時尋找錯誤可能需要逐級排查,較為的繁瑣

裝飾模式適用的場景

(1)、在不影響其他物件的前提下,動態,透明的給單個的物件新增職責

(2)、當不能採用繼承的方式對系統進行擴充套件或者採用繼承不利於系統擴充套件和維護時可以採用裝飾模式,不能採用繼承的情況主要有兩類:第一類是系統中存在大量的獨立的擴充套件,為支援每一種擴充套件或者擴充套件之間的組合都將產生大量的子類,使得子類數目呈爆炸性增長。而第二類是那麼已經被定義為不可繼承的類(final類)

裝飾模式的具體實現

專案結構(表現形式為為構建類新增新的功能)

抽象構件類與具體構件類

//抽象介面構件類:抽象構件類,為了突出與模式有關的核心程式碼,對原有控制元件程式碼進行了大量的簡化
public abstract class Component {
    public abstract void display();
}
package com.company.component;

import com.company.component.Component;

//列表框類:具體構件類
public class ListBox extends Component {
    @Override
    public void display() {
        System.out.println("顯示列表框");
    }
}
package com.company.component;

import com.company.component.Component;

//窗體類:具體構件類
public class TextBox extends Component {

    @Override
    public void display() {
        System.out.println("顯示窗體!");
    }
}

抽象裝飾類

package com.company;

import com.company.component.Component;

//構件裝飾類:抽象裝飾類
public class ComponentDecorator extends Component {
    private Component component;  //維持對物件構件型別物件的引用,根據里氏替換原則
    //注入抽象構件型別的物件
    public ComponentDecorator(Component component) {
        this.component = component;
    }

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

具體裝飾類

package com.company.decorator;

import com.company.ComponentDecorator;
import com.company.component.Component;

public class BlockBorderDecorator extends ComponentDecorator {
    public BlockBorderDecorator(Component component) {
        super(component);
    }
    public void display(){
        this.setBlockBorder();
        super.display();
    }
    public void setBlockBorder(){
        System.out.println("為構件增加黑色邊框");
    }
}
package com.company.decorator;

import com.company.ComponentDecorator;
import com.company.component.Component;

//滾動條裝飾類:具體裝飾類
public class ScrollDecorator extends ComponentDecorator {
    public ScrollDecorator(Component component) {
        super(component);
    }
    public void display(){
        this.setScrollBar();
        super.display();
    }
    public void setScrollBar(){
        System.out.println("為構件增加滾動條");
    }
}

測試類

public static void main(String[] args) {
    Component component,component1,component2;  //使用抽象構件定義
    component=new ListBox();  //定義具體構件
    component1=new ScrollDecorator(component);  //定義裝飾後的構件
    component1.display();
    component2=new BlockBorderDecorator(component1);
    component2.display();
}

轉載請註明出處,掌聲送給社會人