Download Java Days Lviv 2015

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the work of artificial intelligence, which forms the content of this project

Document related concepts
no text concepts found
Transcript
Professional Java EE Design Patterns
Alex Theedom
@alextheedom
alextheedom.com
#JavaEE
@alextheedom
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
#JavaEE
@alextheedom
What to expect
• What’s the story
• Why am I here? What’s the message?
• Whistle stop tour
• Design Patterns: what, when and why
• Context Dependency Injection
#JavaEE
@alextheedom
What to expect
• Deep Dive
• Singleton Pattern
• Factory Pattern
• Harnessing the power (something special)
• Quickie Patterns
• Façade, Decorator, Observer
• Q&A
#JavaEE
@alextheedom
What’s the story
• Java EE changed design pattern implementation
• Implementation has simplified
• Implementation has been enhanced
• Greater creativity
• How?
• I will show you today
• Change is part of Java EE continued development
#JavaEE
@alextheedom
Design patterns: 3W’S
• What are design patterns?
• Why do we need them?
• When to use them?
#JavaEE
@alextheedom
Context Dependency Injection
• Simplifies programming model
• Annotations have replaced XML config files
• Convention over Configuration
• Resources are injected by type
• @Inject and disambiguation @Qualifier
• POJO (JSR 299 managed bean)
• Otherwise @Producer
#JavaEE
@alextheedom
Singleton Pattern
• Ubiquitous and controversial but inescapable
• Instantiated once
• Not normally destroy during application life cycle
#JavaEE
@alextheedom
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;
}
}
#JavaEE
@alextheedom
Conventional Implementation
• Only one instance of Logger created
• Created by first call the getInstance()
• Thread safe creation
• Use it like so:
Logger logger = Logger.getInstance();
#JavaEE
@alextheedom
Java EE Implementation
@Singleton
public class Logger {
private Logger() {
// Creation code here
}
}
#JavaEE
@alextheedom
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;
#JavaEE
@alextheedom
Java EE Implementation
• Eager instantiation @Startup
• Perform startup tasks @PostConstruct
#JavaEE
@alextheedom
Java EE Implementation
@Startup
@Singleton
public class Logger {
private Logger() {
// Creation code here
}
@PostConstruct
void startUpTask() {
// Perform start up tasks
}
}
#JavaEE
@alextheedom
Java EE Implementation
• Specify dependent instantiation
@DependsOn("PrimaryBean")
@Startup
@Singleton
public class Logger {
...
}
#JavaEE
@alextheedom
Java EE Implementation
@DependsOn("PrimaryBean")
@Startup
@Singleton
public class Logger {
private Logger() {
// Creation code here
}
@PostConstruct
void startUpTask() {
// Perform start up tasks
}
}
#JavaEE
@alextheedom
Java EE Implementation
• Conclusions so far
• Very different implementation
• Substantially less boilerplate code
• Enhancements via specialized annotations
#JavaEE
@alextheedom
Java EE Implementation
• Further enhancements
• Fine grain concurrency management
• Container vs. bean managed
@Singleton
@ConcurrencyManagement(ConcurrencyManagementType.BEAN)
public class Logger {
...
}
• What about method access?
#JavaEE
@alextheedom
Java EE Implementation
• Method access
• LockType.WRITE and LockType.READ
@Lock(LockType.WRITE)
public void addMessage(String message) {
// Add message to log
}
@Lock(LockType.READ)
public String getMessage() {
// Get message
}
#JavaEE
@alextheedom
Java EE Implementation
• Method access timeout
• ConcurrentAccessTimeoutException
• Defined by annotation @AccessTimeout
• Class and method level
@AccessTimeout(value = 30, unit=TimeUnit.SECONDS)
@Lock(LockType.WRITE)
public void addMessage(String message) {
// Add message to log
}
#JavaEE
@alextheedom
Conclusion
• Substantially different manner of implementation
• Marked reduction in code (~50%)
• Implementation improved via specialized annotations
• Startup behavioural characteristics
• Fine grain control over concurrency and access timeout
#JavaEE
@alextheedom
Factory Pattern
• Creational pattern
• Interface for creating family of objects
• Clients are decoupled from the creation
#JavaEE
@alextheedom
Conventional Implementation
• Abstract factory
public class DrinksMachineFactory implements AbstractDrinksMachineFactory{
public DrinksMachine createCoffeeMachine() {
return new CoffeeMachine();
}
}
• Use it like so:
AbstractDrinksMachineFactory factory = new DrinksMachineFactory();
DrinksMachine coffeeMachine = factory.createCoffeeMachine();
#JavaEE
@alextheedom
Java EE Implementation
• CDI framework is a factory
public class CoffeeMachine implements DrinksMachine {
// Implementation code
}
• Use it like so:
@Inject
DrinksMachine drinksMachine;
#JavaEE
@alextheedom
Java EE Implementation
• Problem!
Multiple concrete implementations
public class CoffeeMachine implements DrinksMachine {
// Implementation code
}
public class SoftDrinksMachine implements DrinksMachine {
// Implementation code
}
• Which DrinksMachine to inject?
@Inject
DrinksMachine drinksMachine;
#JavaEE
@alextheedom
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 Coffee
#JavaEE
@alextheedom
Java EE Implementation
• Annotate respective classes
@Coffee
public class CoffeeMachine implements DrinksMachine {
// Implementation code
}
@SoftDrink
public class SoftDrinksMachine implements DrinksMachine {
// Implementation code
}
#JavaEE
@alextheedom
Java EE Implementation
• Annotate injection points
@Inject @SoftDrink
DrinksMachine softDrinksMachine;
@Inject @Coffee
DrinksMachine coffeeDrinksMachine;
#JavaEE
@alextheedom
Java EE Implementation
• Conclusions so far
• No boilerplate code
• Container does all the hard work
• Disambiguation via qualifiers
• Remember
• Only JSR299 beans are ‘injectable’
#JavaEE
@alextheedom
Java EE Implementation
• Dive deeper
• Producer methods
@Produces
@Library
public List<Book> getLibrary(){
// Generate a List of books called 'library'
return library;
}
• Use it like so:
@Inject @Library
List<Books> library;
#JavaEE
@alextheedom
Java EE Implementation
• Scope
• Determines when method called
• Life of object: @RequestScoped -> @ApplicationScoped
@SessionScoped
@Produces
@Library
public List<Book> getLibrary(){
// Generate a List of books called 'library'
return library;
}
#JavaEE
@alextheedom
Java EE Implementation
• Parameterized creation
public class LoggerFactory{
@Produces
public Logger logger(InjectionPoint injectionPoint) {
return Logger.getLogger(
injectionPoint.getMember()
.getDeclaringClass().getName());
}
}
• Use it like so:
@Inject
private transient Logger logger;
#JavaEE
@alextheedom
Java EE Implementation
• Conclusions so far
• Virtually any object can be made injectable
• Automatic per class configuration
#JavaEE
@alextheedom
Harnessing the power of CDI
• A variation on the factory pattern
• Imaginative use of CDI
• Multiple implementations of the same interface
• Collect and select pattern
• Uses @Any, enums, annotation literals and Instance class
#JavaEE
@alextheedom
Harnessing the power of CDI
• @Any
@Any
@Inject
private Instance<MessageType> messages
#JavaEE
@alextheedom
Harnessing the power of CDI
• Distinguish between message types using qualifiers
@Qualifier
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.TYPE})
public @interface Message {
Type value();
enum Type{ SHORT, LONG }
}
#JavaEE
@alextheedom
Harnessing the power of CDI
• Annotate our classes
@Message(Message.Type.SHORT)
public class ShortMessage implements MessageType{
// Short message implementation code
}
@Message(Message.Type.LONG)
public class LongMessage implements MessageType{
// Long message implementation code
}
#JavaEE
@alextheedom
Harnessing the power of CDI
• Create an annotation literal for messages
public class MessageLiteral extends
AnnotationLiteral<Message> implements Message {
private Type type;
public MessageLiteral(Type type) {
this.type = type;
}
public Type value() {
return type;
}
}
#JavaEE
@alextheedom
Harnessing the power of CDI
• Putting the puzzle together
@Inject
@Any
private Instance<MessageType> messages;
public MessageType getMessage(Message.Type type) {
MessageLiteral literal = new MessageLiteral(type);
Instance<MessageType> typeMessages =
messages.select(literal);
return typeMessages.get();
}
#JavaEE
@alextheedom
Harnessing the power of CDI
• Use it like so:
@Inject
private MessageFactory mf;
public void doMessage(){
MessageType m = mf.getMessage(Message.Type.SHORT);
}
#JavaEE
@alextheedom
Conclusion
• CDI removes need for factory pattern
• Container does all the hard work
• Substantially less boilerplate code
• Disambiguation via qualifiers
• Increased creativity
• Collect and select
#JavaEE
@alextheedom
Other Patterns
• Facade
• Decorator
• Observer
#JavaEE
@alextheedom
Façade Pattern
• Encapsulates complicated logic
• @Stateless, @Stateful
@Stateless
public class AccountService{}
@Stateless
public class BankServiceFacade{
@Inject
private AccountService accountService;
}
#JavaEE
@alextheedom
Decorator Pattern
• Dynamically adds logic to an object
#JavaEE
@alextheedom
Decorator Pattern
@Decorator
@Priority(Interceptor.Priority.APPLICATION)
public class PriceDiscountDecorator implements Product {
@Any
@Inject
@Delegate
private Product product;
public String generateLabel() {
product.setPrice(product.getPrice() * 0.5);
return product.generateLabel();
}
}
#JavaEE
@alextheedom
Observer Pattern
• Notifies dependents of state change
public void trace(@Observes String message){
// Response to String event
}
#JavaEE
@alextheedom
Final Conclusion
• Efficiency savings
• Greater control over behaviour
• New features enhance implementation
• Opens doors to new pattern design
#JavaEE
@alextheedom
40% discount with promo code
VBK43
when ordering through
wiley.com
valid until 1st September
#JavaEE
@alextheedom
Q&A
#JavaEE
#DVXFR14{session hashtag}
@YourTwitterHandle
@alextheedom
Professional Java EE Design Patterns
Alex Theedom
@alextheedom
alextheedom.com
#JavaEE
Thank You
@alextheedom
Related documents