Diese Präsentation wurde erfolgreich gemeldet.
Wir verwenden Ihre LinkedIn Profilangaben und Informationen zu Ihren Aktivitäten, um Anzeigen zu personalisieren und Ihnen relevantere Inhalte anzuzeigen. Sie können Ihre Anzeigeneinstellungen jederzeit ändern.

Advanced web application architecture Way2Web

2.128 Aufrufe

Veröffentlicht am

How to:
- Design a clean domain model
- Model your application's use cases as application services
- Connect those well-designed layers to the world outside

Protecting your high quality domain model can be accomplished by applying a so-called ports & adapters or hexagonal architecture.
Some of the keywords for this talk: aggregate design, domain events, application services, commands, queries and events, layered architecture, ports & adapters, hexagonal architecture.

Veröffentlicht in: Software
  • Loggen Sie sich ein, um Kommentare anzuzeigen.

Advanced web application architecture Way2Web

  1. 1. Advanced (Simple) Web Application Architecture Matthias Noback @matthiasnoback
  2. 2. A little bit of controversy for you What makes a framework "good"?
  3. 3. "I make a lot of money with it"
  4. 4. Faulty heuristic A hard question: "Is it good?" Gets replaced by an easy question: "Do people make money with it?"
  5. 5. "I learn design patterns from it"
  6. 6. "My framework uses semantic versioning"
  7. 7. "My framework is great for prototyping"
  8. 8. "I can go to conferences about my framework"
  9. 9. A framework is not something to identify with, but something you use, and know how to use to your advantage
  10. 10. Frameworks dictate the structure of your project
  11. 11. High-level structural elements ● Models/entities ● Controllers ● Views/templates ● Migrations ● Configuration
  12. 12. Thin controllers, fat models ● "Only briefly visit your controller, go to your model as fast as you can." ● In practice: we build services, lots of them, and large ones too.
  13. 13. The effects of a framework- driven architecture ● Implicit use case scenarios ● Implicit connections to actors ● Coupling to the framework
  14. 14. Why bad? ● Scenarios are interrelated (legacy spaghetti) ● Domain logic is mixed with infrastructure logic ● Impossible to switch frameworks
  15. 15. What do we want? ● The ability to focus on domain logic without thinking about storage, web service, web requests, etc. ● The ability to switch to a different database, framework, message queue, filesystem, etc.
  16. 16. We need to make a split between: Infrastructure and Domain logic The intention and the implementation of communication
  17. 17. First: what is domain logic/infrastructure 1. Saving an uploaded file to a cloud file storage 2. Instantiating an entity by calling its constructor 3. Storing an entity in the database 4. Calculating the total amount for an invoice 5. Making sure that an order has at least one line 6. Publishing a domain event to a message queue
  18. 18. Heuristic ● Try describing what the system does without mentioning any technology. ● Split the implementation along these lines.
  19. 19. Example: Fixer We convert the invoice line and total amounts of the invoice currency by sending a GET request to Fixer's /api/latest API endpoint, providing the invoice currency as the base currency and EUR as the target currency.
  20. 20. Applying the heuristic "We need to convert the invoice line and total amounts of the invoice currency. In order to do this, we need to find out the current exchange rate between the invoice currency and our standard currency (EUR)." ExchangeRateProvider
  21. 21. Applying the heuristic "We do this by sending a GET request to Fixer's /api/latest API endpoint, providing the invoice currency as the base currency and EUR as the target currency. The result will be a JSON string which we decode. We'll return a Rate value object based on the data we receive." FixerExchangeRateProvider implements ExchangeRateProvider
  22. 22. Domain logic versus Infrastructure
  23. 23. Domain logic versus Infrastructure ● Entities ● Value objects ● Repository interfaces ● Domain services ● SQL query ● HTTP headers ● File permissions ● MIME types ● JSON/XML encoding
  24. 24. Split the code in two parts ● One part which shows what you're trying to accomplish. ● Another part which fills in the low-level details.
  25. 25. What about... A web controller action? 1. In the controller, only take out the necessary data from the Request. 2. Call a service that knows nothing about the web.
  26. 26. What about... Saving an entity to the database? 1. Recognize the need for persistence, and define an interface for it (e.g. a repository interface). 2. Provide an implementation that knows how to talk to your particular database.
  27. 27. Application service Repository interface Web controller calls uses Repository implementation implements
  28. 28. So far ● We've separated domain logic from infrastructure ● We can replace the infrastructure "layer"; domain logic is independent of it ● We can test complete use case scenarios without invoking infrastructure code
  29. 29. Application service Repository interface Test driver calls uses Repository stub implements
  30. 30. Application service Repository interface calls uses implements Webcontroller Testdriver MySQL Stub calls implements
  31. 31. Hexagonal architecture, or: Ports & adapters Port: an intention of a dialog Adapter: supporting implementation for the dialog Hexagon: the application without its adapters
  32. 32. Hexagonal architecture, or: Ports & adapters Port: "For saving entities" (represented by a repository interface with a save() method) Adapter: "Save entities by sending SQL insert/update statements to a MySQL database" (implemented in a repository class).
  33. 33. Application service Repository interface calls uses implements Webcontroller Testdriver MySQL Stub calls implements
  34. 34. Userinterface Persistence Notifications Batchimport News feed Blob storage
  35. 35. Application service Repository interface calls uses implements Webcontroller Testdriver MySQL Stub calls implements
  36. 36. Stub MySQL NoSQL
  37. 37. W ebcontroller CLIcommand
  38. 38. What does this bring us? Domain logic is decoupled from infrastructure, meaning that:
  39. 39. What does this bring us? The domain logic can survive the replacement of port adapters
  40. 40. What does this bring us? We can create new adapters for existing ports and swap them
  41. 41. What does this bring us? We can switch frameworks
  42. 42. But, I'll never switch frameworks... You will
  43. 43. But, I'll never switch frameworks... Even a minor framework (or library) upgrade can sometimes feel like a complete switch
  44. 44. But, I'll never switch frameworks... Your favorite framework today will stop being maintained some day (just like the earth itself)
  45. 45. But, I'll never switch frameworks... What's modern and cool now, won't be in just two years
  46. 46. What does this bring us? We can test every part in isolation (domain logic, adapters)
  47. 47. But, I don't write tests... You have to
  48. 48. Why do developers not write tests? Because it involves a learning process on top of the process of learning to write code.
  49. 49. Why do developers not write tests? Because it seems to be possible to skip the extra effort needed to write tests and do something easier: write production code.
  50. 50. Why do developers not write tests? The feedback loop is very slow: you'll only learn later that having a test suite is absolutely required to keep the software in a presentable state in the long run.
  51. 51. So please write your tests Start learning today; Reduce the extra effort it takes And finally: enjoy the increase in development speed
  52. 52. "What if my project is short-lived?"
  53. 53. The advice doesn't apply (But don't decide to quickly)
  54. 54. What's a good framework? A framework that doesn't get in the way
  55. 55. A good framework allows me to split: Infrastructure and Domain logic The intention and the implementation of communication
  56. 56. Questions? Matthias Noback Training & Consultancy matthiasnoback.nl

×