java设计模式之装饰器模式

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

你可能感兴趣的:(设计模式,java设计模式,java)