The implementation of traditional design patterns have changed in Java EE 7. By taking advantage of Java EE features such as CDI and the smart use of annotations, traditional design patterns can be implemented in a much cleaner and quicker way. With the use of code examples I will demonstrate how to implement some of the most commonly use design patterns in Java EE. Among the design patterns discuss there will be Factory, Singleton, Observer and Decorator.
2. @alextheedom#JavaEE
Speaker’s Bio
•Senior Java Developer
•Author: Professional Java EE Design Patterns
•E-learning Platforms
•Cash Machine Software
•Microservice Based Lottery Systems
•Spring and Java EE
6. @alextheedom#JavaEE
Conventional Implementation
public class Logger {
private static Logger instance;
private Logger() {
// Creation code here
}
public static synchronized Logger getInstance() {
if(instance == null) {
instance = new Logger();
}
return instance;
}
}
public class Logger {
private static Logger instance;
private Logger() {
// Creation code here
}
public static synchronized Logger getInstance() {
if(instance == null) {
instance = new Logger();
}
return instance;
}
}
7. @alextheedom#JavaEE
Conventional Implementation
•Only one instance of Logger created
•Created by first call to getInstance()
•Thread safe creation
•Use it like so:
Logger logger = Logger.getInstance();Logger logger = Logger.getInstance();
9. @alextheedom#JavaEE
Java EE Implementation
•Only one instance of Logger created
•Created by container (lazily)
•Knows it’s a singleton because @Singleton
•Use it like so:
@Inject
Logger logger;
@Inject
Logger logger;
15. @alextheedom#JavaEE
Java EE Implementation
•Further enhancements
•Fine grain concurrency management
•Container vs. bean managed
@Singleton
@ConcurrencyManagement(ConcurrencyManagementType.BEAN)
public class Logger {
...
}
@Singleton
@ConcurrencyManagement(ConcurrencyManagementType.BEAN)
public class Logger {
...
}
•What about method access?
16. @alextheedom#JavaEE
Java EE Implementation
•Method access
•LockType.WRITE and LockType.READ
•Method access timeout
@AccessTimeout(value = 30, unit=TimeUnit.SECONDS)
@Lock(LockType.WRITE)
public void addMessage(String message) {
// Add message to log
}
@Lock(LockType.READ)
public String getMessage() {
// Get message
}
@AccessTimeout(value = 30, unit=TimeUnit.SECONDS)
@Lock(LockType.WRITE)
public void addMessage(String message) {
// Add message to log
}
@Lock(LockType.READ)
public String getMessage() {
// Get message
}
17. @alextheedom#JavaEE
Conclusion
•Substantially different manner of implementation
•Marked reduction in code
•Implementation improved via specialized annotations
•Startup behavioural characteristics
•Fine grain control over concurrency and access timeout
19. @alextheedom#JavaEE
Java EE Implementation
•CDI framework is a factory
public class CoffeeMachine implements DrinksMachine {}public class CoffeeMachine implements DrinksMachine {}
•Use it like so:
@Inject
DrinksMachine drinksMachine;
@Inject
DrinksMachine drinksMachine;
20. @alextheedom#JavaEE
Java EE Implementation
•Problem! Multiple concrete implementations
public class CoffeeMachine implements DrinksMachine{…}
public class SoftDrinksMachine implements DrinksMachine{…}
public class CoffeeMachine implements DrinksMachine{…}
public class SoftDrinksMachine implements DrinksMachine{…}
@Inject
DrinksMachine drinksMachine;
@Inject
DrinksMachine drinksMachine;
•Which DrinksMachine to inject?
21. @alextheedom#JavaEE
Java EE Implementation
•Solution! Qualifiers
@Qualifier
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.FIELD})
public @interface SoftDrink
@Qualifier
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.FIELD})
public @interface SoftDrink
@Qualifier
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.FIELD})
public @interface Coffee
@Qualifier
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.FIELD})
public @interface Coffee
22. @alextheedom#JavaEE
Java EE Implementation
•Annotate respective classes
@Coffee
public class CoffeeMachine implements DrinksMachine {}
@Coffee
public class CoffeeMachine implements DrinksMachine {}
@SoftDrink
public class SoftDrinksMachine implements DrinksMachine {}
@SoftDrink
public class SoftDrinksMachine implements DrinksMachine {}
•Annotate injection points
@Inject @SoftDrink
DrinksMachine softDrinksMachine;
@Inject @SoftDrink
DrinksMachine softDrinksMachine;
@Inject @Coffee
DrinksMachine coffeeDrinksMachine;
@Inject @Coffee
DrinksMachine coffeeDrinksMachine;
24. @alextheedom#JavaEE
Java EE Implementation
•Dive deeper
•Producer methods
•Use it like so:
@Produces
@Library
public List<Book> getLibrary(){
// Generate a List of books called 'library'
return library;
}
@Produces
@Library
public List<Book> getLibrary(){
// Generate a List of books called 'library'
return library;
}
@Inject @Library
List<Books> library;
@Inject @Library
List<Books> library;
25. @alextheedom#JavaEE
Java EE Implementation
•Scope
•Determines when method called
•Life of object: @RequestScoped -> @ApplicationScoped
@RequestScoped
@Produces
@Library
public List<Book> getLibrary(){
// Generate a List of books called 'library'
return library;
}
@RequestScoped
@Produces
@Library
public List<Book> getLibrary(){
// Generate a List of books called 'library'
return library;
}
26. @alextheedom#JavaEE
Java EE Implementation
•Parameterized creation
public class LoggerFactory{
@Produces
public Logger logger(InjectionPoint injectionPoint) {
return Logger.getLogger(
injectionPoint.getMember()
.getDeclaringClass().getName());
}
}
public class LoggerFactory{
@Produces
public Logger logger(InjectionPoint injectionPoint) {
return Logger.getLogger(
injectionPoint.getMember()
.getDeclaringClass().getName());
}
}
@Inject
private transient Logger logger;
@Inject
private transient Logger logger;
27. @alextheedom#JavaEE
Conclusion
•CDI removes need for factory pattern
•Container does all the hard work
•Substantially less boilerplate code
•Disambiguation via qualifiers
•Virtually any object can be made injectable
•Automatic per class configuration
29. @alextheedom#JavaEE
Façade Pattern
•Encapsulates complicated logic
•@Stateless, @Stateful
@Stateless
public class BankServiceFacade {
@Inject
private AccountService accountService;
}
@Stateless
public class BankServiceFacade {
@Inject
private AccountService accountService;
}
@Stateless
public class AccountService{}
@Stateless
public class AccountService{}