Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Upcoming SlideShare
What to Upload to SlideShare
Next
Download to read offline and view in fullscreen.

Share

Effective Java with Groovy - How Language Influences Adoption of Good Practices

Download to read offline

Slides from my APACHECON@HOME 2020 talk - "Effective Java with Groovy - How Language Influences Adoption of Good Practices".

'Effective Java' presents the most effective ways of using language. However, the adoption of these practices among Java developers is less than satisfactory. In my observation, the effort required to implement them can be a barrier to the adoption of these practices. Since Groovy runs on JVM, most of the suggestions from Effective Java are equally relevant for Groovy developers. Groovy provides out of the box constructs for many of the recommended practices which can boost developer productivity. In this talk, I walk you through code examples that follow these good practices, highlighting the Groovy way of implementing the 'Effective Java' suggestions. As a participant, you walk away, appreciating the simplicity with which Groovy empowers the developers. The talk also provides food for thought - how a language can influence its users to adopt good practices. Java users learn the techniques a language can use to reduce the friction to adoption of good practices, instead of coming up with a prescription on how to implement good practices. Developers familiar with Groovy understand the reason behind the design of their favourite language features.

Related Books

Free with a 30 day trial from Scribd

See all

Related Audiobooks

Free with a 30 day trial from Scribd

See all
  • Be the first to like this

Effective Java with Groovy - How Language Influences Adoption of Good Practices

  1. 1. Effective Java With Groovy - How Language Influences Adoption of Good Practices Naresha K @naresha_k https://blog.nareshak.com/ APACHECON @HOME Spt, 29th – Oct. 1st 2020
  2. 2. About me Developer, Architect & Tech Excellence Coach Founder & Organiser Bangalore Groovy User Group
  3. 3. 3 Java Language JVM Platform/ Real Machine Platform/ Real Machine Platform/ Real Machine
  4. 4. 4 Java Language Platform/ Real Machine Platform/ Real Machine Platform/ Real Machine Groovy JVM
  5. 5. 5 Most people talk about Java the language, and this may sound odd coming from me, but I could hardly care less. At the core of the Java ecosystem is the JVM. - James Gosling, Creator of the Java Programming Language(2011, TheServerSide)
  6. 6. 6
  7. 7. initial idea was to make a little dynamic language which compiles directly to Java classes and provides all the nice (alleged) productivity benefits - James Strachan http://radio-weblogs.com/0112098/2003/08/29.html
  8. 8. Know your guides Context/ the Problem What does “Effective Java” say? The traps Groovier Solution Lessons Learned Tool Wisdom 9
  9. 9. float price = 0.1f; float total = 0; for(int i=0; i<10; i++){ total += price; } System.out.println("Total: " + total); Total: 1.0000001
  10. 10. double price = 0.1; double total = 0; for(int i=0; i<10; i++){ total += price; } System.out.println("Total: " + total); Total: 0.9999999999999999
  11. 11. #48: Avoid float and double if exact answers are required
  12. 12. BigDecimal price = new BigDecimal(0.1); BigDecimal total = new BigDecimal(0); for(int i=0; i<10; i++){ total = total.add(price); } System.out.println("Total: " + total); Total: 1.0000000000000000555111512312578270211815834045410156250
  13. 13. BigDecimal price = new BigDecimal(0.1); BigDecimal total = new BigDecimal(0); for(int i=0; i<10; i++){ total = total.add(price); } System.out.println("Total: " + total); Total: 1.0000000000000000555111512312578270211815834045410156250
  14. 14. def price = 0.1 def total = 0 for(int i=0; i<10; i++){ total += price } println "Total: " + total Total: 1.0
  15. 15. def price = 0.1 def total = 0 for(int i=0; i<10; i++){ total += price } println "Total: " + total println price.class println total.class Total: 1.0 class java.math.BigDecimal class java.math.BigDecimal
  16. 16. Select appropriate default Principle of Least Astonishment
  17. 17. class Product { String sku String description BigDecimal price }
  18. 18. Product book1 = new Product( sku: 'P101', description: 'Effective Java’, price: 40.0) Product book2 = new Product( sku: 'P101', description: 'Effective Java’, price: 40.0) println book1 == book2 false
  19. 19. Product book1 = new Product( sku: 'P101', description: 'Effective Java’, price: 40.0) Product book2 = new Product( sku: 'P101', description: 'Effective Java’, price: 40.0) def stock = [:] stock[book1] = 100 println stock[book2] null
  20. 20. #8: Obey the general contract when overriding equals #9: Always override hashCode when you override equals
  21. 21. class Product { String sku String description BigDecimal price } class Product { String sku String description BigDecimal price LocalDate dateOfManufacture } class Product { String sku String description BigDecimal price LocalDate dateOfManufacture LocalDate dateOfExpiry }
  22. 22. @EqualsAndHashCode class Product { String sku String description BigDecimal price }
  23. 23. Product book1 = new Product( sku: 'P101', description: 'Effective Java’, price: 40.0) Product book2 = new Product( sku: 'P101', description: 'Effective Java’, price: 40.0) println book1 == book2 true
  24. 24. Product book1 = new Product( sku: 'P101', description: 'Effective Java’, price: 40.0) Product book2 = new Product( sku: 'P101', description: 'Effective Java’, price: 40.0) def stock = [:] stock[book1] = 100 println stock[book2] 100
  25. 25. @EqualsAndHashCode(includes = 'id') class Product { Long id String sku String description BigDecimal price static constraints = { sku unique: true } }
  26. 26. @EqualsAndHashCode(includes = 'id') class Product { Long id String sku String description BigDecimal price static constraints = { sku unique: true } }
  27. 27. @EqualsAndHashCode(includes = ‘sku') class Product { Long id String sku String description BigDecimal price static constraints = { sku unique: true } }
  28. 28. AST Transformation Single point of representation of any knowledge
  29. 29. #46: Prefer for-each loops to traditional for loops
  30. 30. def numbers = [10, 20, 30, 40] def sum = 0 for(int number in numbers){ sum += number } println "Sum: " + sum
  31. 31. numbers.each { number -> println number } println numbers.collect { number -> number * 2 } println numbers.inject(0, { result, number -> result + number } ) 10 20 30 40 [20, 40, 60, 80] 100
  32. 32. Closures Favor Internal iterators to external iterators Minimise the moving parts
  33. 33. Billion Dollor Effort
  34. 34. Billion Dollor Effort null check
  35. 35. 40 List<Speaker> getSpeakers(String conference) { return null; } List<Speaker> speakers = getSpeakers(“ApacheCon@Home 2020“); if (speakers != null) { //... }
  36. 36. #43: Return empty arrays or collections, not nulls
  37. 37. println getSpeakers(‘ApacheCon@Home 2020') .collect { it.firstName } println getSpeakers(‘ApacheCon@Home 2020’) .findAll { it.firstName.length() > 5 }
  38. 38. println getSpeakers(‘ApacheCon@Home 2020') .collect { it.firstName } // [] println getSpeakers(‘ApacheCon@Home 2020’) .findAll { it.firstName.length() > 5 } // []
  39. 39. NullObject Pattern No boilerplate code - $$$ Life is too short for null checks!
  40. 40. https://www.flickr.com/photos/38080114@N07/8594601982/
  41. 41. #15: Minimize Mutability
  42. 42. Rules to make a class immutable 1. Don’t provide any mutators 2. Ensure that the class can’t be extended 3. Make all fields final 4. Make all fields private 5. Ensure exclusive access to any mutable components
  43. 43. class ImmutableClass{ private final def field1 private final def field2 //... private final def field10 public ImmutableClass(f1, f2,… f10){ //initialization } }
  44. 44. import groovy.transform.Immutable @Immutable class Rectangle{ int length int breadth } def r = new Rectangle(length: 10, breadth: 5) println r // Rectangle(10, 5)
  45. 45. public Rectangle(java.util.HashMap args) { if ( args .length == null) { } else { this .length = (( args .length) as int) } if ( args .breadth == null) { } else { this .breadth = (( args .breadth) as int) } }
  46. 46. AST Transformation Readability Matters Syntactic Sugar
  47. 47. #15: Favour composition over inheritance
  48. 48. def ph = ['919812312345', '4512341234', ‘19252199916'] as PhoneNumbers println ph.find { it == '19252199916'} println ph.findAll { it.endsWith('4') }
  49. 49. def ph = ['919812312345', '4512341234', ‘19252199916'] as PhoneNumbers println ph.find { it == '19252199916'} println ph.findAll { it.endsWith('4') } println ph.indianNumbers()
  50. 50. class PhoneNumbers extends ArrayList { }
  51. 51. class PhoneNumbers { private @Delegate List phoneNumbers PhoneNumbers(numbers) { phoneNumbers = numbers } def indianNumbers() { phoneNumbers.findAll { it.startsWith('91') } } }
  52. 52. Favoring Composition - The Groovy Way APACHECON @HOME Spt, 29th – Oct. 1st 2020
  53. 53. AST Transformation Simplify
  54. 54. #3: Enforce the singleton property with a private constructor or an enum type
  55. 55. class Manager { private static final Manager manager = new Manager() private Manager() { super() } static Manager getInstance() { manager } } def m1 = Manager.getInstance() def m2 = Manager.getInstance() println m1 == m2 true
  56. 56. class Manager { private static final Manager manager = new Manager() private Manager() { super() } static Manager getInstance() { manager } } def m1 = Manager.getInstance() def m2 = Manager.getInstance() println m1 == m2 true def m3 = new Manager() println m3 Manager@b968a76
  57. 57. @Singleton class Manager {} def m1 = Manager.getInstance() def m2 = Manager.getInstance() println m1 == m2 def m3 = new Manager() println m3 true Caught: java.lang.RuntimeException: Can't instantiate singleton Manager. Use Manager.instance
  58. 58. private static Manager manager static Manager getInstance() { if(!manager){ manager = new Manager() } manager }
  59. 59. private static Manager manager static synchronized Manager getInstance() { if(!manager){ manager = new Manager() } manager }
  60. 60. private static volatile Manager manager static synchronized Manager getInstance() { if(!manager){ manager = new Manager() } manager }
  61. 61. @Singleton(lazy=true) class Manager {} public static Manager getInstance() { if (instance != null) { return instance } else { synchronized (Manager) { if (instance != null) { return instance } else { return instance = new Manager() } } } }
  62. 62. AST Transformation YAGNI Premature optimisation is the root of all evil
  63. 63. Take Away Some of the ‘Effective Java’ already built into the language AST Transformations reduce the effort to implement few more Effective Java implementations may not always be effective Groovy implementations (Traps)
  64. 64. Take Away Programming languages can reduce the friction to implement good practices
  65. 65. Take Away The power of AST transformations is available to the developers
  66. 66. https://blog.nareshak.com/effective-java-with-groovy/
  67. 67. Thank You APACHECON @HOME Spt, 29th – Oct. 1st 2020

Slides from my APACHECON@HOME 2020 talk - "Effective Java with Groovy - How Language Influences Adoption of Good Practices". 'Effective Java' presents the most effective ways of using language. However, the adoption of these practices among Java developers is less than satisfactory. In my observation, the effort required to implement them can be a barrier to the adoption of these practices. Since Groovy runs on JVM, most of the suggestions from Effective Java are equally relevant for Groovy developers. Groovy provides out of the box constructs for many of the recommended practices which can boost developer productivity. In this talk, I walk you through code examples that follow these good practices, highlighting the Groovy way of implementing the 'Effective Java' suggestions. As a participant, you walk away, appreciating the simplicity with which Groovy empowers the developers. The talk also provides food for thought - how a language can influence its users to adopt good practices. Java users learn the techniques a language can use to reduce the friction to adoption of good practices, instead of coming up with a prescription on how to implement good practices. Developers familiar with Groovy understand the reason behind the design of their favourite language features.

Views

Total views

202

On Slideshare

0

From embeds

0

Number of embeds

7

Actions

Downloads

1

Shares

0

Comments

0

Likes

0

×