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 中的列表)?可能是我在这里遗漏了什么。
提前致谢
拉克什
最佳答案
您问与传统的手写装饰器模式相比,CDI 给您带来了什么。不多。仅:
- 保证注入(inject)的bean已经被自动“装饰”了
- 让您跳过修饰界面中的每个方法的重写
顺便说一句,一些澄清,你说:
With CDI (...) objects can not be decorated at runtime like the classic Decorator pattern
错了,对象是在运行时修饰的。但是什么被什么装饰,是在编译时声明的。
如果您自己实现装饰器模式(经典方法),那么您将获得提到的灵 active ——但您真的需要这个吗?有时是,有时不是。
更新: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
}
所以这似乎是一个很好的用例。
关于java - CDI : Is @Decorator useful in real projects compared to classic decorator pattern,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33264726/