擴充套件系統功能——裝飾模式(三)
12.3 完整解決方案
為了讓系統具有更好的靈活性和可擴充套件性,克服繼承複用所帶來的問題,Sunny公司開發人員使用裝飾模式來重構圖形介面構件庫的設計,其中部分類的基本結構如圖12-4所示:
圖12-4 圖形介面構件庫結構圖
在圖12-4中,Component充當抽象構件類,其子類Window、TextBox、ListBox充當具體構件類,Component類的另一個子類ComponentDecorator充當抽象裝飾類,ComponentDecorator的子類ScrollBarDecorator和BlackBorderDecorator充當具體裝飾類。完整程式碼如下所示:
//抽象介面構件類:抽象構件類,為了突出與模式相關的核心程式碼,對原有控制元件程式碼進行了大量的簡化 abstract class Component { public abstract void display(); }
//窗體類:具體構件類 class Window extends Component { public void display() { System.out.println("顯示窗體!"); } }
//文字框類:具體構件類 class TextBox extends Component { public void display() { System.out.println("顯示文字框!"); } }
//列表框類:具體構件類 class ListBox extends Component { public void display() { System.out.println("顯示列表框!"); } }
//構件裝飾類:抽象裝飾類 class ComponentDecorator extends Component { private Component component; //維持對抽象構件型別物件的引用
public ComponentDecorator(Component component) //注入抽象構件型別的物件 { this.component = component; }
public void display() { component.display(); } }
//滾動條裝飾類:具體裝飾類 class ScrollBarDecorator extends ComponentDecorator { public ScrollBarDecorator(Component component) { super(component); }
public void display() { this.setScrollBar(); super.display(); }
public void setScrollBar() { System.out.println("為構件增加滾動條!"); } }
//黑色邊框裝飾類:具體裝飾類 class BlackBorderDecorator extends ComponentDecorator { public BlackBorderDecorator(Component component) { super(component); }
public void display() { this.setBlackBorder(); super.display(); }
public void setBlackBorder() { System.out.println("為構件增加黑色邊框!"); } } |
編寫如下客戶端測試程式碼:
class Client { public static void main(String args[]) { Component component,componentSB; //使用抽象構件定義 component = new Window(); //定義具體構件 componentSB = new ScrollBarDecorator(component); //定義裝飾後的構件 componentSB.display(); } } |
編譯並執行程式,輸出結果如下:
為構件增加滾動條! 顯示窗體! |
在客戶端程式碼中,我們先定義了一個Window型別的具體構件物件component,然後將component作為建構函式的引數注入到具體裝飾類ScrollBarDecorator中,得到一個裝飾之後物件componentSB,再呼叫componentSB的display()方法後將得到一個有滾動條的窗體。如果我們希望得到一個既有滾動條又有黑色邊框的窗體,不需要對原有類庫進行任何修改,只需將客戶端程式碼修改為如下所示:
class Client { public static void main(String args[]) { Component component,componentSB,componentBB; //全部使用抽象構件定義 component = new Window(); componentSB = new ScrollBarDecorator(component); componentBB = new BlackBorderDecorator(componentSB); //將裝飾了一次之後的物件繼續注入到另一個裝飾類中,進行第二次裝飾 componentBB.display(); } } |
編譯並執行程式,輸出結果如下:
為構件增加黑色邊框! 為構件增加滾動條! 顯示窗體! |
我們可以將裝飾了一次之後的componentSB物件注入另一個裝飾類BlackBorderDecorator中實現第二次裝飾,得到一個經過兩次裝飾的物件componentBB,再呼叫componentBB的display()方法即可得到一個既有滾動條又有黑色邊框的窗體。
如果需要在原有系統中增加一個新的具體構件類或者新的具體裝飾類,無須修改現有類庫程式碼,只需將它們分別作為抽象構件類或者抽象裝飾類的子類即可。與圖12-2所示的繼承結構相比,使用裝飾模式之後將大大減少了子類的個數,讓系統擴充套件起來更加方便,而且更容易維護,是取代繼承複用的有效方式之一。
【作者:劉偉 http://blog.csdn.net/lovelion】
相關文章
- 擴充套件系統功能——裝飾模式(四)套件模式
- 擴充套件系統功能——裝飾模式(二)套件模式
- 擴充套件類的三種方式(繼承,裝飾模式,動態代理)套件繼承模式
- Kotlin的裝飾者模式與原始碼擴充套件Kotlin模式原始碼套件
- windows系統磁碟擴容/擴充套件Windows套件
- aix擴充套件檔案系統AI套件
- aix 擴充套件檔案系統AI套件
- 擴充套件你的KUBECTL功能套件
- PHP 一鍵安裝擴充套件的程式-(Windows 系統)PHP套件Windows
- PHP 系統樹圖擴充套件元件PHP套件元件
- OPENWRT擴充套件系統到U盤套件
- 擴充套件系統的磁碟空間套件
- Linux 檔案系統擴充套件Linux套件
- php7安裝redis擴充套件和memcache擴充套件PHPRedis套件
- YAML 擴充套件安裝YAML套件
- Yac 擴充套件安裝套件
- PHP 擴充套件安裝PHP套件
- mongodb擴充套件安裝MongoDB套件
- sphinxphp擴充套件安裝PHP套件
- macOS Sierra系統下PHP5.6安裝memcached擴充套件MacPHP套件
- linux/Windows系統如何安裝PHP-openssl擴充套件LinuxWindowsPHP套件
- [外掛擴充套件]系統主題管理套件
- 擴充套件.Django-許可權系統套件Django
- kotlin 擴充套件(擴充套件函式和擴充套件屬性)Kotlin套件函式
- PostgreSQL 安裝擴充套件包SQL套件
- PHP安裝redis擴充套件PHPRedis套件
- php amqp擴充套件安裝PHPMQ套件
- Centosphp安裝cassandra擴充套件CentOSPHP套件
- (MAC) PHP擴充套件安裝MacPHP套件
- php mysql擴充套件安裝PHPMySql套件
- php 安裝yar擴充套件PHP套件
- php安裝openssl 擴充套件PHP套件
- php gmp擴充套件安裝PHP套件
- 安裝phpxdebug擴充套件PHP套件
- PHP opcache擴充套件安裝PHPopcache套件
- PHP安裝fastDFS擴充套件PHPAST套件
- 讀構建可擴充套件分散式系統:方法與實踐15可擴充套件系統的基本要素套件分散式
- SpringBoot-11 擴充套件功能Spring Boot套件