Getting the most out of Java [Nordic Coding-2010]
Upcoming SlideShare
Loading in...5
×
 

Like this? Share it with your network

Share

Getting the most out of Java [Nordic Coding-2010]

on

  • 913 views

In this talk we explain how we use the more recent concepts of the Java programming language in order to improve readability and maintainability of our code.

In this talk we explain how we use the more recent concepts of the Java programming language in order to improve readability and maintainability of our code.

Statistics

Views

Total Views
913
Views on SlideShare
913
Embed Views
0

Actions

Likes
0
Downloads
13
Comments
0

0 Embeds 0

No embeds

Accessibility

Categories

Upload Details

Uploaded via as Apple Keynote

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n

Getting the most out of Java [Nordic Coding-2010] Presentation Transcript

  • 1. Getting the most out of Java Sebastian Zarnekow - Sven Efftinge itemis
  • 2. Topics
  • 3. TopicsConstruction of Data Objects
  • 4. TopicsConstruction of Data Objects Dependency Injection
  • 5. TopicsConstruction of Data Objects Dependency Injection Fluent Interfaces
  • 6. TopicsConstruction of Data Objects Dependency Injection Fluent Interfaces Polymorphic Dispatch
  • 7. TopicsConstruction of Data Objects Dependency Injection Fluent Interfaces Polymorphic Dispatch Annotation-based APIs
  • 8. Java is getting old
  • 9. Java is Ceremonial
  • 10. Java is Ceremonialpublic String greeting(final String name) { return "Hello "+name+"!";}
  • 11. Java is CeremonialPublic visibility should be defaultpublic String greeting(final String name) { return "Hello "+name+"!";}
  • 12. Java is Ceremonialpublic String greeting(final String name) { return "Hello "+name+"!";}
  • 13. Java is CeremonialLocal variables and arguments should be final by default public String greeting(final String name) { return "Hello "+name+"!"; }
  • 14. Java is Ceremonialpublic String greeting(final String name) { return "Hello "+name+"!";}
  • 15. Java is Ceremonial Return type can be inferredpublic String greeting(final String name) { return "Hello "+name+"!";}
  • 16. Java is Ceremonialpublic String greeting(final String name) { return "Hello "+name+"!";}
  • 17. Java is Ceremonialpublic String greeting(final String name) : return "Hello "+name+"!";}
  • 18. Java is Ceremonialpublic String greeting(final String name) { return "Hello "+name+"!";}greeting(String name) : "Hello "+name+"!";
  • 19. Java’s Syntax is Inflexible
  • 20. Java’s Syntax is InflexibleAll infix operators work for built-in types only.
  • 21. Java’s Syntax is InflexibleAll infix operators work for built-in types only. 2 / 4 * 13;
  • 22. Java’s Syntax is InflexibleAll infix operators work for built-in types only. 2 / 4 * 13; new BigDecimal(2) .divide(new BigDecimal(4)) .multiply(new BigDecimal(13));
  • 23. Java lacks Closures
  • 24. Java lacks Closures Working with collections in Java (i.e. without closures): public List<String> fourLetterWords(List<String> words) { List<String> fourLetterWords = Lists.newArrayList(); for (String string : words) { if (string.length()==4) fourLetterWords.add(string); } return fourLetterWords; }
  • 25. Java lacks Closures Working with collections in Java (i.e. with closures): public List<String> fourLetterWords(List<String> words) { return words.select(#{s->s.length()==4}); }
  • 26. ...but Java is also great!
  • 27. ...but Java is also great!•Lots of developers
  • 28. ...but Java is also great!•Lots of developers•JVM is a great platform
  • 29. ...but Java is also great!•Lots of developers•JVM is a great platform•Big open-source community
  • 30. ...but Java is also great!•Lots of developers•JVM is a great platform•Big open-source community•Leading edge tooling (Eclipse, IntelliJ IDEA)
  • 31. What can we do about the “not-so-nice things” in Java?
  • 32. Object Instantiation
  • 33. Object Categories
  • 34. Object Categories• Short Living, Data Objects
  • 35. Object Categories• Short Living, Data Objects • Collections (ArrayList, HashSet, Iterator)
  • 36. Object Categories• Short Living, Data Objects • Collections (ArrayList, HashSet, Iterator) • Immutable Objects (BigInteger, String)
  • 37. Object Categories• Short Living, Data Objects • Collections (ArrayList, HashSet, Iterator) • Immutable Objects (BigInteger, String) • Others (LayoutManager, Runnables)
  • 38. Object Categories• Short Living, Data Objects • Collections (ArrayList, HashSet, Iterator) • Immutable Objects (BigInteger, String) • Others (LayoutManager, Runnables)• Components
  • 39. Object Categories• Short Living, Data Objects • Collections (ArrayList, HashSet, Iterator) • Immutable Objects (BigInteger, String) • Others (LayoutManager, Runnables)• Components • Singletons (ConnectionPool, Scheduler, ...)
  • 40. Object Categories• Short Living, Data Objects • Collections (ArrayList, HashSet, Iterator) • Immutable Objects (BigInteger, String) • Others (LayoutManager, Runnables)• Components • Singletons (ConnectionPool, Scheduler, ...) • Services (URLValidator, BillingService, ...)
  • 41. Construction ofData Objects
  • 42. Construction of Data Objects• Convenience
  • 43. Construction of Data Objects• Convenience• Readability
  • 44. Construction of Data Objects• Convenience• ReadabilityMap<String,Foo> foos = new HashMap<String, Foo>();
  • 45. Use Type InferenceMap<String,Foo> foos = new HashMap<String, Foo>();
  • 46. Use Type InferenceMap<String,Foo> foos = new HashMap<String, Foo>();Map<String,Foo> foos = Maps.newHashMap();
  • 47. Use Type InferenceMap<String,Foo> foos = new HashMap<String, Foo>();Map<String,Foo> foos = Maps.newHashMap();public static <K, V> HashMap<K, V> newHashMap() { return new HashMap<K, V>();}
  • 48. Use Static ImportsMap<String,Foo> foos = Maps.newHashMap();
  • 49. Use Static ImportsMap<String,Foo> foos = Maps.newHashMap();Map<String,Foo> foos = newHashMap();
  • 50. Use Static ImportsMap<String,Foo> foos = Maps.newHashMap();import static com.google.common.collect.Maps.*;...Map<String,Foo> foos = newHashMap();
  • 51. Use Var ArgsList<String> names = newArrayList();names.add("Foo");names.add("Bar");names.add("Baz");
  • 52. Use Var ArgsList<String> names = newArrayList();names.add("Foo");names.add("Bar");names.add("Baz");List<String> names = newArrayList("Foo","Bar","Baz");
  • 53. Use Var ArgsList<String> names = newArrayList();names.add("Foo");names.add("Bar");names.add("Baz");List<String> names = newArrayList("Foo","Bar","Baz");public static <E> ArrayList<E> newArrayList(E... elements) { ...}
  • 54. Component Instantiation - Classical Approach -
  • 55. Constructor Invocation
  • 56. Constructor Invocation public class TwitterClient { void send(String message) { if (message.length() > 140) { Shortener shortener = new TinyUrlShortener(); message = shortener.shorten(message); } if (message.length() <= 140) { Tweeter tweeter = new SmsTweeter(); tweeter.send(message); } } }
  • 57. Constructor Invocation Shortener shortener = new TinyUrlShortener(); Tweeter tweeter = new SmsTweeter();
  • 58. Constructor Invocation• Strong Dependencies• Not Testable Shortener shortener = new TinyUrlShortener(); Tweeter tweeter = new SmsTweeter();
  • 59. Component Instantiation- Dependency Injection -
  • 60. Constructor Parameters
  • 61. Constructor Parameterspublic class TwitterClient { private Shortener shortener; private Tweeter tweeter; public TwitterClient(Shortener shortener, Tweeter tweeter) { this.shortener = shortener; this.tweeter = tweeter; } void send(String message) { if (message.length() > 140) { message = shortener.shorten(message); } if (message.length() <= 140) { tweeter.send(message); } }}
  • 62. Constructor Parameters// Initialize the component graphShortener shortener = new TinyUrlShortener();Tweeter tweeter = new SmsTweeter();TwitterClient client = new TwitterClient(shortener, tweeter);// Do Something meaningfulclient.send(“Hello World”);
  • 63. Constructor Parameters ... Have Advantages
  • 64. Constructor Parameters ... Have Advantages• Components Depend on Interfaces
  • 65. Constructor Parameters ... Have Advantages• Components Depend on Interfaces• Testable Code
  • 66. Constructor Parameters ... Have Advantages• Components Depend on Interfaces• Testable Code• Dependencies are No Longer Burried in the Core of Your Application
  • 67. Constructor Parameters ... Leave the Burden to the Client
  • 68. Constructor Parameters ... Leave the Burden to the ClientHttpConnection http = new HttpConnection(“..”);
  • 69. Constructor Parameters ... Leave the Burden to the ClientHttpConnection http = new HttpConnection(“..”);SoapConnection soap = new SoapConnection(http);
  • 70. Constructor Parameters ... Leave the Burden to the ClientHttpConnection http = new HttpConnection(“..”);SoapConnection soap = new SoapConnection(http);Shortener shortener = new TinyUrlShortener(soap);
  • 71. Constructor Parameters ... Leave the Burden to the ClientHttpConnection http = new HttpConnection(“..”);SoapConnection soap = new SoapConnection(http);Shortener shortener = new TinyUrlShortener(soap);AndroidSmsSender sender = new AndroidSmsSender();
  • 72. Constructor Parameters ... Leave the Burden to the ClientHttpConnection http = new HttpConnection(“..”);SoapConnection soap = new SoapConnection(http);Shortener shortener = new TinyUrlShortener(soap);AndroidSmsSender sender = new AndroidSmsSender();Tweeter tweeter = new SmsTweeter(sender);
  • 73. Constructor Parameters ... Leave the Burden to the ClientHttpConnection http = new HttpConnection(“..”);SoapConnection soap = new SoapConnection(http);Shortener shortener = new TinyUrlShortener(soap);AndroidSmsSender sender = new AndroidSmsSender();Tweeter tweeter = new SmsTweeter(sender);TwitterClient client = new TwitterClient(shortener, tweeter);
  • 74. Constructor Parameters ... Leave the Burden to the ClientHttpConnection http = new HttpConnection(“..”);SoapConnection soap = new SoapConnection(http);Shortener shortener = new TinyUrlShortener(soap);AndroidSmsSender sender = new AndroidSmsSender();Tweeter tweeter = new SmsTweeter(sender);TwitterClient client = new TwitterClient(shortener, tweeter);client.send(“Hello World”);
  • 75. Constructor Parameters ... Revisitedpublic class TwitterClient { private Shortener shortener; private Tweeter tweeter; public TwitterClient(Shortener shortener, Tweeter tweeter) { this.shortener = shortener; this.tweeter = tweeter; } void send(String message) { .. }}
  • 76. Constructor Parameters ... Revisitedpublic class TwitterClient { private Shortener shortener; private Tweeter tweeter; @Inject public TwitterClient(Shortener shortener, Tweeter tweeter) { this.shortener = shortener; this.tweeter = tweeter; } void send(String message) { .. }}
  • 77. Constructor Parameters ... Revisited// Initialize the component graphInjector i = Guice.createInjector(new TweetModule());// Obtain main componentTwitterClient client = i.getInstance(TwitterClient.class);// Do something meaningfulclient.send(“Hello Guice!”);
  • 78. Remember This?
  • 79. Encapsulated Dependenciesclass TweetModule extends AbstractModule { protected void configure() { bind(Shortener.class).to(TinyUrlShortener.class); bind(Tweeter.class).to(SmsTweeter.class); }}
  • 80. Modern APIDesign
  • 81. Modern APIDesign Easy To Use
  • 82. Modern APIDesign Easy To Use Consistent
  • 83. Modern APIDesign Easy To Use Consistent Hard To Misuse
  • 84. Modern APIDesign Easy To Use Consistent Hard To Misuse Easy To Read !
  • 85. Half-caf ventinon-fat Latte to go.
  • 86. Half-caf ventinon-fat Latte to go.
  • 87. Fluent InterfacesHalf-caf ventinon-fat Latte to go.
  • 88. Fluent InterfacesCoffeeOrder order = new Latte();order.setSize(Size.VENTI);order.setCaffeine(Caffeine.HALF);order.setMilk(MilkType.NONFAT);order.setFoam(false);Coffee coffee = order.prepare(true);
  • 89. Fluent InterfacesCoffee coffee = new Latte() .venti() .halfCaf() .nonFat() .prepare(TO_GO);
  • 90. Fluent InterfacesChained Method-Calls That Read LikeNatural Language
  • 91. Fluent InterfacesChained Method-Calls That Read LikeNatural Language http://www.wikihow.com/Order-at-Starbucks
  • 92. Fluent InterfacesStringBuilder builder = ..;return builder .append(“The result is “) .append(result) .append(‘.’) .toString();
  • 93. Fluent InterfacesHow To:
  • 94. Fluent Interfaces How To:1. Methods Modify Internal State and
  • 95. Fluent Interfaces How To:1. Methods Modify Internal State and2. Return self or new Object
  • 96. Fluent Interfaces How To:1. Methods Modify Internal State and2. Return self or new Object3. Until Result is Returned
  • 97. Fluent InterfacesExamples: Guice Binder API bind(Service.class) .to(Implementation.class) .in(Scopes.REQUEST);
  • 98. Fluent Interfaces Examples: EasyMockLinkedList mocked = mock(LinkedList.class);when(mocked.get(0)).thenReturn(“first”);
  • 99. Fluent Interfaces Examples: Google Guava MapMakerConcurrentMap<Key, Value> map = new MapMaker() .softKeys() .weakValues() .expiration(30, MINUTES) .makeComputingMap( new Function<Key, Value>() { public Value apply(Key key) { return createExpensiveValue(key); } });
  • 100. Fluent Interfaces Examples: Google Guava MapMaker With ClosuresConcurrentMap<Key, Value> map = new MapMaker() .softKeys() .weakValues() .expiration(30, MINUTES) .makeComputingMap(k|createExpensiveValue(k));
  • 101. Visitor Pattern (GoF) ... separating an algorithmfrom an object structure it operates on...
  • 102. Polymorphic Dispatching
  • 103. Polymorphic Dispatching Visitor visitor = new ExternalVisitor(); visitor.visit(car); visitor.visit(bus); visitor.visit(engine); visitor.visit(wheel);
  • 104. Polymorphic Dispatching class ExternalVisitor { String visit(Object o) { if (o instanceof Bus) { .. } else if (o instanceof Car) { .. } else if (o instanceof Engine) { .. } else .. } }
  • 105. Polymorphic DispatchingDispatcher dispatcher = new Dispatcher(this, “doVisit”);String visit(Object o) { return dispatcher.dispatch(o);}String doVisit(Bus b) {return “Bus: ” + print(b.getParts());}String doVisit(Car c) {return “Car: ” + print(c.getParts());}String doVisit(Engine e) { ... }String doVisit(Collection<?> parts) { ... }
  • 106. Polymorphic Dispatching• Non Invasive External Visitor
  • 107. Polymorphic Dispatching• Non Invasive External Visitor• Handle Arbitrary Object Graphs
  • 108. Polymorphic Dispatching• Non Invasive External Visitor• Handle Arbitrary Object Graphs• Eliminate if-instanceof-else Cascades
  • 109. Polymorphic Dispatching• Non Invasive External Visitor• Handle Arbitrary Object Graphs• Eliminate if-instanceof-else Cascades• Dispatch According to Runtime Type of Arguments (Like switch-Statement on Types)
  • 110. Annotation-based APIs
  • 111. Annotation-based APIsaddAction(new AbstractAction(“Exit”) { { putValue(MNEMONIC_KEY, “E”); putValue(SHORT_DESCRIPTION, “Exit App”); } public void actionPerformed(ActionEvent e) { System.exit(0); }});
  • 112. Annotation-based APIs@Action(“Exit”, mnemonic=”E”, desc=”Exit App”)public void exit(ActionEvent e) { System.exit(0);}
  • 113. Annotation-based APIs Examples: Property Change Events@PropertyChangeListener({“size”})public void invalidateLayout(PropertyChangeEvent e) { ..}@PropertyChangeListener({“value”, “selectedItem”})public void revalidate(PropertyChangeEvent e) { ..}
  • 114. Annotation-based APIs Examples: Validation@Validate(OnSave, nullIsOk=true, property=”EMail”)ValidationResult matchesPattern(String s) { if (!s.matches(PATTERN)) { return ValidationResult.createError(..); } return OK;}
  • 115. Annotation-based APIs • More Concise Code
  • 116. Annotation-based APIs • More Concise Code • Avoid Anonymous Classes
  • 117. Annotation-based APIs • More Concise Code • Avoid Anonymous Classes • Easier to Understand
  • 118. Annotation-based APIs • More Concise Code • Avoid Anonymous Classes • Easier to Understand • Less Code to Maintain
  • 119. Annotation-based APIs • More Concise Code • Avoid Anonymous Classes • Easier to Understand • Less Code to Maintain • Method can be overwritten (Extensibility, Testability)
  • 120. Recab
  • 121. RecabConstruction of Data Objects
  • 122. RecabConstruction of Data Objects Dependency Injection
  • 123. RecabConstruction of Data Objects Dependency Injection Fluent Interfaces
  • 124. RecabConstruction of Data Objects Dependency Injection Fluent Interfaces Polymorphic Dispatch
  • 125. RecabConstruction of Data Objects Dependency Injection Fluent Interfaces Polymorphic Dispatch Annotation-based APIs
  • 126. The Good News?• One Day Java May Have
  • 127. The Good News?• One Day Java May Have • Closures (Java 8 - JSR 335)
  • 128. The Good News?• One Day Java May Have • Closures (Java 8 - JSR 335) • Improved Type Inference (Java 7 - JSR 334)
  • 129. The Good News?• One Day Java May Have • Closures (Java 8 - JSR 335) • Improved Type Inference (Java 7 - JSR 334) • ...
  • 130. The Good News?• One Day Java May Have • Closures (Java 8 - JSR 335) • Improved Type Inference (Java 7 - JSR 334) • ...• Due 2011 & 2012
  • 131. Thanks.