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.

Effective Java with Groovy - How Language can Influence Good Practices

144 views

Published on

Slide from my GIDS 2019 talk - Effective Java with Groovy - How Language can Influence Good Practices among Developers.

Published in: Software
  • DOWNLOAD THE BOOK INTO AVAILABLE FORMAT (New Update) ......................................................................................................................... ......................................................................................................................... Download Full PDF EBOOK here { https://urlzs.com/UABbn } ......................................................................................................................... Download Full EPUB Ebook here { https://urlzs.com/UABbn } ......................................................................................................................... Download Full doc Ebook here { https://urlzs.com/UABbn } ......................................................................................................................... Download PDF EBOOK here { https://urlzs.com/UABbn } ......................................................................................................................... Download EPUB Ebook here { https://urlzs.com/UABbn } ......................................................................................................................... Download doc Ebook here { https://urlzs.com/UABbn } ......................................................................................................................... ......................................................................................................................... ................................................................................................................................... eBook is an electronic version of a traditional print book THE can be read by using a personal computer or by using an eBook reader. (An eBook reader can be a software application for use on a computer such as Microsoft's free Reader application, or a book-sized computer THE is used solely as a reading device such as Nuvomedia's Rocket eBook.) Users can purchase an eBook on diskette or CD, but the most popular method of getting an eBook is to purchase a downloadable file of the eBook (or other reading material) from a Web site (such as Barnes and Noble) to be read from the user's computer or reading device. Generally, an eBook can be downloaded in five minutes or less ......................................................................................................................... .............. Browse by Genre Available eBOOK .............................................................................................................................. Art, Biography, Business, Chick Lit, Children's, Christian, Classics, Comics, Contemporary, CookBOOK, Manga, Memoir, Music, Mystery, Non Fiction, Paranormal, Philosophy, Poetry, Psychology, Religion, Romance, Science, Science Fiction, Self Help, Suspense, Spirituality, Sports, Thriller, Travel, Young Adult, Crime, EBOOK, Fantasy, Fiction, Graphic Novels, Historical Fiction, History, Horror, Humor And Comedy, ......................................................................................................................... ......................................................................................................................... .....BEST SELLER FOR EBOOK RECOMMEND............................................................. ......................................................................................................................... Blowout: Corrupted Democracy, Rogue State Russia, and the Richest, Most Destructive Industry on Earth,-- The Ride of a Lifetime: Lessons Learned from 15 Years as CEO of the Walt Disney Company,-- Call Sign Chaos: Learning to Lead,-- StrengthsFinder 2.0,-- Stillness Is the Key,-- She Said: Breaking the Sexual Harassment Story THE Helped Ignite a Movement,-- Atomic Habits: An Easy & Proven Way to Build Good Habits & Break Bad Ones,-- Everything Is Figureoutable,-- What It Takes: Lessons in the Pursuit of Excellence,-- Rich Dad Poor Dad: What the Rich Teach Their Kids About Money THE the Poor and Middle Class Do Not!,-- The Total Money Makeover: Classic Edition: A Proven Plan for Financial Fitness,-- Shut Up and Listen!: Hard Business Truths THE Will Help You Succeed, ......................................................................................................................... .........................................................................................................................
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • Be the first to like this

Effective Java with Groovy - How Language can Influence Good Practices

  1. 1. Effective Java with Groovy - How language can Influence Good Practices Naresha K, Technical Excellence Coach | Consultant | Agile & Cloud Transformation Catalyst @naresha_k https://blog.nareshak.com/
  2. 2. About Me
  3. 3. http://nareshak.blogspot.com/
  4. 4. http://nareshak.blogspot.com/
  5. 5. !7 https://www.flickr.com/photos/hchalkley/30724738
  6. 6. !8 Data Information Knowledge Wisdom
  7. 7. !9 https://www.flickr.com/photos/drauh/2456223489
  8. 8. !10
  9. 9. !11http://radio-weblogs.com/0112098/2003/08/29.html 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
  10. 10. Know Your Path The problem/ Context What does ‘Effective Java’ say? The traps Groovier Solution Lessons Learned !12 Tool Wisdom
  11. 11. !13 https://www.flickr.com/photos/twid/410697715
  12. 12. !14 class Product { Long id String code String name BigDecimal price static constraints = { code unique: true } }
  13. 13. P #1 !15 def actionE1(){ Product p = new Product(code: 'P101', name: 'Effective Java', price: 499.00) p.save(flush: true) render p } def actionE2(){ Product p = new Product(code: 'P101', name: 'Effective Java', price: 499.00) Product p2 = Product.findByCode('P101') render p == p2 } false
  14. 14. P #2 !16 def actionH1(){ Product p = new Product(code: 'P102', name: 'Programming Groovy 2', price: 2217.78) p.save(flush: true) def stock = [:] stock[p] = 100 session.setAttribute('stock', stock) render stock } def actionH2(){ def stock = session.getAttribute('stock') println stock Product p = new Product(code: 'P102', name: 'Programming Groovy 2', price: 2217.78) render stock[p] } null
  15. 15. !17
  16. 16. !18 #8: Obey the general contract when overriding equals #9: Always override hashCode when you override equals
  17. 17. !19 import groovy.transform.EqualsAndHashCode @EqualsAndHashCode(includes='id') class Product { Long id String code String name BigDecimal price static constraints = { code unique: true } }
  18. 18. !20 import groovy.transform.EqualsAndHashCode @EqualsAndHashCode(includes=‘code') class Product { Long id String code String name BigDecimal price static constraints = { code unique: true } }
  19. 19. P #1 !21 def actionE1(){ Product p = new Product(code: 'P101', name: 'Effective Java', price: 499.00) p.save(flush: true) render p } def actionE2(){ Product p = new Product(code: 'P101', name: 'Effective Java', price: 499.00) Product p2 = Product.findByCode('P101') render p == p2 } true
  20. 20. P #2 !22 def actionH1(){ Product p = new Product(code: 'P102', name: 'Programming Groovy 2', price: 2217.78) p.save(flush: true) def stock = [:] stock[p] = 100 session.setAttribute('stock', stock) render stock } def actionH2(){ def stock = session.getAttribute('stock') println stock Product p = new Product(code: 'P102', name: 'Programming Groovy 2', price: 2217.78) render stock[p] } 100
  21. 21. !23 AST Transformation Single point of representation for any knowledge
  22. 22. !24 List<Integer> numbers = Arrays.asList(10, 20, 30, 40); for(int i=0; i<numbers.size(); i++){ System.out.println(numbers.get(i)); }
  23. 23. !25 http://upload.wikimedia.org/wikipedia/commons/8/82/Cable_closet_bh.jpg
  24. 24. !26 #46: Prefer for-each loops to traditional for loops
  25. 25. !27 def numbers = [10, 20, 30, 40] def sum = 0 for(int number in numbers){ sum += number } println "Sum: " + sum
  26. 26. !28 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
  27. 27. !29 Closures Favor Internal iterators to external iterators Minimize the moving parts in your code
  28. 28. !30 public static void main( String[] args ) { float price = 0.1f; float total = 0; for(int i=0; i<10; i++){ total += price; } System.out.println("Total: " + total); } Total: 1.0000001
  29. 29. !31 public static void main( String[] args ) { double price = 0.1; double total = 0; for(int i=0; i<10; i++){ total += price; } System.out.println("Total: " + total); } Total: 0.9999999999999999
  30. 30. !32 #48: Avoid float and double if exact answers are required
  31. 31. !33 public static void main( String[] args ) { 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.000000000000000055511151231257827021181 5834045410156250
  32. 32. !34 public static void main( String[] args ) { 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.0
  33. 33. !35 def price = 0.1 def total = 0 10.times { total += price } println "Total: " + total Total: 1.0
  34. 34. !36 Principle Of Least Astonishment Select appropriate default
  35. 35. !37 [1, 3, 4, 8, 16, 9] •Find all even numbers •Find all odd numbers •Find numbers divisible by 4 •Find numbers greater than 5
  36. 36. !38 #21: Use function objects to represent strategies
  37. 37. !39 interface Filter{ def includes(number) } class OddFilter implements Filter{ def includes(number){ number % 2 != 0 } } class DivisibleBy4Filter implements Filter{ def includes(number){ number % 4 == 0 } } def doFilter(numbers, Filter filter){ def filteredValues = [] for(int number in numbers){ if(filter.includes(number)){ filteredValues << number } } filteredValues } println doFilter(numbers, new OddFilter()) println doFilter(numbers, new DivisibleBy4Filter())
  38. 38. !40 def divisibleBy4 = { number -> number % 4 == 0 } def odd = { number -> number % 2 != 0 } def numbers = [1, 3, 4, 8, 16, 9] println "Odd numbers: " + numbers.findAll(odd) println "Div by 4: " + numbers.findAll(divisibleBy4) Odd numbers: [1, 3, 9] Div by 4: [4, 8, 16]
  39. 39. !41 Closures No boilerplate code polymorphic code reading skill not required Less duplicate code (potentially)
  40. 40. Bring in Order !42 @ToString class Person { String name int age } def geeks = [ new Person(name: 'Arun', age: 35), new Person(name: 'Raj', age: 30), new Person(name: 'Abhi', age: 35), new Person(name:'Kumar', age: 32), new Person(name: 'Kumar', age: 25) ]
  41. 41. !43 #12: Consider implementing Comparable
  42. 42. !44 println 10 <=> 20 println 20 <=> 10 println 10 <=> 10 -1 1 0
  43. 43. !45 @ToString class Person implements Comparable<Person>{ String name int age int compareTo(Person other){ name <=> other.name } }
  44. 44. Default Sort Order !46 println geeks.sort(false) Original: [ Person(Arun, 35), Person(Raj, 30), Person(Abhi, 35), Person(Kumar, 32), Person(Kumar, 25) ] Sorted: [ Person(Abhi, 35), Person(Arun, 35), Person(Kumar, 32), Person(Kumar, 25), Person(Raj, 30) ]
  45. 45. Sort by Age !47 println geeks.sort(false) { a, b -> a.age <=> b.age} Original: [ Person(Arun, 35), Person(Raj, 30), Person(Abhi, 35), Person(Kumar, 32), Person(Kumar, 25) ] Sorted: [ Person(Kumar, 25), Person(Raj, 30), Person(Kumar, 32), Person(Arun, 35), Person(Abhi, 35) ]
  46. 46. Sort by age, name !48 int compareTo(Person other) { if (this.is(other)) { return 0 } java.lang.Integer value = 0 value = this .name <=> other .name if ( value != 0) { return value } value = this .age <=> other .age if ( value != 0) { return value } return 0 }
  47. 47. Sort by age, name !49 println geeks.sort(false, { a, b -> [{it.age}, {it.name}].findResult { c -> c(a) <=> c(b) ?: null } }) Original: [ Person(Arun, 35), Person(Raj, 30), Person(Abhi, 35), Person(Kumar, 32), Person(Kumar, 25) ] Sorted: [ Person(Kumar, 25), Person(Raj, 30), Person(Kumar, 32), Person(Abhi, 35), Person(Arun, 35) ]
  48. 48. Sort by age, name !50 Original: [ Person(Arun, 35), Person(Raj, 30), Person(Abhi, 35), Person(Kumar, 32), Person(Kumar, 25) ] Sorted: [ Person(Kumar, 25), Person(Raj, 30), Person(Kumar, 32), Person(Abhi, 35), Person(Arun, 35) ] @Sortable(includes = "name, age") @ToString class Person { String name int age }
  49. 49. !51 Syntactic Sugar - Spaceship Operator Simplify common tasks
  50. 50. Million Dollar Effort? !52 ?
  51. 51. Million Dollar Effort !!! !53 null
  52. 52. !54 def List<Speaker> getSpeakers(String conference){ null } def gidsSpeakers = getSpeakers('GIDS19') if(gidsSpeakers != null){ }
  53. 53. !55 #43: Return empty arrays or collections, not nulls
  54. 54. !56 def numbers = [2, 3, 1, 4] println numbers.collect { it + 1} [3, 4, 2, 5] numbers = [] println numbers.collect { it + 1} [] println numbers .findAll { it % 2 == 0} .collect { it * 2} .sum()
  55. 55. !57 println null.collect { it } [] println null.collect { it }.sum() null Caught: java.lang.NullPointerException: Cannot invoke method sum() on null object println null.collect { it }.sum() println null.sum()
  56. 56. !58
  57. 57. !59 NullObject No boilerplate code Life is too short for null checks
  58. 58. !60
  59. 59. !61 #3: Enforce the singleton property with a private constructor or an enum type
  60. 60. !62 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
  61. 61. !63 class Manager{ private static final Manager manager = new Manager() private Manager(){ super() } static Manager getInstance(){ manager } } def m = new Manager() println m Manager@12e61fe6
  62. 62. !64 @Singleton class Manager{ } def m1 = Manager.getInstance() def m2 = Manager.getInstance() println m1 == m2 def m = new Manager() println m Caught: java.lang.RuntimeException: Can't instantiate singleton Manager. Use Manager.instance
  63. 63. !65 private static Manager manager static Manager getInstance(){ if(!manager){ manager = new Manager() } manager }
  64. 64. !66 private static Manager manager static synchronized Manager getInstance(){ if(!manager){ manager = new Manager() } manager }
  65. 65. !67 @Singleton(lazy=true) class Manager{ } println Manager.@instance def m1 = Manager.getInstance() println Manager.@instance null Manager@12e61fe6
  66. 66. !68 @Singleton(lazy=true) class Manager{ } println Manager.@instance def m1 = Manager.getInstance() println Manager.@instance null Manager@12e61fe6
  67. 67. !69
  68. 68. !70 private static volatile Manager instance public static Manager getInstance() { if ( instance != null) { return instance } else { synchronized (Manager) { if ( instance != null) { return instance } else { return instance = new Manager() } } } }
  69. 69. !71 YAGNI Premature optimisation is the root of all evil Don’t punish the punctual AST Transformation
  70. 70. !72 https://www.flickr.com/photos/38080114@N07/8594601982/
  71. 71. !73 #15: Minimize Mutability
  72. 72. Rules to make a class mutable • Don’t provide any mutators • Ensure that the class can’t be extended • Make all fields final • Make all fields private • Ensure exclusive access to any mutable components !74
  73. 73. !75 class ImmutableClass{ private final def field1 private final def field2 //... private final def field10 public ImmutableClass(f1, f2,… f10){ //initialization } }
  74. 74. !76 import groovy.transform.Immutable @Immutable class Rectangle{ int length int breadth } def r = new Rectangle(length: 10, breadth: 5) println r // Rectangle(10, 5)
  75. 75. !77
  76. 76. Code !78 public Rectangle(java.util.HashMap args) { metaClass = /*BytecodeExpression*/ if ( args .length == null) { } else { this .length = (( args .length) as int) } if ( args .breadth == null) { } else { this .breadth = (( args .breadth) as int) } }
  77. 77. !79 Syntactic Sugar Readability Matters AST Transformation
  78. 78. !80
  79. 79. !81 #15: Favour composition over inheritance
  80. 80. !82 class PhoneNumbers{ private @Delegate List phoneNumbers PhoneNumbers(numbers){ phoneNumbers = numbers } def bengaluruNumbers(){ phoneNumbers.findAll { it.startsWith('80') } } }
  81. 81. !83 def ph = ['9812312345', '9812312346', '802312347'] as PhoneNumbers println ph println ph.find { it == '9812312345'} println ph.find { it.endsWith('6') } println ph.bengaluruNumbers()
  82. 82. Traits trait CanSing { def sing() { println "Singing" } } trait CanDance { def dance() { println "Dancing" } } class Person implements CanSing, CanDance {} Person reema = new Person() reema.sing() reema.dance()
  83. 83. !85 AST Transformation Simplify Traits
  84. 84. 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) !86
  85. 85. Take Away Programming languages can reduce the friction to implement good practices !87
  86. 86. Thank You

×