Use Case Driven Development in Symfony

38
USE CASE DRIVEN DEVELOPMENT IN SYMFONY Bartosz Zasada [email protected]

Transcript of Use Case Driven Development in Symfony

Page 1: Use Case Driven Development in Symfony

USE CASE DRIVEN DEVELOPMENT IN SYMFONY

Bartosz Zasada [email protected]

Page 2: Use Case Driven Development in Symfony

ABOUT ME

➤ From Toruń, Poland

➤ Software developer since 2010

➤ In Berlin since July 2015

➤ Bass player

Page 3: Use Case Driven Development in Symfony

WHAT ARE YOU WORKING ON?

Page 4: Use Case Driven Development in Symfony

HOW CAN I USE YOUR WEBSITE?

Page 5: Use Case Driven Development in Symfony

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.

Page 6: Use Case Driven Development in Symfony

USE CASES

Page 7: Use Case Driven Development in Symfony

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

Page 8: Use Case Driven Development in Symfony

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

Page 9: Use Case Driven Development in Symfony

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

Page 10: Use Case Driven Development in Symfony

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

Page 11: Use Case Driven Development in Symfony

IMPLEMENTING USE CASES

Page 12: Use Case Driven Development in Symfony

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

Page 13: Use Case Driven Development in Symfony

IMPLEMENTATION EXAMPLE

Page 14: Use Case Driven Development in Symfony

IMPLEMENTATION EXAMPLE

Page 15: Use Case Driven Development in Symfony

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

Page 16: Use Case Driven Development in Symfony

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

Page 17: Use Case Driven Development in Symfony

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

Page 18: Use Case Driven Development in Symfony

INTERFACE SEGREGATION PRINCIPLE

Display Products in Category Category Repository

Display Featured Categories

Featured Category Repository

Display Category Tree

Category Tree Repository

Doctrine Category Repository

Page 19: Use Case Driven Development in Symfony

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

Page 20: Use Case Driven Development in Symfony

DEPENDENCY INVERSION PRINCIPLE

Use Case HTTP Request

HTTP RequestUse Case Use Case Request

Page 21: Use Case Driven Development in Symfony

ALL THAT BOILERPLATE

Page 22: Use Case Driven Development in Symfony

INTRODUCING USE CASE BUNDLE

Page 23: Use Case Driven Development in Symfony

INSTALLATION

➤ composer require bamiz/use-case-bundle ➤ AppKernel.php: new Bamiz\UseCaseBundle\BamizUseCaseBundle()

Page 24: Use Case Driven Development in Symfony

USAGE

services.yml

Use Case

Controller

Page 25: Use Case Driven Development in Symfony

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

Page 26: Use Case Driven Development in Symfony

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

Page 27: Use Case Driven Development in Symfony

CONFIGURING PROCESSORS FOR USE CASES

Page 28: Use Case Driven Development in Symfony

DEPENDENCIES

Use Case Request

Input

Use Case

Output Input Processor

Response Processor

Use Case Response

Page 29: Use Case Driven Development in Symfony

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

Page 30: Use Case Driven Development in Symfony

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

Page 31: Use Case Driven Development in Symfony

SO MUCH ROOM TO GROW

Page 32: Use Case Driven Development in Symfony

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

Page 33: Use Case Driven Development in Symfony

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()

Page 34: Use Case Driven Development in Symfony

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 ...

Page 35: Use Case Driven Development in Symfony

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: [email protected]

Page 36: Use Case Driven Development in Symfony

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

Page 37: Use Case Driven Development in Symfony

QUESTIONS?

Page 38: Use Case Driven Development in Symfony

THANK YOU 🙂