java days lviv 2015

50
#JavaEE @alextheedom Professional Java EE Design Patterns Alex Theedom @alextheedom alextheedom.com

Upload: atheedom

Post on 08-Aug-2015

57 views

Category:

Technology


0 download

TRANSCRIPT

Page 1: Java days Lviv 2015

#JavaEE#JavaEE @alextheedom@alextheedom

Professional Java EE Design PatternsAlex Theedom@alextheedom alextheedom.com

Page 2: Java days Lviv 2015

@alextheedom@alextheedom#JavaEE#JavaEE

Speaker’s BioSpeaker’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

Page 3: Java days Lviv 2015

@alextheedom@alextheedom#JavaEE#JavaEE

What to expectWhat 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

Page 4: Java days Lviv 2015

@alextheedom@alextheedom#JavaEE#JavaEE

What to expectWhat to expect

•Deep Dive

•Singleton Pattern

•Factory Pattern

•Harnessing the power (something special)

•Quickie Patterns

•Façade, Decorator, Observer

•Q&A

Page 5: Java days Lviv 2015

@alextheedom@alextheedom#JavaEE#JavaEE

What’s the storyWhat’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

Page 6: Java days Lviv 2015

@alextheedom@alextheedom#JavaEE#JavaEE

Design patterns: 3W’SDesign patterns: 3W’S

•What are design patterns?

•Why do we need them?

•When to use them?

Page 7: Java days Lviv 2015

@alextheedom@alextheedom#JavaEE#JavaEE

Context Dependency InjectionContext 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

Page 8: Java days Lviv 2015

@alextheedom@alextheedom#JavaEE#JavaEE

Singleton PatternSingleton Pattern

•Ubiquitous and controversial but inescapable

•Instantiated once

•Not normally destroy during application life cycle

Page 9: Java days Lviv 2015

@alextheedom@alextheedom#JavaEE#JavaEE

Conventional ImplementationConventional 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;     } }

Page 10: Java days Lviv 2015

@alextheedom@alextheedom#JavaEE#JavaEE

Conventional ImplementationConventional Implementation

•Only one instance of Logger created

•Created by first call the getInstance()

•Thread safe creation

•Use it like so:

Logger logger = Logger.getInstance(); Logger logger = Logger.getInstance();

Page 11: Java days Lviv 2015

@alextheedom@alextheedom#JavaEE#JavaEE

Java EE ImplementationJava EE Implementation @Singleton public class Logger {

     private Logger() {          // Creation code here     }

}

@Singleton public class Logger {

     private Logger() {          // Creation code here     }

}

Page 12: Java days Lviv 2015

@alextheedom@alextheedom#JavaEE#JavaEE

Java EE ImplementationJava 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;

Page 13: Java days Lviv 2015

@alextheedom@alextheedom#JavaEE#JavaEE

Java EE ImplementationJava EE Implementation

•Eager instantiation @Startup

•Perform startup tasks @PostConstruct

Page 14: Java days Lviv 2015

@alextheedom@alextheedom#JavaEE#JavaEE

Java EE ImplementationJava EE Implementation

@Startup @Singleton public class Logger {

     private Logger() {          // Creation code here     }

     @PostConstruct     void startUpTask() {          // Perform start up tasks     } }

@Startup @Singleton public class Logger {

     private Logger() {          // Creation code here     }

     @PostConstruct     void startUpTask() {          // Perform start up tasks     } }

Page 15: Java days Lviv 2015

@alextheedom@alextheedom#JavaEE#JavaEE

Java EE ImplementationJava EE Implementation

•Specify dependent instantiation

@DependsOn("PrimaryBean") @Startup @Singleton public class Logger {     ... }

@DependsOn("PrimaryBean") @Startup @Singleton public class Logger {     ... }

Page 16: Java days Lviv 2015

@alextheedom@alextheedom#JavaEE#JavaEE

Java EE ImplementationJava EE Implementation

@DependsOn("PrimaryBean") @Startup @Singleton public class Logger {

     private Logger() {          // Creation code here     }

     @PostConstruct     void startUpTask() {          // Perform start up tasks     } }

@DependsOn("PrimaryBean") @Startup @Singleton public class Logger {

     private Logger() {          // Creation code here     }

     @PostConstruct     void startUpTask() {          // Perform start up tasks     } }

Page 17: Java days Lviv 2015

@alextheedom@alextheedom#JavaEE#JavaEE

Java EE ImplementationJava EE Implementation

•Conclusions so far

•Very different implementation

•Substantially less boilerplate code

•Enhancements via specialized annotations

Page 18: Java days Lviv 2015

@alextheedom@alextheedom#JavaEE#JavaEE

Java EE ImplementationJava 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?

Page 19: Java days Lviv 2015

@alextheedom@alextheedom#JavaEE#JavaEE

Java EE ImplementationJava 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 }

@Lock(LockType.WRITE) public void addMessage(String message) {    // Add message to log }

 @Lock(LockType.READ) public String getMessage() {     // Get message }

Page 20: Java days Lviv 2015

@alextheedom@alextheedom#JavaEE#JavaEE

Java EE ImplementationJava 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 }

@AccessTimeout(value = 30, unit=TimeUnit.SECONDS) @Lock(LockType.WRITE) public void addMessage(String message) {    // Add message to log }

Page 21: Java days Lviv 2015

@alextheedom@alextheedom#JavaEE#JavaEE

ConclusionConclusion

•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

Page 22: Java days Lviv 2015

@alextheedom@alextheedom#JavaEE#JavaEE

Factory PatternFactory Pattern

•Creational pattern

•Interface for creating family of objects

•Clients are decoupled from the creation

Page 23: Java days Lviv 2015

@alextheedom@alextheedom#JavaEE#JavaEE

Conventional ImplementationConventional Implementation

public class DrinksMachineFactory implements AbstractDrinksMachineFactory{     public DrinksMachine createCoffeeMachine() {          return new CoffeeMachine();     } }

public class DrinksMachineFactory implements AbstractDrinksMachineFactory{     public DrinksMachine createCoffeeMachine() {          return new CoffeeMachine();     } }

•Use it like so:

AbstractDrinksMachineFactory factory = new DrinksMachineFactory(); DrinksMachine coffeeMachine = factory.createCoffeeMachine();

AbstractDrinksMachineFactory factory = new DrinksMachineFactory(); DrinksMachine coffeeMachine = factory.createCoffeeMachine();

•Abstract factory

Page 24: Java days Lviv 2015

@alextheedom@alextheedom#JavaEE#JavaEE

Java EE ImplementationJava EE Implementation

•CDI framework is a factory

public class CoffeeMachine implements DrinksMachine {     // Implementation code }

public class CoffeeMachine implements DrinksMachine {     // Implementation code }

•Use it like so:

@Inject DrinksMachine drinksMachine; @Inject DrinksMachine drinksMachine;

Page 25: Java days Lviv 2015

@alextheedom@alextheedom#JavaEE#JavaEE

Java EE ImplementationJava EE Implementation

•Problem! Multiple concrete implementations

public class CoffeeMachine implements DrinksMachine {     // Implementation code }

public class SoftDrinksMachine implements DrinksMachine {     // Implementation code }

public class CoffeeMachine implements DrinksMachine {     // Implementation code }

public class SoftDrinksMachine implements DrinksMachine {     // Implementation code }

@Inject DrinksMachine drinksMachine; @Inject DrinksMachine drinksMachine;

•Which DrinksMachine to inject?

Page 26: Java days Lviv 2015

@alextheedom@alextheedom#JavaEE#JavaEE

Java EE ImplementationJava 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

Page 27: Java days Lviv 2015

@alextheedom@alextheedom#JavaEE#JavaEE

Java EE ImplementationJava EE Implementation

•Annotate respective classes

@Coffee public class CoffeeMachine implements DrinksMachine {     // Implementation code }

@Coffee public class CoffeeMachine implements DrinksMachine {     // Implementation code }

@SoftDrink public class SoftDrinksMachine implements DrinksMachine {     // Implementation code }

@SoftDrink public class SoftDrinksMachine implements DrinksMachine {     // Implementation code }

Page 28: Java days Lviv 2015

@alextheedom@alextheedom#JavaEE#JavaEE

Java EE ImplementationJava EE Implementation

•Annotate injection points

@Inject @SoftDrink DrinksMachine softDrinksMachine; @Inject @SoftDrink DrinksMachine softDrinksMachine;

@Inject @Coffee DrinksMachine coffeeDrinksMachine; @Inject @Coffee DrinksMachine coffeeDrinksMachine;

Page 29: Java days Lviv 2015

@alextheedom@alextheedom#JavaEE#JavaEE

Java EE ImplementationJava EE Implementation

•Conclusions so far

•No boilerplate code

•Container does all the hard work

•Disambiguation via qualifiers

•Remember

•Only JSR299 beans are ‘injectable’

Page 30: Java days Lviv 2015

@alextheedom@alextheedom#JavaEE#JavaEE

Java EE ImplementationJava 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;

Page 31: Java days Lviv 2015

@alextheedom@alextheedom#JavaEE#JavaEE

Java EE ImplementationJava 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; }

@SessionScoped @Produces @Library public List<Book> getLibrary(){     // Generate a List of books called 'library'     return library; }

Page 32: Java days Lviv 2015

@alextheedom@alextheedom#JavaEE#JavaEE

Java EE ImplementationJava EE Implementation•Parameterized creation

•Use it like so:

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;

Page 33: Java days Lviv 2015

@alextheedom@alextheedom#JavaEE#JavaEE

Java EE ImplementationJava EE Implementation

•Conclusions so far

•Virtually any object can be made injectable

•Automatic per class configuration

Page 34: Java days Lviv 2015

@alextheedom@alextheedom#JavaEE#JavaEE

Harnessing the power of CDIHarnessing 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

Page 35: Java days Lviv 2015

@alextheedom@alextheedom#JavaEE#JavaEE

Harnessing the power of CDIHarnessing the power of CDI

•@Any

@Any @Inject private Instance<MessageType> messages

@Any @Inject private Instance<MessageType> messages

Page 36: Java days Lviv 2015

@alextheedom@alextheedom#JavaEE#JavaEE

Harnessing the power of CDIHarnessing 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 } }

@Qualifier @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.FIELD, ElementType.TYPE}) public @interface Message {     Type value();     enum Type{ SHORT, LONG } }

Page 37: Java days Lviv 2015

@alextheedom@alextheedom#JavaEE#JavaEE

Harnessing the power of CDIHarnessing the power of CDI

•Annotate our classes

@Message(Message.Type.SHORT) public class ShortMessage implements MessageType{     // Short message implementation code }

@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 }

@Message(Message.Type.LONG) public class LongMessage implements MessageType{     // Long message implementation code }

Page 38: Java days Lviv 2015

@alextheedom@alextheedom#JavaEE#JavaEE

Harnessing the power of CDIHarnessing the power of CDI

•Create an annotation literal for messages

public class MessageLiteral extendsAnnotationLiteral<Message> implements Message {

private Type type; public MessageLiteral(Type type) { this.type = type; }

public Type value() { return type;

} }

public class MessageLiteral extendsAnnotationLiteral<Message> implements Message {

private Type type; public MessageLiteral(Type type) { this.type = type; }

public Type value() { return type;

} }

Page 39: Java days Lviv 2015

@alextheedom@alextheedom#JavaEE#JavaEE

Harnessing the power of CDIHarnessing 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(); }

@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(); }

Page 40: Java days Lviv 2015

@alextheedom@alextheedom#JavaEE#JavaEE

Harnessing the power of CDIHarnessing the power of CDI

•Use it like so:

@Inject private MessageFactory mf;  public void doMessage(){        MessageType m = mf.getMessage(Message.Type.SHORT); }

@Inject private MessageFactory mf;  public void doMessage(){        MessageType m = mf.getMessage(Message.Type.SHORT); }

Page 41: Java days Lviv 2015

@alextheedom@alextheedom#JavaEE#JavaEE

ConclusionConclusion

•CDI removes need for factory pattern

•Container does all the hard work

•Substantially less boilerplate code

•Disambiguation via qualifiers

•Increased creativity

•Collect and select

Page 42: Java days Lviv 2015

@alextheedom@alextheedom#JavaEE#JavaEE

Other PatternsOther Patterns

•Facade

•Decorator

•Observer

Page 43: Java days Lviv 2015

@alextheedom@alextheedom#JavaEE#JavaEE

Façade PatternFaç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{}

Page 44: Java days Lviv 2015

@alextheedom@alextheedom#JavaEE#JavaEE

Decorator PatternDecorator Pattern

•Dynamically adds logic to an object

Page 45: Java days Lviv 2015

@alextheedom@alextheedom#JavaEE#JavaEE

Decorator PatternDecorator 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();    } }

@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();    } }

Page 46: Java days Lviv 2015

@alextheedom@alextheedom#JavaEE#JavaEE

Observer PatternObserver Pattern

•Notifies dependents of state change

public void trace(@Observes String message){     // Response to String event }

public void trace(@Observes String message){     // Response to String event }

Page 47: Java days Lviv 2015

@alextheedom@alextheedom#JavaEE#JavaEE

Final ConclusionFinal Conclusion

•Efficiency savings

•Greater control over behaviour

•New features enhance implementation

•Opens doors to new pattern design

Page 48: Java days Lviv 2015

#JavaEE#JavaEE @alextheedom@alextheedom

40% discount with promo

code VBK43when ordering through

wiley.comvalid until 1st September

Page 49: Java days Lviv 2015

@YourTwitterHandle#DVXFR14{session hashtag} @alextheedom@alextheedom#JavaEE#JavaEE

Q & A

Page 50: Java days Lviv 2015

#JavaEE#JavaEE @alextheedom@alextheedom

Professional Java EE Design PatternsAlex Theedom@alextheedom alextheedom.com

Thank You