PHP Barcelona Monthly Talk Feb 2015

1,708 views

Published on

Talk about simplicity and DDD and how we are applying this concepts in Akamon Backend Project: Horus

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

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

No notes for slide

PHP Barcelona Monthly Talk Feb 2015

  1. 1. (println "Hello World! :)")
  2. 2. DDD as an implementation detail Eloi Poch Sergi González
  3. 3. Who$are$we?$ $ ! es.linkedin.com/in/eloipoch/$ $ $ @eloipoch$ $ Eloi.poch@akamon.com$ Eloi!Poch! ! Technical!Lead!at!@Akamon! •  So8ware$Developer$ •  Clojure$developer$wannabe$ •  Want$to$code$in$Castefa$beach$while$drinking$wine$
  4. 4. (conj '(1 2 3) 4)
  5. 5. Who$are$we?$ $ ! es.linkedin.com/in/sergigp/$ $ $ “SergiGP$ $ Sergi.gonzalez@akamon.com$ Sergi! ! Technical!Lead!at!@Akamon! •  So<ware$Developer$ •  Chief$Trolling$Officer$ •  Two$animals$remaining$to$have$an$urban$zoo$
  6. 6. Akamon
  7. 7. A little bit on Akamon before we deal with the technical stuff
  8. 8. We#develop#Social#Casino#Games#
  9. 9. Por$olio'of'Facebook'games'
  10. 10. Por$olio'of'Mobile'apps'
  11. 11. Recently(launched(a(new(Casino(Suite(
  12. 12. Technically …
  13. 13. Flash Client Game Server Backend AS3 Nova Java JReactive & Vertx PHP Horus
  14. 14. @eloipoch @jordillonch @SergiGP @jorgeavila_ss @jdiezc @jvalduvieco @amassa5 Who we are? The backend team
  15. 15. Development Problems
  16. 16. Our expectations…
  17. 17. Performance Big Data Difficult Algorithms Concurrency Real time analytics Scalability
  18. 18. The ugly truth…
  19. 19. Technical Problems
  20. 20. Code Complexity Big ball of mud Shared State Coupling
  21. 21. & Non-Technical problems
  22. 22. Different Cultures
  23. 23. Tackling Complex Code The Philosophy
  24. 24. Simple made Easy
  25. 25. Complex(( One(role( One(task( not(a(single(opera2on( ( OBJECTIVE Hard( Familiar,(near(your( knowledge( ( ( Simple(vs(Easy( ( SUBJECTIVEOBJECTIVE
  26. 26. Simple vs Easy $mysqli = new mysqli("localhost", "horus", "olakease", “suite"); $mysqli->query("INSERT INTO users …”)) SIMPLE EASY /** * @ORMEntity * @ORMTable(name="product") */ class Product
  27. 27. $sum = function ($carry, $item) { return $carry + $item; } array_reduce([1, 2, 3], $sum); $acc = 0; foreach ([1, 2, 3] as $value) { $acc += $value; } SIMPLE EASY Simple vs EasySimple vs Easy
  28. 28. $acc = 0; foreach ([1, 2, 3] as $value) { $acc += $value; } SIMPLE EASY (reduce + [1 2 3]) Simple vs EasySimple vs Easy
  29. 29. Simplicity vs Easiness • Easy to understand • Easy to debug • Easy to change, flexibility, maintenable • Easy to use • Hard to debug • Hard to change
  30. 30. Complected • Something does more than one thing and you can’t split it easily • Source of accidental complexity • DON’T DO IT
  31. 31. Essential Complexity VS Accidental Complexity
  32. 32. Do not complect, compose
  33. 33. Tackling Complex Code The Theory
  34. 34. Organisational level
  35. 35. Pair Programming
  36. 36. Pull Requests
  37. 37. Code Reviews
  38. 38. Continuous Integration
  39. 39. Self Empowerment Never ask for permission unless it would be reckless not to
  40. 40. Trust Great teams are unafraid to air their dirty laundry, admit their mistakes, their weaknesses and their concerns without fear. Patrick Lencioni
  41. 41. Technical Level
  42. 42. Lean Approach
  43. 43. Any model/solution is provisional
  44. 44. YAGNI You Aren’t Gonna Need It
  45. 45. DDD Concepts
  46. 46. • DDD Tactical: • Application Services • Domain Services • Domain Events • Repositories • AR & VO • DDD Strategical: • Modules • Bounded Contexts • SubDomains • Context Maps
  47. 47. CQRS Concepts
  48. 48. Hexagonal Architecture
  49. 49. TDD & BDD
  50. 50. Tackling Complex Code The Practice
  51. 51. Divide, Test & Conquer
  52. 52. Product Entity Example
  53. 53. Product Id Name Description Price Currency Image Url Coins StoreId
  54. 54. Product Product Descriptions Product Prices Stores Product Benefits Product Images
  55. 55. ProductId Product Description Product Price Stores Product Benefit Product Image Description Name Currency Amount Coins StoreId Image Url
  56. 56. ProductId Product Description Product Price Stores Product Benefit Product Image Description Name Currency Amount Coins StoreId Image Url Product BC
  57. 57. ProductId Product Description Product Price Stores Product Benefit Product Image Description Name Currency Amount Coins StoreId Image Url Pricing/Sales BC Product BC
  58. 58. Product Id BenefitId Product Price ProductId Amount Currency Product Description ProductId Name Description Product Benefit Id Amount VirtualMoneyId Product Store ProductId StoreId
  59. 59. HORUS
  60. 60. Big Picture • Directories: 773 • Files: 1501 • Lines of code: 113885 • Non-Comment Lines of Code: 88806 (80%) • Average Class Length: 14 lines • Average Method Length: 2 lines • Cyclomatic Complexity / LLOC: 0.06 • Cyclomatic Complexity / Number of Methods: 1.21 HORUS
  61. 61. Big Picture of our Code in Horus • Directories: 773 / 558 • Files: 1501 / 1001 • Lines of code: 113885 / 41205 • Non-Comment Lines of Code: 88806 (80%) / 38045 (92%) • Average Class Length: 14 lines / 5 lines • Average Method Length: 2 lines / 2 lines • Cyclomatic Complexity / LLOC: 0.06 / 0.03 • Cyclomatic Complexity / Number of Methods: 1.21 / 1.14
  62. 62. UserPostController Command Bus UserRegistratorCommandHandler UserRegistrator Domain Event Publisher UserRegisteredDomainEv entSubscriber UserAccountOpener User UserRepository Event Subscribers . . . POST /users [ userId: 0db90987-5ce1-4683-bb05-7d1b5539cb0b ] Command Handlers . . . UserRegisteredDomainEvent User HORUS BASIC REQUEST UserRegistrationCommand UserRegistrationCommand userId analyticsContextId userId analyticsContextId UserRegisteredDomainEvent userId analyticsContextId id 
 (Economy Account)
  63. 63. UserPostController Command Bus UserRegistratorCommandHandler UserRegistrator Domain Event Publisher UserRegisteredDomainEv entSubscriber UserAccountOpener User UserRepository Event Subscribers . . . POST /users [ userId: 0db90987-5ce1-4683-bb05-7d1b5539cb0b ] Command Handlers . . . UserRegisteredDomainEvent User HORUS BASIC REQUEST UserRegistrationCommand UserRegistrationCommand userId analyticsContextId userId analyticsContextId UserRegisteredDomainEvent userId analyticsContextId id 
 (Economy Account) UserModule EconomyModule
  64. 64. Operational Analytics Support Marketing DE C Q Q We are still COUPLED !!
  65. 65. Operational Analytics Support Marketing HTTP …
  66. 66. Tackling Complex Code The Conclusions
  67. 67. Mistakes • Do not store domain events • Own libraries for CQRS & DDD • Do not use Domain Services • Domain events with wrong identifiers • Couple App Services to Commands & Queries • Not start earlier some Modules/Bounded Contexts
  68. 68. Mistakes • Let the DB guide us • Let the framework guide us
  69. 69. Problems • Domain Events: Lost of order (async) • Doctrine • Unit Of Work + Integration Test = Fail • Embedded: Identifier or not • Behat: The Container
  70. 70. Tips & Tricks • Repositories: • Just add, save and find • Use of DQL implies the schema is too complex • Controllers: 50 lines of code • Application Services: Avoid business logic • One step at time: Hex. Arch. -> DDD -> CQRS -> ES? • Start it as a Module and promote it later to BC
  71. 71. TROLLTIME QUESTIONS? Akamon Developers

×