去年的这个时候,我写了一系列有关JavaEE实现设计模式的博客文章。 大约一年后,我意识到我错过了我最喜欢的图案装饰器。
装饰器模式基本上是通过装饰其他对象来扩展对象功能的方法,这些对象可以包装目标对象并为其添加自身的行为。 如果您从未使用过或听说过装饰器,我强烈建议您阅读Head First Design Patterns的第3章。
就像我之前的文章中提到的其他模式一样,JavaEE提供了一种简单而优雅的方式来使用装饰器模式。 让我们从一个简单的无状态会话Bean开始。
package com.devchronicles.decorator;import javax.ejb.Stateless;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;/**** @author murat*/
@Stateless
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public class EventService {public void startService(){System.out.println("do something important here...");}
}
要开始实现装饰器模式,我们需要一个接口,以便可以将装饰器和要装饰的对象绑定在一起。
package com.devchronicles.decorator;/**** @author murat*/
public interface ServiceInterface {public void startService();
}
接口具有装饰器将在其上添加功能的方法。 接下来,我们需要对现有的EventService bean进行一些更改以使其可修饰。
package com.devchronicles.decorator;import javax.ejb.Stateless;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;/**** @author murat*/
@Stateless
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public class EventService implements ServiceInterface{public void startService(){System.out.println("do something important here...");}
}
现在我们准备添加所需的装饰器。 我们需要做的就是注释我们的类,实现ServiceInterface并注入我们的服务委托。
package com.devchronicles.decorator;import javax.decorator.Decorator;
import javax.decorator.Delegate;
import javax.inject.Inject;/**** @author murat*/
@Decorator //declares this class as a decorator
public class DecoratorService implements ServiceInterface{ //must implement the service interface@Inject //inject the service@Delegate //and annotate as the delegateServiceInterface service;@Overridepublic void startService() { //implement the startService method to add functionalitySystem.out.println("decorating the existing service!");service.startService(); //let the execution chain continue}
}
几个装饰器可以使用服务接口。
package com.devchronicles.decorator;import javax.decorator.Decorator;
import javax.decorator.Delegate;
import javax.inject.Inject;/**** @author murat*/
@Decorator
public class Decorator2Service implements ServiceInterface{@Inject@DelegateServiceInterface service;@Overridepublic void startService() {System.out.println("decorating the service even further!!!");service.startService();}
}
大多数配置可以通过JavaEE6中的注释来完成。 但是,我们仍然需要添加一些xml配置以使装饰器起作用。 由于我们已经为装饰器添加了注释,因此这似乎令人失望,但是配置仍然非常简单,并且需要声明执行顺序。 将以下行添加到空的beans.xml中。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://java.sun.com/xml/ns/javaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/beans_1_0.xsd"><decorators><class>com.devchronicles.decorator.DecoratorService</class><class>com.devchronicles.decorator.Decorator2Service</class></decorators>
</beans>
当执行EventService的startService方法时,装饰器将装饰ejb并将其自身的行为添加到执行中。
...INFO: WEB0671: Loading application [Decorator] at [/Decorator]
INFO: Decorator was successfully deployed in 2,534 milliseconds.
INFO: decorating the existing service!
INFO: decorating the service even further!!!
INFO: do something important here...
...
参考: JavaEE重新审视设计模式: Developer Chronicles博客上的JCG合作伙伴 Murat Yener的装饰器 。
翻译自: https://www.javacodegeeks.com/2012/10/javaee-revisits-design-patterns-decorator.html