KEMBAR78
Alex Theedom Java ee revisits design patterns | PDF
Java EE
revisits design patterns
Sep. 2-4
Kyiv, Desyatynna str. 12
@readlearncode
Alex Theedom Senior Java Developer
Who am I?
Alex Theedom, Senior Java Developer
@readlearncode
Available at
What’s on?
• Design patterns retrospective
• Map classical design patterns to Java EE 7
• Contexts and Dependency Injection
• Singleton, Factory, Façade, Decorator and Observer
• Final Conclusions
• Q&A
What are you doing?
• Java Enterprise Edition (J2EE, EE 6/7)
• Spring
The beginning
•Design Patterns: Elements of Reusable Object-Oriented Software
(E Gamma, R Helm, R Johnson and J Vlissides. 1994)
AKA Gang of Four AKA GoF
•Creational, behavioral and structural
•So what are design patterns in practice?
Enterprise Java and design patterns
•JavaOne 2000 talk: Prototyping patterns for the J2EE
platform
•Core J2EE Patterns (D. Anur, J. Crupi and D. Malks)
•Out-of-box design pattern implementations with
Java EE 5
Java EE Programming Model
•Simplified programming model
• Annotations have replaced XML description files
• Convention over Configuration
• CDI hides object creation
•Resources are injected by type
Singleton Pattern
•Creational pattern
•Single instance and instantiated once
•Must be thread safe
•Not normally destroy during application life cycle
•Classic implementation: private constructor, double
locking, static initializer, enums …
Singleton Pattern
@DependsOn("DatabaseConnectionBean")
@Startup
@Singleton
public class Logger {
@PostConstruct
void constructExpensiveObject() {
// Expensive construction
}
}
@Inject
Logger logger;
Singleton Pattern
•Conclusions so far
• Very different implementation
• Substantially less boilerplate code
• Enhancements via specialized annotations
There’s more…
Singleton Pattern
@Singleton
@ConcurrencyManagement(ConcurrencyManagementType.BEAN)
public class Logger {
@AccessTimeout(value = 30, unit=TimeUnit.SECONDS)
@Lock(LockType.WRITE)
public void addMessage(String message) {}
@Lock(LockType.READ)
public String getMessage() {}
}
•Container/bean managed concurrency
The Good, Bad and the Ugly
•The Good:
•enhancements via specialized annotations
•startup behavioural characteristics
•fine grain control over concurrency and access
timeout
•substantially less boilerplate code
The Good, Bad and the Ugly
•The Bad:
•overuse can cause problems
•lazy loading causes delays
•eager loading causes memory problems
•And the ugly:
•considered an anti-pattern
•only niche use
•smarter to use a stateless session bean
The Good, Bad and the Ugly
Factory Pattern
•Creational pattern
•Interface for creating family of objects
•Clients are decoupled from the creation
Factory Pattern
•CDI framework is a factory !?!
public class CoffeeMachine implements DrinksMachine {
// Implementation code
}
•Use it like so:
@Inject
DrinksMachine drinksMachine;
Factory Pattern
•Problem! Multiple concrete implementations
public class CoffeeMachine implements DrinksMachine {
// Implementation code
}
public class SoftDrinksMachine implements DrinksMachine {
// Implementation code
}
@Inject
DrinksMachine drinksMachine;
•Which DrinksMachine to inject?
?!?
Factory Pattern
•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
Factory Pattern
•Annotate respective classes
@Coffee
public class CoffeeMachine implements DrinksMachine {
// Implementation code
}
@SoftDrink
public class SoftDrinksMachine implements DrinksMachine {
// Implementation code
}
Factory Pattern
•Annotate injection points
@Inject @SoftDrink
DrinksMachine softDrinksMachine;
@Inject @Coffee
DrinksMachine coffeeDrinksMachine;
Factory Pattern
•Remember
•Only JSR299 beans are ‘injectable’
•But I want to inject a Collection type or Object with a
parameterized constructor
-> let’s dive deeper
Factory Pattern
•Dive deeper
• Producer methods
• Use it like so:
@History
@Produces
public List<Book> getLibrary(){
// Generate a List of books called 'library'
return library;
}
@History
@Inject
List<Books> library;
@Qualifier
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface History
Factory Pattern
• Scope
• Determines when method called
• Life of object: @RequestScoped -> @ApplicationScoped
@RequestScoped
@History
@Produces
public List<Book> getLibrary(){
// Generate a List of books called 'library'
return library;
}
The Good, Bad and the Ugly
•The Good:
•easy to implement
•no boilerplate code
•works magically
•any object can be made injectable
The Good, Bad and the Ugly
•The Bad: named annotation is not type safe
@Named("History") -> @History
•and the ugly: object creation hidden, hard to follow
execution flow, IDE should help
Façade Pattern
•Hides the complex logic and provides the interface for
the client
•Typically used in APIs
•Classic implementation: Just create a method to hide
complexity
Façade Pattern
•Encapsulates complicated logic
• @Stateless, @Stateful@Stateless
public class BankServiceFacade{
public void complexBusinessLogic(){
// Very very complex logic
}
}
@Inject
public BankServiceFacade service;
The Good, Bad and the Ugly
•The Good: simple, robust, gives you a range of services
•The Bad: over use introduces unnecessary layers, if you
don’t need it don’t introduce one
•and the ugly: there isn’t one really
Decorator Pattern
•Structural Pattern
•Dynamically adds logic to an object at runtime
•More flexible that inheritance
•Classic implementation: Both the decorator and target
object share the same interface. Decorator wraps the
target object and adds its own behaviour
Decorator Pattern
@Decorator
@Priority(Interceptor.Priority.APPLICATION)
public class PriceDiscountDecorator implements Product {
@Coffee
@Any
@Delegate
@Inject
private Product product;
public String generateLabel() {
product.setPrice(product.getPrice() * 0.5);
return product.generateLabel();
}
}
•The Good: very easy to change behaviour without
breaking legacy code
•The Bad: needs XML config (<CDI 1.1)
•and the ugly: overuse will introduce an execution flow
which is hard to follow
The Good, Bad and the Ugly
Observer Pattern
•Behavioural Pattern
•Publisher-Subscriber
•Classic implementation: Implement a Subscriber
interface, register with publisher and call a notify
method on subscribers
Observer Pattern
•Define an event class
public class MessageEvent {
private String message;
public MessageEvent(String message){
this.message = message;
}
public String getMessage(){
return message;
}
}
Observer Pattern
•Notifies dependents of state change
@Stateless
public class MessageService {
@Inject
Event<MessageEvent> messageEvent;
public void fireMessage(){
messageEvent.fire(new MessageEvent("Hello World"));
}
}
Observer Pattern
•Dependent receives state change notification
@Stateless
public class MessageObserver {
public void listenToMessage(@Observes MessageEvent message){
System.out.println(message.getMessage());
}
}
Observer Pattern
•Qualifier to filter events
@WarningMessage
@Inject
Event<MessageEvent> messageEvent;
public void listenToMessage(
@Observes @WarningMessage MessageEvent message)
The Good, Bad and the Ugly
•The Good: very easy, no boilerplate code, less than JMS,
the container does the heavy lifting, light weight
•The Bad: confusing execution order but IDE will help
•and the ugly: nothing, its beautiful
Entity
•Lightweight domain object which is persistable
•Annotated with javax.persistence.Entity
•Can represent relational data object/relational mapping
annotations
Entity
@Entity
public class Contact {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String firstName;
private String lastName;
}
Final Conclusion
•Efficiency savings
•Greater control over behaviour
•New features enhance implementation
Q & A
Thank You
Sep. 2-4
Kyiv, Desyatynna str. 12
@readlearncode
Alex Theedom Senior Java Developer

Alex Theedom Java ee revisits design patterns

  • 1.
    Java EE revisits designpatterns Sep. 2-4 Kyiv, Desyatynna str. 12 @readlearncode Alex Theedom Senior Java Developer
  • 2.
    Who am I? AlexTheedom, Senior Java Developer @readlearncode
  • 3.
  • 4.
    What’s on? • Designpatterns retrospective • Map classical design patterns to Java EE 7 • Contexts and Dependency Injection • Singleton, Factory, Façade, Decorator and Observer • Final Conclusions • Q&A
  • 5.
    What are youdoing? • Java Enterprise Edition (J2EE, EE 6/7) • Spring
  • 6.
    The beginning •Design Patterns:Elements of Reusable Object-Oriented Software (E Gamma, R Helm, R Johnson and J Vlissides. 1994) AKA Gang of Four AKA GoF •Creational, behavioral and structural •So what are design patterns in practice?
  • 7.
    Enterprise Java anddesign patterns •JavaOne 2000 talk: Prototyping patterns for the J2EE platform •Core J2EE Patterns (D. Anur, J. Crupi and D. Malks) •Out-of-box design pattern implementations with Java EE 5
  • 8.
    Java EE ProgrammingModel •Simplified programming model • Annotations have replaced XML description files • Convention over Configuration • CDI hides object creation •Resources are injected by type
  • 9.
    Singleton Pattern •Creational pattern •Singleinstance and instantiated once •Must be thread safe •Not normally destroy during application life cycle •Classic implementation: private constructor, double locking, static initializer, enums …
  • 10.
    Singleton Pattern @DependsOn("DatabaseConnectionBean") @Startup @Singleton public classLogger { @PostConstruct void constructExpensiveObject() { // Expensive construction } } @Inject Logger logger;
  • 11.
    Singleton Pattern •Conclusions sofar • Very different implementation • Substantially less boilerplate code • Enhancements via specialized annotations There’s more…
  • 12.
    Singleton Pattern @Singleton @ConcurrencyManagement(ConcurrencyManagementType.BEAN) public classLogger { @AccessTimeout(value = 30, unit=TimeUnit.SECONDS) @Lock(LockType.WRITE) public void addMessage(String message) {} @Lock(LockType.READ) public String getMessage() {} } •Container/bean managed concurrency
  • 13.
    The Good, Badand the Ugly •The Good: •enhancements via specialized annotations •startup behavioural characteristics •fine grain control over concurrency and access timeout •substantially less boilerplate code
  • 14.
    The Good, Badand the Ugly •The Bad: •overuse can cause problems •lazy loading causes delays •eager loading causes memory problems
  • 15.
    •And the ugly: •consideredan anti-pattern •only niche use •smarter to use a stateless session bean The Good, Bad and the Ugly
  • 16.
    Factory Pattern •Creational pattern •Interfacefor creating family of objects •Clients are decoupled from the creation
  • 17.
    Factory Pattern •CDI frameworkis a factory !?! public class CoffeeMachine implements DrinksMachine { // Implementation code } •Use it like so: @Inject DrinksMachine drinksMachine;
  • 18.
    Factory Pattern •Problem! Multipleconcrete implementations public class CoffeeMachine implements DrinksMachine { // Implementation code } public class SoftDrinksMachine implements DrinksMachine { // Implementation code } @Inject DrinksMachine drinksMachine; •Which DrinksMachine to inject? ?!?
  • 19.
    Factory Pattern •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
  • 20.
    Factory Pattern •Annotate respectiveclasses @Coffee public class CoffeeMachine implements DrinksMachine { // Implementation code } @SoftDrink public class SoftDrinksMachine implements DrinksMachine { // Implementation code }
  • 21.
    Factory Pattern •Annotate injectionpoints @Inject @SoftDrink DrinksMachine softDrinksMachine; @Inject @Coffee DrinksMachine coffeeDrinksMachine;
  • 22.
    Factory Pattern •Remember •Only JSR299beans are ‘injectable’ •But I want to inject a Collection type or Object with a parameterized constructor -> let’s dive deeper
  • 23.
    Factory Pattern •Dive deeper •Producer methods • Use it like so: @History @Produces public List<Book> getLibrary(){ // Generate a List of books called 'library' return library; } @History @Inject List<Books> library; @Qualifier @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD}) public @interface History
  • 24.
    Factory Pattern • Scope •Determines when method called • Life of object: @RequestScoped -> @ApplicationScoped @RequestScoped @History @Produces public List<Book> getLibrary(){ // Generate a List of books called 'library' return library; }
  • 25.
    The Good, Badand the Ugly •The Good: •easy to implement •no boilerplate code •works magically •any object can be made injectable
  • 26.
    The Good, Badand the Ugly •The Bad: named annotation is not type safe @Named("History") -> @History •and the ugly: object creation hidden, hard to follow execution flow, IDE should help
  • 27.
    Façade Pattern •Hides thecomplex logic and provides the interface for the client •Typically used in APIs •Classic implementation: Just create a method to hide complexity
  • 28.
    Façade Pattern •Encapsulates complicatedlogic • @Stateless, @Stateful@Stateless public class BankServiceFacade{ public void complexBusinessLogic(){ // Very very complex logic } } @Inject public BankServiceFacade service;
  • 29.
    The Good, Badand the Ugly •The Good: simple, robust, gives you a range of services •The Bad: over use introduces unnecessary layers, if you don’t need it don’t introduce one •and the ugly: there isn’t one really
  • 30.
    Decorator Pattern •Structural Pattern •Dynamicallyadds logic to an object at runtime •More flexible that inheritance •Classic implementation: Both the decorator and target object share the same interface. Decorator wraps the target object and adds its own behaviour
  • 31.
    Decorator Pattern @Decorator @Priority(Interceptor.Priority.APPLICATION) public classPriceDiscountDecorator implements Product { @Coffee @Any @Delegate @Inject private Product product; public String generateLabel() { product.setPrice(product.getPrice() * 0.5); return product.generateLabel(); } }
  • 32.
    •The Good: veryeasy to change behaviour without breaking legacy code •The Bad: needs XML config (<CDI 1.1) •and the ugly: overuse will introduce an execution flow which is hard to follow The Good, Bad and the Ugly
  • 33.
    Observer Pattern •Behavioural Pattern •Publisher-Subscriber •Classicimplementation: Implement a Subscriber interface, register with publisher and call a notify method on subscribers
  • 34.
    Observer Pattern •Define anevent class public class MessageEvent { private String message; public MessageEvent(String message){ this.message = message; } public String getMessage(){ return message; } }
  • 35.
    Observer Pattern •Notifies dependentsof state change @Stateless public class MessageService { @Inject Event<MessageEvent> messageEvent; public void fireMessage(){ messageEvent.fire(new MessageEvent("Hello World")); } }
  • 36.
    Observer Pattern •Dependent receivesstate change notification @Stateless public class MessageObserver { public void listenToMessage(@Observes MessageEvent message){ System.out.println(message.getMessage()); } }
  • 37.
    Observer Pattern •Qualifier tofilter events @WarningMessage @Inject Event<MessageEvent> messageEvent; public void listenToMessage( @Observes @WarningMessage MessageEvent message)
  • 38.
    The Good, Badand the Ugly •The Good: very easy, no boilerplate code, less than JMS, the container does the heavy lifting, light weight •The Bad: confusing execution order but IDE will help •and the ugly: nothing, its beautiful
  • 39.
    Entity •Lightweight domain objectwhich is persistable •Annotated with javax.persistence.Entity •Can represent relational data object/relational mapping annotations
  • 40.
    Entity @Entity public class Contact{ @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; private String firstName; private String lastName; }
  • 41.
    Final Conclusion •Efficiency savings •Greatercontrol over behaviour •New features enhance implementation
  • 42.
  • 43.
    Thank You Sep. 2-4 Kyiv,Desyatynna str. 12 @readlearncode Alex Theedom Senior Java Developer