装饰者设计模式

什么是装饰者设计模式

装饰者设计模式(Decorator Pattern)将某个方法进行增强,可以在被装饰的方法执行前后加上想要的逻辑处理进行增强,又可以不改变现有的结构。这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供额外的功能
使用场景: 1、扩展一个类的功能。 2、动态增加功能,动态撤销。
注意事项:可代替继承

实战

我们利用女孩化妆来演示装饰者设计模式,首先我们定义一个接口,拥有展示的行为:

public interface Showable {
    void show();
}

当然女友会这门功夫了,所以实现了此行为并施展其“美丽的脸庞”了,但此时只是原生态的素颜。

public class Girl implements Showable {

    @Override
    public void show() {
        System.out.print("女孩的素颜");
    }
}

没什么复杂的,直接调用的话会是素面朝天直面惨淡的人生,这样当然达不到美颜效果了,何以一顾倾城。那么接下来要进行化妆了,这里必须依靠一种神秘而又昂贵的东西,化妆品登场了,它同样实现了Showable接口。

public class Decorator implements Showable {

    /**
    * 拥有某个善于展示的对象
    */
    private Showable showable;

    public Decorator(Showable showable){
        this.showable = showable;
    }
    @Override
    public void show() {
        System.out.print("化妆(");
        showable.show();
        System.out.println(")");
    }
}

我们可以发现,在构造化妆品类的时候可以把女孩给注入进来,目的在于调用女孩的show方法,但对于其原本的具体行为装饰器一无所知,并且没有加入任何逻辑限制,它所做的无非是“画龙点睛”,“锦上添花”。接下来我们来运行一下看结果:

public class TestShowable {
    public static void main(String[] args) {
        //将需要被加强的对象传递给装饰类
        new Decorator(new Girl()).show();
        //结果:打扮(女孩的素颜)
    }
}

我们可以看到,只需要新建装饰器的时候把女孩给包装进去就得到了粉饰过的美颜,是不是非常简单?然而此时有女朋友会嫌弃了,“只是打粉底这么简单吗?眼霜呢?口红呢……”。

好吧,为了满足女友的要求,我们得再多一些设计。想想看这些化妆品,不管是什么都有共同的特性,也就是说他们统统都可以装饰原生态的素颜展示方法show,那我们何不把这些特性抽象出来呢?开始行动,修改我们的装饰类

public abstract class Decorator implements Showable {
    /**
    * 拥有某个善于展示的对象
    */
    protected Showable showable;

    public Decorator(Showable showable){
        this.showable = showable;
    }
    
    public void show() {
        //直接调用,不加任何装饰
        showable.show();
    }
}

我们把化妆品类给改成抽象类,重写show方法,但不做任何粉饰了,这里我们留给子类具体的某个化妆品去做装饰吧。化妆首先第一步一定要打底了,这里我们首先加入一个口红类:

public class Lipstick extends Decorator{

    public Lipstick(Showable showable) {
        //调用父类构造赋值给成员属性
        super(showable);
    }

    @Override
    public void show() {
        System.out.print("涂口红(");
        showable.show();
        System.out.print(")");
    }
}

涂完口红,最后再喷点香水吧。同样的,我们再定义一个香水类:

public class Perfume extends Decorator {

    public Perfume(Showable showable) {
        super(showable);
    }

    @Override
    public void show() {
        System.out.println("喷香水(");
        showable.show();
        System.out.println(")");
    }
}

最后,我们把女友、口红、香水层层包裹起来并运行,结果如愿以偿。

public class TestShowable {

    public static void main(String[] args) {
        //将需要被加强的对象传递给装饰类,层层包裹起来,每一层都多了一些功能
       new Perfume(new Lipstick(new Girl())).show();
        //结果: 喷香水(涂口红(女孩的素颜))
    }
}

如果女友对这种淡妆效果还是不满意,我们可以继续添加化妆品类,睫毛膏、眼线、眉笔、腮红等等等等,只需要层层包裹起来,最终实现女友浓妆艳抹的梦想。
在这里插入图片描述

我们观察这种装饰器模式结构,是不是似曾相识呢?没错,其实装饰器模式在JDK里就有很多应用,比如Java IO包里的众多流处理类

new BufferedReader(new InputStreamReader(new FileInputStream(filePath)));

当然,流处理类当然要比我们的例子复杂的多,但其基本思想和我们去繁就简的例子异途同归,这些对象就好像是俄罗斯套娃一样层层包裹,层层装饰,每套一层就会多出一些功能出来,我们更可以自由搭配,实现不同的组合功能。
在这里插入图片描述

posted on 2020-01-11 11:19  spiritt  阅读(79)  评论(0编辑  收藏  举报