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.

Designing with Groovy Traits - Gr8Conf India

1,129 views

Published on

Presentation delivered at Gr8Conf India on Jan 16, 2016

Published in: Technology
  • Be the first to comment

Designing with Groovy Traits - Gr8Conf India

  1. 1. Designing with Groovy Traits Naresha K Chief Technologist Channel Bridge Software Labs naresha.k@gmail.com @naresha_k
  2. 2. About Me
  3. 3. OOP
  4. 4. Object Oriented Maturity Model 0 1 2
  5. 5. I made up the term ‘object-oriented', and I can tell you I didn't have that in mind Alan Kay
  6. 6. iskov Substitution Principle
  7. 7. "Favour 'object composition' over 'class inheritance'."
  8. 8. A case for Traits
  9. 9. The Problem Bird charlie = new Bird() charlie.fly() Butterfly aButterFly = new Butterfly() aButterFly.fly()
  10. 10. Recall Interfaces interface Flyable { def fly() }
  11. 11. class Bird implements Flyable { def fly() { println "Flying..." } } class Butterfly implements Flyable { def fly() { println "Flying..." } }
  12. 12. The Smell class Bird implements Flyable { def fly() { println "Flying..." } } class Butterfly implements Flyable { def fly() { println "Flying..." } }
  13. 13. DRY class FlyableImpl implements Flyable { def fly() { println 'Flying...' } } class Bird implements Flyable { def fly() { new FlyableImpl().fly() } }
  14. 14. Making it Groovier class DefaultFlyable implements Flyable { def fly() { println 'Flying...' } } class Bird { @Delegate Flyable flyable = new DefaultFlyable() }
  15. 15. Summarizing interface Flyable { def fly() } class DefaultFlyable implements Flyable { def fly() { println 'Flying...' } } class Bird { @Delegate Flyable flyable = new DefaultFlyable() }
  16. 16. Introducing Trait trait Flyable { def fly() { println "Flying.." } } class Bird implements Flyable {}
  17. 17. Multiple Capabilities 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()
  18. 18. The Mechanics
  19. 19. Overriding Methods from a Trait trait Speaker { def speak() { println "speaking" } } class Gr8ConfSpeaker implements Speaker { def speak() { println "Groovy is Groovy!" } } new Gr8ConfSpeaker().speak()
  20. 20. Traits can implement interfaces interface Programmer { def code() } trait GroovyProgrammer implements Programmer { def code() { println 'coding Groovy' } } class Engineer implements GroovyProgrammer {} new Engineer().code()
  21. 21. Traits can declare abstract methods trait Programmer { abstract String getLanguage() def code() { println "Coding ${getLanguage()}" } } class GroovyProgrammer implements Programmer { String getLanguage() { "Groovy"} } new GroovyProgrammer().code()
  22. 22. Traits can have a state trait Programmer { String language def code() { println "Coding ${language}" } } class GroovyProgrammer implements Programmer {} new GroovyProgrammer(language: 'Groovy').code()
  23. 23. A trait can extend another trait trait JavaProgrammer { def codeObjectOriented() { println 'Coding OOP' } } trait GroovyProgrammer extends JavaProgrammer { def codeFunctional() { println 'Coding FP' } } class Engineer implements GroovyProgrammer {} Engineer raj = new Engineer() raj.codeFunctional() raj.codeObjectOriented()
  24. 24. A trait can extend from multiple traits trait Reader { def read() { println 'Reading'} } trait Evaluator { def eval() { println 'Evaluating'} } trait Printer { def printer() { println 'Printing'} } trait Repl implements Reader, Evaluator, Printer { }
  25. 25. The diamond problem trait GroovyProgrammer { def learn() { println 'Learning Traits'} } trait JavaProgrammer { def learn() { println 'Busy coding'} } class Dev implements JavaProgrammer, GroovyProgrammer {} new Dev().learn()
  26. 26. Finer control on the diamond problem class Dev implements JavaProgrammer, GroovyProgrammer { def learn() { JavaProgrammer.super.learn() } }
  27. 27. Applying traits at run time trait Flyable{ def fly(){ println "Flying.." } } class Person {} new Person().fly()
  28. 28. Applying traits at run time def boardAPlane(Person person) { person.withTraits Flyable } def passenger = boardAPlane(new Person()) passenger.fly()
  29. 29. More examples
  30. 30. Composing Behaviours trait UserContextAware { UserContext getUserContext(){ // implementation } } class ProductApi implements UserContextAware {} class PriceApi implements UserContextAware {}
  31. 31. common fields trait Auditable { String createdBy String modifiedBy Date dateCreated Date lastUpdated } class Price implements Auditable { String productCode BigDecimal mrp BigDecimal sellingPrice }
  32. 32. common fields - a trait approach Price groovyInActionToday = new Price( productCode: '9789351198260', mrp: 899, sellingPrice: 751, createdBy: 'admin', modifiedBy: 'rk' ) println groovyInActionToday.createdBy println groovyInActionToday.modifiedBy
  33. 33. Chaining interface Manager { def approve(BigDecimal amount) }
  34. 34. Chaining trait JuniorManager implements Manager { def approve(BigDecimal amount){ if(amount < 10000G){ println "Approved by JM” } else{ println "Sending to SM" super.approve() } } } trait SeniorManager implements Manager { def approve(BigDecimal amount){ println "Approved by SM" } }
  35. 35. Chaining class FinanceDepartment implements SeniorManager, JuniorManager {} FinanceDepartment finance = new FinanceDepartment() finance.approve(3000) finance.approve(30000)
  36. 36. Groovy Coding!

×