java设计模式之装饰器模式

来源:互联网 发布:tcl集团的营销网络 编辑:程序博客网 时间:2024/06/07 00:49

装饰器模式(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)有人拿装饰器和代理做类比,确实装饰器和代理都很大的相似之处,但是根本区别在于它们的目的是完全不一样的。代理是为了控制访问,而装饰器是为了完善功能,根本没有可比性。。。。