裝飾者模式 動態的將責任附加到對象上。若要擴展功能,裝飾者模式提供了比繼承更有彈性的替代方案。 說明: 1、裝飾者和被裝飾者對象有相同的超類型; 2、可以用一個或者多個裝飾者包裝一個對象; 3、既然裝飾者和被裝飾者對象有相同的超類型,所以在任何需要原始對象(被裝飾者)的場合,可以用裝飾過的對象代替它 ...
裝飾者模式 動態的將責任附加到對象上。若要擴展功能,裝飾者模式提供了比繼承更有彈性的替代方案。 說明: 1、裝飾者和被裝飾者對象有相同的超類型; 2、可以用一個或者多個裝飾者包裝一個對象; 3、既然裝飾者和被裝飾者對象有相同的超類型,所以在任何需要原始對象(被裝飾者)的場合,可以用裝飾過的對象代替它; 4、裝飾者可以在委托被裝飾者的行為之前 與 / 或 之後,加上自己的行為,以達到特定的目的; 5、對象可以在任何時候被裝飾,所以可以在運行時動態地、不限量地用你喜歡的裝飾者來裝飾對象。
在裝飾模式中的角色有:
抽象構件(Component)角色:給出一個抽象介面,以規範準備接收附加責任的對象。
具體構件(ConcreteComponent)角色:定義一個將要接收附加責任的類。
裝飾(Decorator)角色:持有一個構件(Component)對象的實例,並定義一個與抽象構件介面一致的介面。
具體裝飾(ConcreteDecorator)角色:負責給構件對象“貼上”附加的責任。
/** * 孫悟空的本尊,並且定義了七十二變的方法。 * 抽象構件(Component)角色 */ public abstract class Monkey { protected String type = "本尊"; protected abstract void change(); public String getType() { return type; } } |
/** * 齊天大聖 * 具體構件(ConcreteComponent)角色 * */ public class MonkeyKing extends Monkey{ public MonkeyKing() { type = "齊天大聖 -> "; } @Override protected void change() { System.out.println("七十二變......"); } } |
/** * 變化的孫悟空 * 裝飾(Decorator)角色 * */ public abstract class ChangeMonkey extends Monkey{ @Override protected abstract void change(); } |
/** * 變化後為魚 * 具體裝飾(ConcreteDecorator)角色 * */ public class Fish extends ChangeMonkey{ private Monkey monkey; public Fish(Monkey monkey) { this.monkey = monkey; } @Override protected void change() { System.out.println("變化為 Fish ......"); } public String getType() { return monkey.getType() + "fish -> "; } } |
/** * 變化後為鳥 * 具體裝飾(ConcreteDecorator)角色 * */ public class Bird extends ChangeMonkey{ private Monkey monkey; public Bird(Monkey monkey) { this.monkey = monkey; } @Override protected void change() { System.out.println("Bird......"); } public String getType() { return monkey.getType() + "bird -> "; } } |
public class Client { public static void main(String[] args) { Monkey monkey = new MonkeyKing(); Monkey fish = new Fish(monkey); Monkey fish2 = new Fish(fish); Monkey bird = new Bird(fish2); System.out.println(bird.getType()); bird.change(); } } |
根據上圖可以看出:
● 抽象構件(Component)角色:由InputStream扮演。這是一個抽象類,為各種子類型提供統一的介面。
● 具體構件(ConcreteComponent)角色:由ByteArrayInputStream、FileInputStream、PipedInputStream、StringBufferInputStream等類扮演。它們實現了抽象構件角色所規定的介面。
● 抽象裝飾(Decorator)角色:由FilterInputStream扮演。它實現了InputStream所規定的介面。
● 具體裝飾(ConcreteDecorator)角色:由幾個類扮演,分別是BufferedInputStream、DataInputStream以及兩個不常用到的類LineNumberInputStream、PushbackInputStream。
裝飾模式的優點(1)裝飾模式與繼承關係的目的都是要擴展對象的功能,但是裝飾模式可以提供比繼承更多的靈活性。裝飾模式允許系統動態決定“貼上”一個需要的“裝飾”,或者除掉一個不需要的“裝飾”。繼承關係則不同,繼承關係是靜態的,它在系統運行前就決定了。
(2)通過使用不同的具體裝飾類以及這些裝飾類的排列組合,設計師可以創造出很多不同行為的組合。
裝飾模式的缺點由於使用裝飾模式,可以比使用繼承關係需要較少數目的類。使用較少的類,當然使設計比較易於進行。但是,在另一方面,使用裝飾模式會產生比使用繼承關係更多的對象。更多的對象會使得查錯變得困難,特別是這些對象看上去都很相像。
參考資料:《Head First 設計模式》 http://www.cnblogs.com/java-my-life/archive/2012/04/20/2455726.html