【问题标题】:CDI : Is @Decorator useful in real projects compared to classic decorator patternCDI:与经典装饰器模式相比,@Decorator 在实际项目中是否有用
【发布时间】:2016-01-20 18:28:30
【问题描述】:
Env:
   Wildfly 9.0.1
   Weld 2.2.14

我目前正在研究在我们的旧代码库中合理使用 CDI @Decorator 的可能性。

查看规范和 java ee 7 示例,CDI @Decorators 似乎是

  • 在编译时定义。好吧,至少是他们的名单
  • 不能像经典装饰器那样在运行时装饰对象 模式

引用经典的 Pizza and Toppings 示例,可以在运行时创建任何深度的加满披萨。例如:new Cheese(new Ham(new Pepper(new LargePizza())))

CDI @Decorator 可以做到这一点吗?如果不是,@Decorator 的真正用途是什么,您必须在编译时声明对象,即使用 @Decorator 和 @Delegate(以及 beans.xml 中的列表)?可能是我在这里遗漏了一些东西。

提前致谢,

拉克什

【问题讨论】:

  • 我使用装饰器的一种方法是通过使用某种缓存来隐藏对实际服务调用的昂贵调用。这只是在我无法使用某种缓存拦截器逻辑的情况下

标签: java jakarta-ee design-patterns cdi decorator


【解决方案1】:

装饰器和替代方案是解决相似但不完全相同问题的两种方法。在另一种情况下,您希望满足现有 bean 的签名,同时不执行原始 bean 的任何行为。把它想象成嘲弄。

装饰器和拦截器可能更密切相关。装饰器旨在在调用原始 bean 的代码之前/之后做一些事情。这类似于拦截器,除了拦截器期望将相同的拦截逻辑应用于所有方法调用。装饰者没有这种期望。

【讨论】:

  • 我的问题是关于 CDI 装饰器及其在现实世界中的使用。
  • @RakeshK.Cherukuri 这个答案非常适合您的问题。您问与手工制作的方法相比,CDI 为您提供了什么。不多。只保证注入的 bean 已经自动“装饰”了。
【解决方案2】:

您问 CDI 与经典的手工编写的装饰器模式相比给了您什么。不多。仅:

  • 保证注入的bean已经自动“装饰”了
  • 让您跳过装饰界面中的每个方法

顺便说一句,一些澄清,你说:

使用 CDI (...) 对象不能像经典的装饰器模式那样在运行时进行装饰

错了,对象是在运行时修饰的。但是什么被什么修饰,是在编译时声明的。
如果您自己实现装饰器模式(经典方法),那么您将获得提到的灵活性 - 但您真的需要这个吗?有时是,有时不是。


更新:CDI @Decorator 确实不能防止 类爆炸 问题。这是一个很大的缺点。

但我也可以想象 CDI @Decorator 的有效用例 - 例如假设您想为EntityManager 添加一些行为。在这种情况下,您不能使用继承,因为 JPA 实现在编译时是未知的。如果您要手动实现装饰器,那么您将不得不编写很多很多方法,请参见:

public class CraftedEntityManager implements EntityManager {

    private final EntityManager delegator;

    public CraftedEntityManager(EntityManager em) {
        this.delegator = em;
    }

    @Override
    public void persist(Object entity) {
        delegator.persist(entity);
    }

    @Override
    public <T> T merge(T entity) {
        return delegator.merge(entity);
    }

    @Override
    public void remove(Object entity) {
        delegator.remove(entity);
    }

    // ...
    // here goes almost 50 other methods of the EntityManager

}

所以这似乎是一个很好的用例。

【讨论】:

  • 谢谢@Demecki。这也正是我的观点。经典的装饰器模式可防止类爆炸。据我了解(正如您所说),CDI 并非如此,我们必须声明“什么被什么装饰”。也就是说,我只是想知道为什么 @Decorator 如果不能解决“班级爆炸”问题,为什么会首先添加它。按照设计,CDI 应该拥有它。对于您的另一个问题,我们是否需要它在很大程度上取决于手头的任务。看看 Java EE 所取得的进步,我对 @Decorator 到目前为止是一个有限的装饰器模式感到有点惊讶。
  • @RakeshK.Cherukuri 你是对的。请查看我的更新答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-03-10
  • 1970-01-01
  • 2019-02-23
  • 2012-01-20
  • 2018-12-23
  • 2019-10-16
  • 2021-04-01
相关资源
最近更新 更多