装饰器模式(decorator Pattern)一般用来扩展原有类的功能。“装饰模式把复杂的功能简单化,然后在运行期间动态组合”,这句话是引用。。
其实最生动的例子,莫过于JDK源码中的IO流源码了,有兴趣的童鞋可以自己看看。
构建场景,最开始给我们盖一个房子,然后我们装修的时候要给房子安装门和窗户。
(1)首先我们有一个接口:
public interface Building {
void build();
}
(2)然后我们盖了一个房子
public class House implements Building{
@Override
public void build() {
System.out.println("建造了一栋房子");
}
}
(3)这时候我们想给房子装修,于是我们使用装饰器模式,首先定义一个装饰器抽象类
/**
* 房子装饰器抽象类
*/
public abstract class HouseDecorator implements Building {
//注意,这里可是持有一个对象的
protected Building buildingDecorator;
public HouseDecorator(Building buildingDecorator) {
this.buildingDecorator = buildingDecorator;
}
@Override
public void build() {
buildingDecorator.build();
}
}
(4)接下来我们可以愉快的装修房子了,装个门先:
public class Door extends HouseDecorator {
public Door(Building buildingDecorator) {
super(buildingDecorator);
}
@Override
public void build() {
buildingDecorator.build();
System.out.println("安装了一个门");
}
}
再装个窗户:
/**
* 窗户
*/
public class Window extends HouseDecorator{
public Window(Building buildingDecorator) {
super(buildingDecorator);
}
@Override
public void build() {
buildingDecorator.build();
System.out.println("安装了一个窗户");
}
}
(5)执行代码:
public static void main(String[] args) {
Building houseBuilding = new House();
houseBuilding.build();
System.out.println();
Building doorDecorator = new Door(houseBuilding);
doorDecorator.build();
System.out.println();
Building windowDecorator = new Window(doorDecorator);
windowDecorator.build();
}
(6)输出结果:
建造了一栋房子
建造了一栋房子
安装了一个门
建造了一栋房子
安装了一个门
安装了一个窗户
到此,装饰器模式就实现了,有的童鞋说,你这代码写的好多啊,我怎么觉得Building可以删掉,直接让House也继承抽象类。确实,上述代码可以改成这样:
/**
* 建筑抽象类
*/
public abstract class Building {
protected Building buildingDecorator;
public Building(Building buildingDecorator) {
this.buildingDecorator = buildingDecorator;
}
public void build() {
}
}
/**
* 房子
*/
public class House extends Building{
public House(Building buildingDecorator) {
super(buildingDecorator);
}
@Override
public void build() {
System.out.println("建造了一栋房子");
}
}
/**
* 门
*/
public class Door extends Building {
public Door(Building buildingDecorator) {
super(buildingDecorator);
}
@Override
public void build() {
buildingDecorator.build();
System.out.println("安装了一个门");
}
}
/**
* 窗户
*/
public class Window extends Building{
public Window(Building buildingDecorator) {
super(buildingDecorator);
}
@Override
public void build() {
buildingDecorator.build();
System.out.println("安装了一个窗户");
}
}
总结:(1)可以明显看出从上到下输出逐渐增多,意味着同样是build()函数,一个Building对象的功能越来越强大。每装饰一层,相当于就增加了新的功能
(2)上下两种装饰器的写法都没有问题,都是装饰器的思想。
(3)有人拿装饰器和代理做类比,确实装饰器和代理都很大的相似之处,但是根本区别在于它们的目的是完全不一样的。代理是为了控制访问,而装饰器是为了完善功能,根本没有可比性。。。。