设计模式(十二)装饰者模式

设计模式概述见:
http://blog.csdn.net/chijiandi/article/details/78839305

装饰者模式的基本概念

装饰者模式是在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象。
有点像我们小时候玩过的纸盒套纸盒,拆开一层还有一层的样子,每一层的纸盒则是对应不同的功能,你想要这个功能就装饰,不想要就不装饰。

什么时候使用装饰者模式

当一个已完成的类功能需要进行一些动态的功能添加,比方说炒菜时可以选择加盐不加盐,也可以选择放葱不放葱,又或者可以结合观察者模式,在炒菜时选择是否通知别人。
使用继承不易扩展,而装饰者模式使装饰类和被装饰类相互独立,避免了他们的耦合,并通过动态添加的方式对类进行一个维护。

装饰者模式怎么用

比方说我们现在有一个已完成的类,而我们并不想修改他已完成的代码,可是却想让他在执行这个操作的时候动态操作做一些我们想做的事

已有的类:

package behavioralPattren.decorator;

/**
 * @author : cjd
 * @Description : 需要装饰的类
 * @create : 2018-04-08 9:05
 **/
public class Food {
    private String name = "";

    public Food() {
    }

    public Food(String name) {
        this.name = name;
    }

    public void fry() {
        System.out.println("做了一道" + name);
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

第一步:提取需要装饰的方法fry成抽象,同时让已有类实现抽象

package behavioralPattren.decorator;

/**
 * @author : cjd
 * @Description : 需要扩展的方法
 * @create : 2018-04-08 9:58
 **/
public interface Cooking {
     void fry();
}

第二步:创建一个动态装饰的类,与代理模式很像,不过这里并没有对方法直接进行扩展

package behavioralPattren.decorator;

/**
 * @author : cjd
 * @Description : 被动态装饰的类
 * @create : 2018-04-08 9:13
 **/
public class Steps implements Cooking {
    protected Cooking cooking;

    protected Steps(Cooking cooking) {
        this.cooking = cooking;
    }

    @Override
    public void fry() {
        if (cooking != null) {
            cooking.fry();
        }
    }
}

第三步:创建具体装饰类,在这里可以控制方法在装饰之前还是之后执行

package behavioralPattren.decorator;

/**
 * @author : cjd
 * @Description : 具体装饰的类
 * @create : 2018-04-08 9:17
 **/
public class ActualStep extends Steps {

    public ActualStep(Cooking cooking) {
        super(cooking);
    }

    @Override
    public void fry() {
        ownMethod();
        super.fry();
        //ownMethod();放在父类方法执行后执行也可以,具体执行顺序越后面包装的越迟执行
        // 执行顺序如   4 3 2 1 2 3 4
    }

    //需要装饰的独立方法
    private void ownMethod() {
        System.out.println("我在做完前做一些自己的事");
    }
}

主函数进行调用:

package behavioralPattren.decorator;

/**
 * @author : cjd
 * @Description : 主函数
 * @create : 2018-04-08 9:20
 **/
public class Main {
    public static void main(String[] args) {
        ActualStep actualStep = new ActualStep(new Food("宫保鸡丁"));
        actualStep.fry();
    }
}

结果如下:

我在做完前做一些自己的事
做了一道宫保鸡丁

扫描二维码关注公众号,回复: 2546302 查看本文章

后记

装饰者模式和代理模式的结构很相似,相比较代理模式而言使用难度上也略微提高一些,在添加一些额外的操作时装饰者模式显然更加灵活,而代理模式使用方便,他大多也时用作隐藏一些不想让客户端知道的信息
如果要我用自己的话来形容装饰模式,我感觉学会这个模式对扩展来说,使用上真的很强大。

猜你喜欢

转载自blog.csdn.net/chijiandi/article/details/79848200