经过关联机制给类增长行为,其行为的扩展由修饰对象来决定;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();