經過關聯機制給類增長行爲,其行爲的擴展由修飾對象來決定;html
如JAVA IO流裏的如下形式,BufferedReader爲裝飾類,其關聯了一個具體對象(new FileReader(new File("test.txt"))),並對其進行裝飾,裝飾後擁有readLine行爲(方法):java
new BufferedReader(new FileReader(new File("test.txt")));
與繼承類似,不一樣點在於繼承是在編譯期間擴展父類,而裝飾器模式在運行期間動態擴展原有對象;ide
或者說,繼承是對類進行擴展,裝飾模式是對對象進行擴展;函數
抽象構件post
具體構件this
抽象裝飾類spa
具體裝飾類code
說明:具體構件、抽象裝飾類、具體裝飾類的共同父類是抽象構件,具體裝飾類繼承抽象裝飾類並在運行期間裝飾具體構件;htm
例子說明:對象
畫家接口Painter,爲抽象構件,有兩個方法,獲取畫家描述信息及繪畫;
PaintBeginner實現Painter接口,爲具體構件;
PainterDecorator實現Painter接口,爲抽象裝飾類,其內部關聯一個Painter對象,經過構造函數獲取;
HillPainterDecorator、RiverPainterDecorator、TreePainterDecorator爲具體裝飾類,代表被裝飾的畫家可以繪畫Hill、River、Tree;
類圖:
代碼實現:
Painter.java
package com.pichen.dp.decorator; public interface Painter { public abstract String getDescription(); public abstract String painting(); }
PaintBeginner.java
package com.pichen.dp.decorator; public class PaintBeginner implements Painter{ @Override public String getDescription() { return ""; } @Override public String painting() { /* do nothing */ return ""; } }
PainterDecorator.java
package com.pichen.dp.decorator; public abstract class PainterDecorator implements Painter{ private Painter decoratedPainter; public PainterDecorator(Painter decoratedPainter) { this.decoratedPainter = decoratedPainter; } public Painter getPainter(){ return this.decoratedPainter; } }
HillPainterDecorator.java
package com.pichen.dp.decorator; public class HillPainterDecorator extends PainterDecorator{ public HillPainterDecorator(Painter paper) { super(paper); } @Override public String getDescription() { return this.getPainter().getDescription() + "can paint hill, "; } @Override public String painting() { /* painting the hill */ return this.getPainter().painting() + paintingHill(); } public String paintingHill(){ return "Hill, "; } }
RiverPainterDecorator.java
package com.pichen.dp.decorator; public class RiverPainterDecorator extends PainterDecorator{ public RiverPainterDecorator(Painter paper) { super(paper); } @Override public String getDescription() { return this.getPainter().getDescription() + "can paint river, "; } @Override public String painting() { /* painting the river */ return this.getPainter().painting() + paintingRiver(); } public String paintingRiver(){ return "River, "; } }
TreePainterDecorator.java
package com.pichen.dp.decorator; public class TreePainterDecorator extends PainterDecorator{ public TreePainterDecorator(Painter paper) { super(paper); } @Override public String getDescription() { return this.getPainter().getDescription() + "can paint tree, "; } @Override public String painting() { /* painting the tree */ return this.getPainter().painting() + paintingTree(); } public String paintingTree(){ return "Tree, "; } }
Main.java
package com.pichen.dp.decorator; public class Main { public static void main(String[] args) { Painter p0 = new PaintBeginner(); System.out.println("Painter description:" + p0.getDescription()); System.out.println("Painting:" + p0.painting() + "\n"); HillPainterDecorator p2 = new HillPainterDecorator(new PaintBeginner()); System.out.println("Painter description:" + p2.getDescription()); System.out.println("Painting:" + p2.painting()); System.out.println("Painting:" + p2.paintingHill() + "\n"); //新增的行爲 RiverPainterDecorator p3 = new RiverPainterDecorator(new PaintBeginner()); System.out.println("Painter description:" + p3.getDescription()); System.out.println("Painting:" + p3.painting()); System.out.println("Painting:" + p3.paintingRiver() + "\n"); //新增的行爲 HillPainterDecorator p4 = new HillPainterDecorator(new RiverPainterDecorator(new TreePainterDecorator(new PaintBeginner()))); System.out.println("Painter description:" + p4.getDescription()); System.out.println("Painting:" + p4.painting()); System.out.println("Painting:" + p4.paintingHill() + "\n"); //新增的行爲 } }
執行結果以下,PaintBeginner類的對象未裝飾前,無行爲;在被裝飾器裝飾後,行爲能夠改變:
這裏簡單的以Reader、BufferedReader、FileReader舉個例子,以下代碼:
BufferedReader br = new BufferedReader(new FileReader(new File("test.txt"))); br.readLine();
說明:
其中BufferedReader與FileReader有一個共同抽象父類Reader,Reader爲抽象構件;
new FileReader(new File("test.txt"))爲具體構件,運行期間被修飾的對象;
BufferedReader爲具體修飾類,運行期間修飾具體構件;
裝飾後,被修飾的對象新增的行爲是擁有readLine方法;
ps:查看源碼,沒發現BufferedReader對應的抽象裝飾類,我的以爲沒有抽象裝飾類,裝飾模式也是能夠正常工做的,抽象構件(Reader)能夠由具體修飾類關聯;
另外,具體修飾類也能夠做爲基類,被其它類繼承的,繼承後的類一樣也是具體修飾類,如LineNumberReader就是繼承BufferedReader;
因此,上面語句還能夠這樣寫(ps:只是舉例,其實不必用BufferedReader修飾,直接LineNumberReader裝飾下就能夠):
BufferedReader br = new LineNumberReader(new BufferedReader(new FileReader(new File("test.txt")))); br.readLine();