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.

Use Case Driven Development in Symfony

1,154 views

Published on

Reflecting the use cases of applications in the code and introducing a bundle that will make it easier to do in Symfony.

Published in: Software

Use Case Driven Development in Symfony

  1. 1. USE CASE DRIVEN DEVELOPMENT IN SYMFONY Bartosz Zasada zasada.bartosz@gmail.com
  2. 2. ABOUT ME ➤ From Toruń, Poland ➤ Software developer since 2010 ➤ In Berlin since July 2015 ➤ Bass player
  3. 3. WHAT ARE YOU WORKING ON?
  4. 4. HOW CAN I USE YOUR WEBSITE?
  5. 5. HOW CAN I USE YOUR WEBSITE? ➤ You can buy a lot of different stuff and have it delivered the very next day. ➤ You can cheaply book a room for your vacation in a nice hotel. ➤ You can order a meal, making your choice basing on opinions shared by other users. ➤ You can watch videos of kittens and participate in endless flame wars in the comments section.
  6. 6. USE CASES
  7. 7. ACTORS ➤ An actor is anyone (or anything) that interacts with the application ➤ Different actors have their own specific needs ➤ One person can have a role of many actors
  8. 8. USE CASES ➤ A use case is a specific way of using the system by using some part of the functionality ➤ When all actors are known, identifying their needs will define the complete functionality of the application
  9. 9. EXAMPLES OF USE CASES ➤ View products in category ➤ View product page ➤ Add product to shopping cart ➤ Place order ➤ Mark payment as paid ➤ Dispatch shipment ➤ Add product to stock ➤ Set discount for product Customer Customer Service Inventory Manager
  10. 10. COURSES OF EXECUTION ➤ The primary course of the use case is a series of events that lead to the one successful outcome ➤ The use case can also follow one of the alternative courses, which usually means that something went wrong ➤ Product does not exist ➤ Product is out of stock ➤ The quantity is not a positive integer ➤ The maximum quantity was exceeded ➤ A system failure has occurred
  11. 11. IMPLEMENTING USE CASES
  12. 12. ONE USE CASE, ONE CLASS ➤ Isolate the application behavior in a class that represents a Use Case ➤ Identify the incoming data and create a Request object ➤ Return the result as a single Response object ➤ Or throw an Exception if something goes wrong
  13. 13. IMPLEMENTATION EXAMPLE
  14. 14. IMPLEMENTATION EXAMPLE
  15. 15. BUT THAT'S MY CONTROLLER ACTIONS! ➤ Okay, but... ➤ The controllers depend on classes that belong to HttpFoundation ➤ Often you have to inject the entire HTTP request ➤ Always you have to return an HTTP response ➤ The use cases are mixed with details that have nothing to do with business logic
  16. 16. SO WHAT? ➤ HTTP requests and responses are specific to web applications ➤ They can come in different forms regardless of the logic ➤ GET - query string or route attributes ➤ POST - form_params or JSON (or XML) in the body ➤ Response - HTML, JSON, XML ➤ Exporting data - XML, CSV, PDF... ➤ Business logic should be clearly separated from these details
  17. 17. USE CASES ARE SOLID ➤ Single Responsibility Principle is clearly visible: 
 each Use Case defines a single possible interaction of a user with the application ➤ By having the Use Cases follow the same pattern, the system becomes open for extension and closed for modification, as the new functionality is added by creating new classes rather than modifying the existing ones - thus following the Open- Closed Principle ➤ Use Cases favor Interface Segregation Principle: every interface upon which a Use Case depends defines needs specific to this Use Case
  18. 18. INTERFACE SEGREGATION PRINCIPLE Display Products
 in Category Category Repository Display Featured
 Categories Featured 
 Category Repository Display 
 Category Tree Category Tree
 Repository Doctrine
 Category Repository
  19. 19. USE CASES ARE SOLID ➤ Use Cases follow the Dependency Inversion Principle ➤ Instead of having business logic depend on HTTP requests and responses, the HTTP layer becomes dependent on Use Case Requests and Use Case Responses
  20. 20. DEPENDENCY INVERSION PRINCIPLE Use Case HTTP Request HTTP RequestUse Case Use Case Request
  21. 21. ALL THAT BOILERPLATE
  22. 22. INTRODUCING USE CASE BUNDLE
  23. 23. INSTALLATION ➤ composer require bamiz/use-case-bundle ➤ AppKernel.php: 
 new BamizUseCaseBundleBamizUseCaseBundle()
  24. 24. USAGE services.yml Use Case Controller
  25. 25. HANDLING INPUT ➤ Input is whatever the application receives from its user ➤ The Use Case is resolved based on Input ➤ The Use Case Request is created for the Use Case ➤ An Input Processor parses the Input and initializes the fields of the Use Case Request Use CaseUse Case RequestInput Processor
  26. 26. CREATING OUTPUT ➤ Output is whatever the user sees as the result of the application's operation ➤ The Use Case Response is returned by the Use Case ➤ An Exception is thrown by the Use Case ➤ A Response Processor creates the Output using the data contained in the Response or Exception Use Case Use Case Response Response Processor
  27. 27. CONFIGURING PROCESSORS FOR USE CASES
  28. 28. DEPENDENCIES Use Case Request Input Use Case OutputInput Processor Response Processor Use Case Response
  29. 29. BUNDLED PROCESSORS ➤ Input Processors ➤ HTTP - populates the fields with data from HTTP Request ➤ Form - uses Symfony Forms to initialize the Request ➤ JSON - Decodes request body as JSON ➤ Response Processors ➤ JSON - returns the Response as JsonResponse ➤ Twig - renders Twig templates using Response as params
  30. 30. YOUR OWN PROCESSORS ➤ Input Processor ➤ Implement InputProcessorInterface ➤ Create a service and tag it as use_case_input_processor ➤ Response Processor ➤ Implement ResponseProcessorInterface ➤ Create a service and tag it as use_case_response_processor
  31. 31. SO MUCH ROOM TO GROW
  32. 32. IDEAS FOR FEATURES ➤ Chaining Input and Response Processors ➤ In progress Done ➤ An Input Processor that ensures the correct types of the fields ➤ Types read from @var/@type in PHPDoc ➤ "1 234,56" → (float)1234.56 ➤ "true"/"1"/"on" → (bool)true; ➤ "false"/"0"/"" → (bool)false ➤ More configuration options ➤ Defaults per Processor (globally or in context) ➤ Defining contexts per Use Cases using YAML
  33. 33. IDEAS FOR FEATURES ➤ Actors ➤ Integration with Symfony Security component ➤ Use Cases restricted to certain Actors ➤ Actors executing their Use Cases reflected in code syntax ➤ $this->registeredUser->addItemToWishlist() ➤ $this->customer->viewProductPage()
  34. 34. IDEAS FOR FEATURES ➤ Code that writes itself ➤ Symfony Command that generates Use Cases, Requests and Responses ➤ Use Cases generated using Behat scenarios ➤ Scenario: Viewing product page ➤ As a customer ➤ I want to view the product page ➤ So that ...
  35. 35. YOU'RE WELCOME TO CONTRIBUTE ➤ https://github.com/bartosz-zasada/use-case-bundle ➤ If you fork, you are awesome already ➤ Make a pull request and you're super awesome ➤ Let's make our software great together ➤ Love it? Hate it? Got an idea? Drop me a message: zasada.bartosz@gmail.com
  36. 36. INSPIRATION ➤ https://www.youtube.com/watch?v=WpkDN78P884 ➤ Object Oriented Software Engineering: A Use Case Driven Approach. Ivar Jacobson et al. ➤ Agile Software Development: Principles, Patterns, and Practices. Robert C. Martin ➤ Videos from http://cleancoders.com
  37. 37. QUESTIONS?
  38. 38. THANK YOU 🙂

×