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

1,072 views

Published on

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.

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
1,072
On SlideShare
0
From Embeds
0
Number of Embeds
4
Actions
Shares
0
Downloads
15
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide
  • \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]

    1. 1. Getting the most out of Java Sebastian Zarnekow - Sven Efftinge itemis
    2. 2. Topics
    3. 3. TopicsConstruction of Data Objects
    4. 4. TopicsConstruction of Data Objects Dependency Injection
    5. 5. TopicsConstruction of Data Objects Dependency Injection Fluent Interfaces
    6. 6. TopicsConstruction of Data Objects Dependency Injection Fluent Interfaces Polymorphic Dispatch
    7. 7. TopicsConstruction of Data Objects Dependency Injection Fluent Interfaces Polymorphic Dispatch Annotation-based APIs
    8. 8. Java is getting old
    9. 9. Java is Ceremonial
    10. 10. Java is Ceremonialpublic String greeting(final String name) { return "Hello "+name+"!";}
    11. 11. Java is CeremonialPublic visibility should be defaultpublic String greeting(final String name) { return "Hello "+name+"!";}
    12. 12. Java is Ceremonialpublic String greeting(final String name) { return "Hello "+name+"!";}
    13. 13. Java is CeremonialLocal variables and arguments should be final by default public String greeting(final String name) { return "Hello "+name+"!"; }
    14. 14. Java is Ceremonialpublic String greeting(final String name) { return "Hello "+name+"!";}
    15. 15. Java is Ceremonial Return type can be inferredpublic String greeting(final String name) { return "Hello "+name+"!";}
    16. 16. Java is Ceremonialpublic String greeting(final String name) { return "Hello "+name+"!";}
    17. 17. Java is Ceremonialpublic String greeting(final String name) : return "Hello "+name+"!";}
    18. 18. Java is Ceremonialpublic String greeting(final String name) { return "Hello "+name+"!";}greeting(String name) : "Hello "+name+"!";
    19. 19. Java’s Syntax is Inflexible
    20. 20. Java’s Syntax is InflexibleAll infix operators work for built-in types only.
    21. 21. Java’s Syntax is InflexibleAll infix operators work for built-in types only. 2 / 4 * 13;
    22. 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. 23. Java lacks Closures
    24. 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. 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. 26. ...but Java is also great!
    27. 27. ...but Java is also great!•Lots of developers
    28. 28. ...but Java is also great!•Lots of developers•JVM is a great platform
    29. 29. ...but Java is also great!•Lots of developers•JVM is a great platform•Big open-source community
    30. 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. 31. What can we do about the “not-so-nice things” in Java?
    32. 32. Object Instantiation
    33. 33. Object Categories
    34. 34. Object Categories• Short Living, Data Objects
    35. 35. Object Categories• Short Living, Data Objects • Collections (ArrayList, HashSet, Iterator)
    36. 36. Object Categories• Short Living, Data Objects • Collections (ArrayList, HashSet, Iterator) • Immutable Objects (BigInteger, String)
    37. 37. Object Categories• Short Living, Data Objects • Collections (ArrayList, HashSet, Iterator) • Immutable Objects (BigInteger, String) • Others (LayoutManager, Runnables)
    38. 38. Object Categories• Short Living, Data Objects • Collections (ArrayList, HashSet, Iterator) • Immutable Objects (BigInteger, String) • Others (LayoutManager, Runnables)• Components
    39. 39. Object Categories• Short Living, Data Objects • Collections (ArrayList, HashSet, Iterator) • Immutable Objects (BigInteger, String) • Others (LayoutManager, Runnables)• Components • Singletons (ConnectionPool, Scheduler, ...)
    40. 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. 41. Construction ofData Objects
    42. 42. Construction of Data Objects• Convenience
    43. 43. Construction of Data Objects• Convenience• Readability
    44. 44. Construction of Data Objects• Convenience• ReadabilityMap<String,Foo> foos = new HashMap<String, Foo>();
    45. 45. Use Type InferenceMap<String,Foo> foos = new HashMap<String, Foo>();
    46. 46. Use Type InferenceMap<String,Foo> foos = new HashMap<String, Foo>();Map<String,Foo> foos = Maps.newHashMap();
    47. 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. 48. Use Static ImportsMap<String,Foo> foos = Maps.newHashMap();
    49. 49. Use Static ImportsMap<String,Foo> foos = Maps.newHashMap();Map<String,Foo> foos = newHashMap();
    50. 50. Use Static ImportsMap<String,Foo> foos = Maps.newHashMap();import static com.google.common.collect.Maps.*;...Map<String,Foo> foos = newHashMap();
    51. 51. Use Var ArgsList<String> names = newArrayList();names.add("Foo");names.add("Bar");names.add("Baz");
    52. 52. Use Var ArgsList<String> names = newArrayList();names.add("Foo");names.add("Bar");names.add("Baz");List<String> names = newArrayList("Foo","Bar","Baz");
    53. 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. 54. Component Instantiation - Classical Approach -
    55. 55. Constructor Invocation
    56. 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. 57. Constructor Invocation Shortener shortener = new TinyUrlShortener(); Tweeter tweeter = new SmsTweeter();
    58. 58. Constructor Invocation• Strong Dependencies• Not Testable Shortener shortener = new TinyUrlShortener(); Tweeter tweeter = new SmsTweeter();
    59. 59. Component Instantiation- Dependency Injection -
    60. 60. Constructor Parameters
    61. 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. 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. 63. Constructor Parameters ... Have Advantages
    64. 64. Constructor Parameters ... Have Advantages• Components Depend on Interfaces
    65. 65. Constructor Parameters ... Have Advantages• Components Depend on Interfaces• Testable Code
    66. 66. Constructor Parameters ... Have Advantages• Components Depend on Interfaces• Testable Code• Dependencies are No Longer Burried in the Core of Your Application
    67. 67. Constructor Parameters ... Leave the Burden to the Client
    68. 68. Constructor Parameters ... Leave the Burden to the ClientHttpConnection http = new HttpConnection(“..”);
    69. 69. Constructor Parameters ... Leave the Burden to the ClientHttpConnection http = new HttpConnection(“..”);SoapConnection soap = new SoapConnection(http);
    70. 70. Constructor Parameters ... Leave the Burden to the ClientHttpConnection http = new HttpConnection(“..”);SoapConnection soap = new SoapConnection(http);Shortener shortener = new TinyUrlShortener(soap);
    71. 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. 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. 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. 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. 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. 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. 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. 78. Remember This?
    79. 79. Encapsulated Dependenciesclass TweetModule extends AbstractModule { protected void configure() { bind(Shortener.class).to(TinyUrlShortener.class); bind(Tweeter.class).to(SmsTweeter.class); }}
    80. 80. Modern APIDesign
    81. 81. Modern APIDesign Easy To Use
    82. 82. Modern APIDesign Easy To Use Consistent
    83. 83. Modern APIDesign Easy To Use Consistent Hard To Misuse
    84. 84. Modern APIDesign Easy To Use Consistent Hard To Misuse Easy To Read !
    85. 85. Half-caf ventinon-fat Latte to go.
    86. 86. Half-caf ventinon-fat Latte to go.
    87. 87. Fluent InterfacesHalf-caf ventinon-fat Latte to go.
    88. 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. 89. Fluent InterfacesCoffee coffee = new Latte() .venti() .halfCaf() .nonFat() .prepare(TO_GO);
    90. 90. Fluent InterfacesChained Method-Calls That Read LikeNatural Language
    91. 91. Fluent InterfacesChained Method-Calls That Read LikeNatural Language http://www.wikihow.com/Order-at-Starbucks
    92. 92. Fluent InterfacesStringBuilder builder = ..;return builder .append(“The result is “) .append(result) .append(‘.’) .toString();
    93. 93. Fluent InterfacesHow To:
    94. 94. Fluent Interfaces How To:1. Methods Modify Internal State and
    95. 95. Fluent Interfaces How To:1. Methods Modify Internal State and2. Return self or new Object
    96. 96. Fluent Interfaces How To:1. Methods Modify Internal State and2. Return self or new Object3. Until Result is Returned
    97. 97. Fluent InterfacesExamples: Guice Binder API bind(Service.class) .to(Implementation.class) .in(Scopes.REQUEST);
    98. 98. Fluent Interfaces Examples: EasyMockLinkedList mocked = mock(LinkedList.class);when(mocked.get(0)).thenReturn(“first”);
    99. 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. 100. Fluent Interfaces Examples: Google Guava MapMaker With ClosuresConcurrentMap<Key, Value> map = new MapMaker() .softKeys() .weakValues() .expiration(30, MINUTES) .makeComputingMap(k|createExpensiveValue(k));
    101. 101. Visitor Pattern (GoF) ... separating an algorithmfrom an object structure it operates on...
    102. 102. Polymorphic Dispatching
    103. 103. Polymorphic Dispatching Visitor visitor = new ExternalVisitor(); visitor.visit(car); visitor.visit(bus); visitor.visit(engine); visitor.visit(wheel);
    104. 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. 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. 106. Polymorphic Dispatching• Non Invasive External Visitor
    107. 107. Polymorphic Dispatching• Non Invasive External Visitor• Handle Arbitrary Object Graphs
    108. 108. Polymorphic Dispatching• Non Invasive External Visitor• Handle Arbitrary Object Graphs• Eliminate if-instanceof-else Cascades
    109. 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. 110. Annotation-based APIs
    111. 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. 112. Annotation-based APIs@Action(“Exit”, mnemonic=”E”, desc=”Exit App”)public void exit(ActionEvent e) { System.exit(0);}
    113. 113. Annotation-based APIs Examples: Property Change Events@PropertyChangeListener({“size”})public void invalidateLayout(PropertyChangeEvent e) { ..}@PropertyChangeListener({“value”, “selectedItem”})public void revalidate(PropertyChangeEvent e) { ..}
    114. 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. 115. Annotation-based APIs • More Concise Code
    116. 116. Annotation-based APIs • More Concise Code • Avoid Anonymous Classes
    117. 117. Annotation-based APIs • More Concise Code • Avoid Anonymous Classes • Easier to Understand
    118. 118. Annotation-based APIs • More Concise Code • Avoid Anonymous Classes • Easier to Understand • Less Code to Maintain
    119. 119. Annotation-based APIs • More Concise Code • Avoid Anonymous Classes • Easier to Understand • Less Code to Maintain • Method can be overwritten (Extensibility, Testability)
    120. 120. Recab
    121. 121. RecabConstruction of Data Objects
    122. 122. RecabConstruction of Data Objects Dependency Injection
    123. 123. RecabConstruction of Data Objects Dependency Injection Fluent Interfaces
    124. 124. RecabConstruction of Data Objects Dependency Injection Fluent Interfaces Polymorphic Dispatch
    125. 125. RecabConstruction of Data Objects Dependency Injection Fluent Interfaces Polymorphic Dispatch Annotation-based APIs
    126. 126. The Good News?• One Day Java May Have
    127. 127. The Good News?• One Day Java May Have • Closures (Java 8 - JSR 335)
    128. 128. The Good News?• One Day Java May Have • Closures (Java 8 - JSR 335) • Improved Type Inference (Java 7 - JSR 334)
    129. 129. The Good News?• One Day Java May Have • Closures (Java 8 - JSR 335) • Improved Type Inference (Java 7 - JSR 334) • ...
    130. 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. 131. Thanks.

    ×