前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >设计模式之装饰者模式

设计模式之装饰者模式

作者头像
九转成圣
发布2024-04-10 17:02:55
发布2024-04-10 17:02:55
11100
代码可运行
举报
文章被收录于专栏:csdncsdn
运行总次数:0
代码可运行

装饰者模式(Decorator)

定义

动态地给一个对象添加额外的职责,就扩展功能而言,装饰模式比生成子类更为灵活。

使用场景

  1. 需要在运行时动态的给一个对象增加额外的职责时候
  2. 需要给一个现有的类增加职责,但是又不想通过继承的方式来实现的时候(应该优先使用组合而非继承),或者通过继承的方式不现实的时候(可能由于排列组合产生类爆炸的问题)

主要角色

  1. 组件接口(Component)
  2. 具体组件(Concrete Component)
  3. 装饰者抽象类(Decorator)
  4. 具体装饰者(Concrete Decorator)

类图

示例代码

组件接口

代码语言:javascript
代码运行次数:0
复制
public interface ICoffee {
    void makeCoffee();
}

具体组件

代码语言:javascript
代码运行次数:0
复制
public class OriginalCoffee implements ICoffee {

    @Override
    public void makeCoffee() {
        System.out.print("原味咖啡 ");
    }
}

抽象装饰者

代码语言:javascript
代码运行次数:0
复制
public abstract class CoffeeDecorator implements ICoffee {
    protected final ICoffee coffee;

    public CoffeeDecorator(ICoffee coffee) {
        this.coffee = coffee;
    }

    @Override
    public void makeCoffee() {
        coffee.makeCoffee();
    }
}

具体装饰者

代码语言:javascript
代码运行次数:0
复制
public class MilkDecorator extends CoffeeDecorator {
    public MilkDecorator(ICoffee coffee) {
        super(coffee);
    }

    @Override
    public void makeCoffee() {
        super.makeCoffee();
        addMilk();
    }


    private void addMilk() {
        System.out.print("加奶 ");
    }
}
代码语言:javascript
代码运行次数:0
复制
public class SugarDecorator extends CoffeeDecorator {
    public SugarDecorator(ICoffee coffee) {
        super(coffee);
    }

    @Override
    public void makeCoffee() {
        super.makeCoffee();
        addSugar();
    }

    private void addSugar() {
        System.out.print("加糖");
    }
}
代码语言:javascript
代码运行次数:0
复制
public class Client {
    public static void main(String[] args) {
        //原味咖啡
        ICoffee coffee=new OriginalCoffee();
        coffee.makeCoffee();
        System.out.println();

        //加奶的咖啡
        coffee=new MilkDecorator(coffee);
        coffee.makeCoffee();
        System.out.println();

        //先加奶后加糖的咖啡
        coffee=new SugarDecorator(coffee);
        coffee.makeCoffee();
    }
}
代码语言:javascript
代码运行次数:0
复制
原味咖啡 
原味咖啡 加奶 
原味咖啡 加奶 加糖

可以从客户端调用代码看出,装饰者模式的精髓在于动态的给对象增减功能。

当你你需要原味咖啡时那就生成原味咖啡的对象,而当你需要加奶咖啡时,仅仅需要将原味咖啡对象传递到加奶装饰者中去装饰一下就好了。如果你加了奶还想加糖,那就把加了奶的咖啡对象丢到加糖装饰者类中去装饰一下,一个先加奶后加糖的咖啡对象就出来了。 如果用继承实现就是排列组合,原味,加糖,加奶,先加糖后加奶,先加奶后加糖,如果再加蜂蜜…

装饰者模式与代理模式的区别

一般认为代理模式侧重于使用代理类增强被代理对象的访问,而装饰者模式侧重于使用装饰者类来对被装饰对象的功能进行增减。 除了上面的区别,个人实践中还发现,装饰者模式主要是提供一组装饰者类,然后形成一个装饰者栈,来动态的对某一个对象不断加强,而代理一般不会使用多级代理.

关注点

  1. 装饰者模式关注于在不改变原有对象的前提下,动态地为对象增加新的功能。
  2. 代理模式则关注于通过代理对象来控制对原始对象的访问,以达到控制访问的目的 怎么理解动态的增加功能:咖啡经过MilkDecorator变成了牛奶咖啡,再经过SugarDecorator后变成了先加牛奶再加糖的咖啡了,这里的动态指的是编写代码时.

打点日志,权限校验是不是都属于对代理对象的访问的控制

工作中遇到场景

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-04-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 装饰者模式(Decorator)
  • 定义
  • 使用场景
  • 主要角色
  • 类图
  • 示例代码
  • 装饰者模式与代理模式的区别
  • 工作中遇到场景
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档