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.

Solid Grails apps with verbose Groovy

3,991 views

Published on

Codemotion 2014

Video de la charla: https://www.youtube.com/watch?v=YwT1ccikv3s

Tras 5 años programando con Grails, me he dado cuenta de que lo he estado haciendo mal. Por programar rápido y hacer un código minúsculo, he perdido muchas cosas por el camino que si tenía cuando programaba aplicaciones web con Java.

Voy a contar mi experiencia personal de cómo he evolucionado mis desarrollos para que sean fáciles de mantener y de testear. Vuelven los POJOS y el código estático, pero solo para ayudar a poner un poco de oden. Aplicando al extremo la "S" de SOLID y aplicando patrones de diseño, hablaré de una manera (más) de diseñar aplicaciones web con Grails usando Commands, organizando el código de los controllers y clasificando los servicios y sus respuestas con pequeñas clases.

Published in: Technology

Solid Grails apps with verbose Groovy

  1. 1. MADRID · NOV 21-22 · 2014 Solid Grails Apps with verbose Groovy Alberto Vilches Consultant at Virtual Software @albertovilches Greach Conference Organizer http://greachconf.com
  2. 2. MADRID · NOV 21-22 · 2014 Disclaimer 1. I’m not a guru, I’m not trying to teach you nothing. 2. This is not a talk about something specific, this is my personal opinion, I can be wrong. 3. It’s just my way to do the things…. Now. Tomorrow I can change my mind, again.
  3. 3. MADRID · NOV 21-22 · 2014 About me 16 years developing, last 5 years with Groovy/Grails Madrid GUG usual suspect Greachconf organizer 2 kids, Maclover, gamer and skeptical Now working at Virtual Software
  4. 4. MADRID · NOV 21-22 · 2014 About me And my code sucks! … and probably yours too. I can’t be the best but I can be better than yesterday. This is a talk about my problems, but I’ll show you solutions.
  5. 5. Introduction MADRID · NOV 21-22 · 2014 PART 0/3
  6. 6. I want to tell you something… MADRID · NOV 21-22 · 2014
  7. 7. I want to tell you about… MADRID · NOV 21-22 · 2014 The Grails trap
  8. 8. MADRID · NOV 21-22 · 2014 A trap? Are you sure? It’s not a trap for everybody Some people are invulnerable
  9. 9. MADRID · NOV 21-22 · 2014 A trap? Are you sure? It’s not a trap for everybody Some people are invulnerable It depends how much you have suffered with j2Ee
  10. 10. MADRID · NOV 21-22 · 2014 Please, kill me I was lost in the f*cking J2EE World Three tiers application servers, EJB, RMI, CORBA, JMS, JDBC direct access, really slooow source java code generation, JNDI, huge monolitic applications full of jar, war and ear, fighting against DTOs, VO, Facade and Service Locators, and of course XML, XML, XML, I told you about XML? Yes XML!
  11. 11. MADRID · NOV 21-22 · 2014 And then…
  12. 12. MADRID · NOV 21-22 · 2014 And then…
  13. 13. MADRID · NOV 21-22 · 2014 And then…
  14. 14. MADRID · NOV 21-22 · 2014 And then… Groovy and Grails The same shit but you ride them with a magic flying unicorn with rocket launcher 0 boilerplate! Working app from scratch in minutes!
  15. 15. MADRID · NOV 21-22 · 2014 Grails: the trap explained  Really new and young  Not much documentation  Not real complex examples (no petstore!)
  16. 16. MADRID · NOV 21-22 · 2014 Grails: the trap explained “With great power comes great responsibility” Spiderman movie “La potencia sin control no sirve de nada” Some old TV ad “Ten cuidao no corras tanto que te vas a dar” My mother
  17. 17. MADRID · NOV 21-22 · 2014 Grails: the trap explained Software architecture? Design patterns?
  18. 18. MADRID · NOV 21-22 · 2014 Grails: the trap explained Software architecture? Design patterns? WHO CARES! WE HAVE ARTIFACTS (remember? no packages at begining!)
  19. 19. MADRID · NOV 21-22 · 2014 Grails: the trap explained No boilerplate and CoC becomes the NEW TRUTH
  20. 20. MADRID · NOV 21-22 · 2014 Grails: the trap explained No boilerplate and CoC becomes the NEW TRUTH the world needs to know it
  21. 21. “Look, my code is really cool!” MADRID · NOV 21-22 · 2014
  22. 22. “Look, my code is really cool!” MADRID · NOV 21-22 · 2014
  23. 23. “Look, my code is really cool!” (In fact, it really really really sucks) MADRID · NOV 21-22 · 2014
  24. 24. MADRID · NOV 21-22 · 2014 Grails: the trap explained no architectural patterns needed, just artifacts
  25. 25. MADRID · NOV 21-22 · 2014 Grails: the trap explained (no architectural patterns needed, just artifacts + really easy data access with gorm)
  26. 26. MADRID · NOV 21-22 · 2014 Grails: the trap explained (no architectural patterns needed, just artifacts + really easy data access with gorm) x (avoiding the “anemic domain model” results in more business logic in controllers, services and domain objects)
  27. 27. MADRID · NOV 21-22 · 2014 Grails: the trap explained (no architectural patterns needed, just artifacts + really easy data access with gorm) x (avoiding the “anemic domain model” results in more business logic in controllers, services and domain objects) ^ (Grails infrastructure everywhere)
  28. 28. MADRID · NOV 21-22 · 2014 Grails: the trap explained (no architectural patterns needed, just artifacts + really easy data access with gorm) x (avoiding the “anemic domain model” results in more business logic in controllers, services and domain objects) ^ (Grails infrastructure everywhere) =================================== Shit, now i’m lost with grails too
  29. 29. My new mess (Grails version) MADRID · NOV 21-22 · 2014
  30. 30. My new mess (Grails version) MADRID · NOV 21-22 · 2014
  31. 31. MADRID · NOV 21-22 · 2014 PART 1/3 The theoric and long part, with patterns and other stuff.
  32. 32. MADRID · NOV 21-22 · 2014 How I’m solving it PROBLEM #1 No control about where the business logic lives Grails hides Spring and Hibernate, offering to you new infrastructure you spread in artifacts
  33. 33. MADRID · NOV 21-22 · 2014 How I’m solving it PROBLEM #1 No control about where the business logic lives Create a taxonomy and rules Grails hides Spring and Hibernate, offering to you new infrastructure you spread in artifacts Isolate it
  34. 34. #1 No control about where the business logic lives MADRID · NOV 21-22 · 2014 My house, my rules:
  35. 35. #1 No control about where the business logic lives MADRID · NOV 21-22 · 2014 My house, my rules: 1) Only use services 2) Return rich responses (and use enums!) 3) Too much services? create your own taxonomy
  36. 36. #1 No control about where the business logic lives 1) Only use services 2) Return rich responses (use enums!)  Controllers just call services methods.  To avoid logic in controllers, services have to MADRID · NOV 21-22 · 2014 return rich object responses.  Controllers and views only have to check responses status calling short methods with meaningful names (clean code!).
  37. 37. #1 No control about where the business logic lives MADRID · NOV 21-22 · 2014
  38. 38. #1 No control about where the business logic lives MADRID · NOV 21-22 · 2014
  39. 39. #1 No control about where the business logic lives MADRID · NOV 21-22 · 2014
  40. 40. #1 No control about where the business logic lives MADRID · NOV 21-22 · 2014
  41. 41. #1 No control about where the business logic lives MADRID · NOV 21-22 · 2014
  42. 42. #1 No control about where the business logic lives MADRID · NOV 21-22 · 2014
  43. 43. #1 No control about where the business logic lives MADRID · NOV 21-22 · 2014
  44. 44. #1 No control about where the business logic lives The good parts:  You can add more info into response classes without change all the app. MADRID · NOV 21-22 · 2014  Easy to test and mocks.  Meaningful actions.
  45. 45. #1 No control about where the business logic lives The good parts:  You can add more info into response classes without change all the app. MADRID · NOV 21-22 · 2014  Easy to test and mocks.  Meaningful actions. The bad parts:  Verbose.
  46. 46. #1 No control about where the business logic lives The good parts:  You can add more info into response classes without change all the app. MADRID · NOV 21-22 · 2014  Easy to test and mocks.  Meaningful actions. The bad parts:  Verbose.
  47. 47. #1 No control about where the business logic lives What about to put logic in domain classes? MADRID · NOV 21-22 · 2014
  48. 48. #1 No control about where the business logic lives What about to put logic in domain classes? MADRID · NOV 21-22 · 2014 IT’S A TRAP!
  49. 49. #1 No control about where the business logic lives What about to put logic in domain classes? MADRID · NOV 21-22 · 2014 “Create methods in your domain classes, but delegate calls to service methods.”
  50. 50. #1 No control about where the business logic lives MADRID · NOV 21-22 · 2014
  51. 51. #1 No control about where the business logic lives MADRID · NOV 21-22 · 2014
  52. 52. #1 No control about where the business logic lives MADRID · NOV 21-22 · 2014
  53. 53. #1 No control about where the business logic lives 3) Too much services? create your own taxonomy MADRID · NOV 21-22 · 2014 My house, my rules:  “Repository” services  “External” services  “Business” services
  54. 54. #1 No control about where the business logic lives MADRID · NOV 21-22 · 2014 “Repository” services  One responsability: access data  Gorm/HQL/JDBC, grailsApplication.config, fileSystem  No transactional!
  55. 55. #1 No control about where the business logic lives “Repository” services, the good parts:  Isolate Grails infrastructure.  Easy to refactor: better rename (only one place to modify) or change data source.  Easy to mantain: only one place to look. MADRID · NOV 21-22 · 2014
  56. 56. #1 No control about where the business logic lives “Repository” services, the good parts:  Isolate Grails infrastructure.  Easy to refactor: better rename (only one place to modify) or change data source.  Easy to mantain: only one place to look. The bad parts:  Verbose, specially the wraping service of MADRID · NOV 21-22 · 2014 grailsApplication.config
  57. 57. #1 No control about where the business logic lives “Repository” services, the good parts:  Isolate Grails infrastructure.  Easy to refactor: better rename (only one place to modify) or change data source.  Easy to mantain: only one place to look. The bad parts:  Verbose, specially the wraping service of MADRID · NOV 21-22 · 2014 grailsApplication.config
  58. 58. #1 No control about where the business logic lives MADRID · NOV 21-22 · 2014 “External” services  One responsability access to remote servers
  59. 59. #1 No control about where the business logic lives MADRID · NOV 21-22 · 2014 “External” services  One responsability access to remote servers  Web Services (rest/soap), apis, mail servers, …  FTP, SNMP, JMX, XMPP, …  Amazon S3, Facebook, Google, Twitter, …
  60. 60. #1 No control about where the business logic lives “External” services, the good parts  Vertical design.  Each integration has one implementation. MADRID · NOV 21-22 · 2014
  61. 61. #1 No control about where the business logic lives “External” services, the good parts  Vertical design.  Each integration has one implementation. The bad parts  Too simple: keep in mind some integrations could need design patterns to avoid huge service classes full of spaghetti code. MADRID · NOV 21-22 · 2014
  62. 62. #1 No control about where the business logic lives External services, good parts  Vertical design.  Each integration has one implementation. The bad parts  Too simple: keep in mind some integrations could need design patterns to avoid huge service classes full of spaghetti code. MADRID · NOV 21-22 · 2014
  63. 63. #1 No control about where the business logic lives MADRID · NOV 21-22 · 2014 “Business” services  One responsability: your business logic  Can be transactional  Orchest all other services
  64. 64. #1 No control about where the business logic lives “Business” services, the good parts  Isolate business logic without infrastructure. MADRID · NOV 21-22 · 2014
  65. 65. #1 No control about where the business logic lives “Business” services, the good parts  Isolate business logic without infrastructure. The bad parts  Verbose: you always have to pass through MADRID · NOV 21-22 · 2014 them.
  66. 66. #1 No control about where the business logic lives “Business” services, the good parts  Isolate business logic without infrastructure. The bad parts  Verbose: you always have to pass through MADRID · NOV 21-22 · 2014 them. Hey, you can break your own rules and call directly to repositoy services.
  67. 67. #1 No control about where the business logic lives “Business” services, the good parts  Isolate business logic without infrastructure. The bad parts  Verbose: you always have to pass through MADRID · NOV 21-22 · 2014 them. Hey, you can break your own rules and call directly to repositoy services.
  68. 68. #1 No control about where the business logic lives MADRID · NOV 21-22 · 2014 My rules
  69. 69. #1 No control about where the business logic lives MADRID · NOV 21-22 · 2014 My rules  Controllers call to business services only  Business services call to any kind of service  Repositories can call other repositories only  External services can’t call other services
  70. 70. #1 No control about where the business logic lives MADRID · NOV 21-22 · 2014
  71. 71. #1 No control about where the business logic lives Create a taxonomy with your own rules MADRID · NOV 21-22 · 2014
  72. 72. #1 No control about where the business logic lives Create a taxonomy with your own rules But ensure all the team respect them MADRID · NOV 21-22 · 2014
  73. 73. MADRID · NOV 21-22 · 2014 PART 2/3 About the views. Sweet and short!
  74. 74. MADRID · NOV 21-22 · 2014 How I’m solving it PROBLEM #2: Controllers have too much duplicated and dynamic code with map arguments (buggy!)
  75. 75. MADRID · NOV 21-22 · 2014 How I’m solving it PROBLEM #2: Controllers have too much duplicated and dynamic code with map arguments (buggy!) Clean code: hide infrastructure in single methods (or classes)
  76. 76. #2 Controllers have too much duplicated and dynamic code MADRID · NOV 21-22 · 2014
  77. 77. #2 Controllers have too much duplicated and dynamic code MADRID · NOV 21-22 · 2014
  78. 78. #2 Controllers have too much duplicated and dynamic code MADRID · NOV 21-22 · 2014
  79. 79. #2 Controllers have too much duplicated and dynamic code MADRID · NOV 21-22 · 2014
  80. 80. #2 Controllers have too much duplicated and dynamic code The good parts  Meaningful actions, easy reading, reusable  Easy to rename model values or view names  Better testing You don’t have to assert model or view, just assert method calls  Static code, if you like MADRID · NOV 21-22 · 2014
  81. 81. #2 Controllers have too much duplicated and dynamic code The good parts  Meaningful actions, easy reading, reusable  Easy to rename model values or view names  Better testing You don’t have to assert model or view, just assert method calls  Static code, if you like The bad parts  Less flexible than using dynamic methods. MADRID · NOV 21-22 · 2014
  82. 82. MADRID · NOV 21-22 · 2014 PART 3/3 Final part. A lot of technical knowledge about data binding. BONUS TRACK: 10 TRICKS!
  83. 83. MADRID · NOV 21-22 · 2014 PART 3/3 Final part. A lot of technical knowledge about data binding. Shut up and keep your eyes open!
  84. 84. MADRID · NOV 21-22 · 2014 How I’m solving it PROBLEM #3: What about the input? Divide input data in minimal commands Use new Grails 2.3 binding events And let me show you some tricks :-)
  85. 85. MADRID · NOV 21-22 · 2014 #3 How Commands works A new command instance is created, then: 1 Data is bound from request (json/params), before and after events are called. 2 Dependency Injection. 3 command.validate() is called. Finally, your action is executed.
  86. 86. MADRID · NOV 21-22 · 2014 #3 How Commands works ControllersApi.class (org.codehaus.groovy.grails.plugins.web.api) initializeCommandObject method. DataBindingUtils.class (org.codehaus.groovy.grails.web.binding) ValidationSupport.class (org.codehaus.groovy.grails.web.plugins.support)
  87. 87. MADRID · NOV 21-22 · 2014 #3 How Commands works TRICK #0 Never ever use domain classes as commands in your actions. It’s a really bad practice, you are exposing your datamodel to the world!
  88. 88. MADRID · NOV 21-22 · 2014 #3 How Commands works TRICK #1 You musn’t validate commands in your actions. Grails did that for you already! Maybe database access will be executed twice.
  89. 89. MADRID · NOV 21-22 · 2014 #3 How Commands works TRICK #2 Yes, you can use more than one command in your actions. All of them will be bound using the same data input.
  90. 90. MADRID · NOV 21-22 · 2014 #3 How Commands works TRICK #3 Pay attention when using new data binding annotations. The annotations are bound to the command class at compile time forever. And maybe you want a different behavior.
  91. 91. MADRID · NOV 21-22 · 2014 #3 How Commands works TRICK #3 Pay attention when using new data binding annotations. Are you sure to use that? What happens if you want to use the command for importing data from a file using other format date?
  92. 92. MADRID · NOV 21-22 · 2014 #3 How Commands works TRICK #4 The @BindUsing is tricky! Use the same field name!
  93. 93. MADRID · NOV 21-22 · 2014 #3 How Commands works TRICK #4 The @BindUsing is tricky How it works? QUIZZ TIME!
  94. 94. MADRID · NOV 21-22 · 2014 #3 How Commands works TRICK #4 The @BindUsing is tricky email emailOther value bound crew@greachconf.com empty ?
  95. 95. MADRID · NOV 21-22 · 2014 #3 How Commands works TRICK #4 The @BindUsing is tricky email emailOther value bound crew@greachconf.com empty empty!
  96. 96. MADRID · NOV 21-22 · 2014 #3 How Commands works TRICK #4 The @BindUsing is tricky email emailOther value bound crew@greachconf.com empty empty! empty VILCHES@GMAIL.COM ?
  97. 97. MADRID · NOV 21-22 · 2014 #3 How Commands works TRICK #4 The @BindUsing is tricky email emailOther value bound crew@greachconf.com empty empty! empty VILCHES@GMAIL.COM empty too!
  98. 98. MADRID · NOV 21-22 · 2014 #3 How Commands works TRICK #4 The @BindUsing is tricky email emailOther value bound crew@greachconf.com empty empty! empty VILCHES@GMAIL.COM empty too! crew@greachconf.com VILCHES@GMAIL.COM ?
  99. 99. MADRID · NOV 21-22 · 2014 #3 How Commands works TRICK #4 The @BindUsing is tricky email emailOther value bound crew@greachconf.com empty empty! empty VILCHES@GMAIL.COM empty too! crew@greachconf.com VILCHES@GMAIL.COM vilches@gmail.com
  100. 100. MADRID · NOV 21-22 · 2014 #3 How Commands works TRICK #4 The @BindUsing is tricky So, be careful…
  101. 101. MADRID · NOV 21-22 · 2014 #3 How Commands works TRICK #5 Default value converters are tricky Locale.default is used if no request bound to current thread.
  102. 102. MADRID · NOV 21-22 · 2014 #3 How Commands works TRICK #5 Default value converters are tricky You have to create another implementation if you want to use commands without request. (i.e.: importing from file in a Quartz job)
  103. 103. MADRID · NOV 21-22 · 2014 #3 How Commands works TRICK #6 Use the binding events Especially, afterBinding event allows you to do some ad-hoc binding and validations. Best part: these events are executed before validate.
  104. 104. MADRID · NOV 21-22 · 2014 #3 How Commands works TRICK #7 Delegate binding events to the commands. Instead to create a listener for every command, create a generic listener and delegate the event call to your command.
  105. 105. MADRID · NOV 21-22 · 2014 #3 How Commands works TRICK #7 Delegate binding events to the commands. It’s just an idea, you can do it better :-)
  106. 106. MADRID · NOV 21-22 · 2014 #3 How Commands works TRICK #8 Don’t let Grails to load entities for you. Only you can access to database in your business logic, not Grails!
  107. 107. MADRID · NOV 21-22 · 2014 #3 How Commands works TRICK #8 Don’t let Grails to load entities for you. controller/action?productType.id=25
  108. 108. MADRID · NOV 21-22 · 2014 #3 How Commands works TRICK #8 Don’t let Grails to load entities for you. controller/action?productType.id=25
  109. 109. MADRID · NOV 21-22 · 2014 #3 How Commands works TRICK #8 Don’t let Grails to load entities for you. Doing that, you have to create a constraint validator to ensure the ownership of the entity.
  110. 110. MADRID · NOV 21-22 · 2014 #3 How Commands works TRICK #8 Don’t let Grails to load entities for you. I don’t like because it needs up to 4 db selects to get the info.
  111. 111. MADRID · NOV 21-22 · 2014 #3 How Commands works TRICK #8 Don’t let Grails to load entities for you. Alternative way to do it using afterBinding event. With only 1 select against db!
  112. 112. MADRID · NOV 21-22 · 2014 #3 How Commands works TRICK #9 You can bind whatever you want! Just call to DataBindingUtils.bindObjectToInstance() It will call to all of your events too!
  113. 113. MADRID · NOV 21-22 · 2014 #3 How Commands works TRICK #9 You can bind whatever you want! All my commands inherits from this class (kind of…)
  114. 114. MADRID · NOV 21-22 · 2014 #3 How Commands works TRICK #10 Use commands as input in your services Ensure they don’t have errors!
  115. 115. THE END? You wanna more tricks? 2 MORE TRICKS! MADRID · NOV 21-22 · 2014
  116. 116. MADRID · NOV 21-22 · 2014 #3 How Commands works TRICK #11 Dependency injection starts AFTER all the events (even the beforeBinding) So, if you need services or any other artifact injected in your commands, just use: Holders.applicationContext.autowireCapableBeanFactory. autowireBeanProperties(command, AutowireCapableBeanFactory.AUTOWIRE_BY_NAME, false)
  117. 117. MADRID · NOV 21-22 · 2014 #3 How Commands works TRICK #12 Create your own annotations! Just create a listener and read the command annotation in the beforeBinding or afterBinding event.
  118. 118. MADRID · NOV 21-22 · 2014 #3 How Commands works TRICK #12 Create your own annotations! Annotation example. It just take a Closure as the only argument.
  119. 119. MADRID · NOV 21-22 · 2014 #3 How Commands works TRICK #12 Create your own annotations! How to read the annotation and call the command from a binding listener:
  120. 120. MADRID · NOV 21-22 · 2014 #3 How Commands works TRICK #12 Create your own annotations! Using the annotation from a command. Real example!
  121. 121. No more tricks, no more rules! New Grails 2.3 Data Binding is very powerful! Use at your own risk and read documentation! Divide input data in minimal commands. Combine with previous patterns. Create your own rules and respect it. MADRID · NOV 21-22 · 2014
  122. 122. Questions? Thank you! @albertovilches http://albertovilches.com @greachconf http://greachconf.com 10-11 April MADRID · NOV 21-22 · 2014 2015

×