一、什么是装饰模式
通过关联机制给类增加行为,其行为的扩展由修饰对象来决定;
二、补充说明
与继承相似,不同点在于继承是在编译期间扩展父类,而装饰器模式在运行期间动态扩展原有对象;
或者说,继承是对类进行扩展,装饰模式是对对象进行扩展;
三、角色
抽象构件
具体构件
抽象装饰类
具体装饰类
说明:具体构件、抽象装饰类、具体装饰类的共同父类是抽象构件,具体装饰类继承抽象装饰类并在运行期间装饰具体构件;
四、例子
例子说明:
画家接口Painter,为抽象构件,有两个方法,获取画家描述信息及绘画;
PaintBeginner实现Painter接口,为具体构件;
PainterDecorator实现Painter接口,为抽象装饰类,其内部关联一个Painter对象,通过构造函数获取;
HillPainterDecorator、RiverPainterDecorator、TreePainterDecorator为具体装饰类,表明被装饰的画家能够绘画Hill、River、Tree;
类图:
代码实现:
Painter.java
packagecom.pichen.dp.decorator;public interfacePainter {public abstractString getDescription();public abstractString painting();
}
View Code
PaintBeginner.java
packagecom.pichen.dp.decorator;public class PaintBeginner implementsPainter{
@OverridepublicString getDescription() {return "";
}
@OverridepublicString painting() {/*do nothing*/
return "";
}
}
View Code
PainterDecorator.java
packagecom.pichen.dp.decorator;public abstract class PainterDecorator implementsPainter{privatePainter decoratedPainter;publicPainterDecorator(Painter decoratedPainter) {this.decoratedPainter =decoratedPainter;
}publicPainter getPainter(){return this.decoratedPainter;
}
}
View Code
HillPainterDecorator.java
packagecom.pichen.dp.decorator;public class HillPainterDecorator extendsPainterDecorator{publicHillPainterDecorator(Painter paper) {super(paper);
}
@OverridepublicString getDescription() {return this.getPainter().getDescription() + "can paint hill, ";
}
@OverridepublicString painting() {/*painting the hill*/
return this.getPainter().painting() +paintingHill();
}publicString paintingHill(){return "Hill, ";
}
}
View Code
RiverPainterDecorator.java
packagecom.pichen.dp.decorator;public class RiverPainterDecorator extendsPainterDecorator{publicRiverPainterDecorator(Painter paper) {super(paper);
}
@OverridepublicString getDescription() {return this.getPainter().getDescription() + "can paint river, ";
}
@OverridepublicString painting() {/*painting the river*/
return this.getPainter().painting() +paintingRiver();
}publicString paintingRiver(){return "River, ";
}
}
View Code
TreePainterDecorator.java
packagecom.pichen.dp.decorator;public class TreePainterDecorator extendsPainterDecorator{publicTreePainterDecorator(Painter paper) {super(paper);
}
@OverridepublicString getDescription() {return this.getPainter().getDescription() + "can paint tree, ";
}
@OverridepublicString painting() {/*painting the tree*/
return this.getPainter().painting() +paintingTree();
}publicString paintingTree(){return "Tree, ";
}
}
View Code
Main.java
packagecom.pichen.dp.decorator;public classMain {public static voidmain(String[] args) {
Painter p0= newPaintBeginner();
System.out.println("Painter description:" +p0.getDescription());
System.out.println("Painting:" + p0.painting() + "\n");
Painter p1= new HillPainterDecorator(new RiverPainterDecorator(new TreePainterDecorator(newPaintBeginner())));
System.out.println("Painter description:" +p1.getDescription());
System.out.println("Painting:" + p1.painting() + "\n");
Painter p2= new RiverPainterDecorator(new HillPainterDecorator(newPaintBeginner()));
System.out.println("Painter description:" +p2.getDescription());
System.out.println("Painting:" + p2.painting() + "\n");
}
}
执行结果如下,PaintBeginner类的对象未装饰前,无行为;在被装饰器装饰后,其行为可动态扩展:
五、JAVA IO流与装饰模式
这里简单的以Reader、BufferedReader、FileReader举个例子,如下代码:
BufferedReader br = new BufferedReader(new FileReader(new File("test.txt")));
br.readLine();
说明:
其中BufferedReader与BufferedReader有一个共同抽象父类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();
links:
原文:http://www.cnblogs.com/chenpi/p/5173818.html