c l e a n a r c h i t e c t u r e s i n p y t h o n

C l e a n A r c h i t e c t u r e s i n P y t - PowerPoint PPT Presentation

C l e a n A r c h i t e c t u r e s i n P y t h o n A t a l e o f d u r a b i l i t y , u t i l i t y , a n d b e a u t y L E O N A R D O G I O R D A N I S O F T W A R E D E V E L O P E


  1. C l e a n A r c h i t e c t u r e s i n P y t h o n A t a l e o f d u r a b i l i t y , u t i l i t y , a n d b e a u t y

  2. L E O N A R D O G I O R D A N I S O F T W A R E D E V E L O P E R A N D B L O G G E R W W W. T H E D I G I T A L C AT O N L I N E . C O M @TW_LGIORDANI - @THEDIGICAT “Who wrote this code?”

  3. WHAT IS THE DEFINITION OF ARCHITECTURE ?

  4. F I R M I T A S , U T I L I T A S , V E N U S T A S Vitruvius, De architectura

  5. D U R A B I L I T Y, U T I L I T Y, B E A U T Y Vitruvius, De architectura

  6. T H E A R T A N D S C I E N C E I N W H I C H T H E C O M P O N E N T S O F A C O M P U T E R S Y S T E M A R E O R G A N I S E D A N D I N T E G R AT E D

  7. D O W E N E E D A R C H I T E C T U R E ?

  8. Ivar Jacobson (1992) Object Oriented Software Engineering: A Use-Case Driven Approach E. Gamma, R. Helm, R. Johnson, J. Vlissides (1994) Design Patterns Robert Martin (2000) Design Principles and Design Patterns Eric Evans (2003) Domain-Driven Design: Tackling Complexity in the Heart of Software H. Hohpe, B. Woolf (2003) Enterprise Integration Patterns: Designing, Building, and Deploying Messaging Solutions

  9. What is the meaning of clean ?

  10. You know where things are, why components are there, what something is.

  11. Leonardo Giordani Clean Architectures in Python A practical approach to better software design bit.ly/getpycabook

  12. The Clean Architecture A layered approach for a more civilized age

  13. The golden rule Talk inward with simple structures , talk outwards through interfaces .

  14. Entities : simple models class Item: def __init__(self, code, price): self.code = code self.price = price

  15. Use case : retrieve a list of items use_case = uc.ItemsListUseCase() use_case.execute()

  16. We want to build a web application @blueprint.route('/items', methods=['GET']) def items(): pass

  17. Incoming HTTP requests become a call and simple structures @blueprint.route('/items', methods=['GET']) def items(): use_case = uc.ItemsListUseCase() use_case.execute(request.args)

  18. The use case extracts data from a repository , which can be any source of data @blueprint.route('/items', methods=['GET']) def items(): use_case = uc.ItemsListUseCase() use_case.execute(request.args)

  19. And the repository can be accessed through an interface @blueprint.route('/items', methods=['GET']) def items(): use_case = uc.ItemsListUseCase() use_case.execute(request.args)

  20. The use case receives the repository interface as an argument of the call @blueprint.route('/items', methods=['GET']) def items(): repo = PostgresRepo(CONNECTION_STRING) use_case = uc.ItemsListUseCase(repo) use_case.execute(request.args)

  21. The use case queries the repository interface with simple structures class ItemsListUseCase: def __init__(self, repo): self.repo = repo def execute(self, params): # BUSINESS LOGIC HERE result = self.repo.list(params) # BUSINESS LOGIC HERE return result

  22. The database interface and the database exchange data in a specifjc language class PostgresRepo: def __init__(self, CONNECTION_STRING): self.ng = create_engine( CONNECTION_STRING) Base.metadata.bind = self.ng def list(self, filters): DBSession = sessionmaker(bind=self.ng) session = DBSession() query = ...

  23. The database interface translates the specifjc language into simple structures and entities class PostgresRepo: def __init__(self, CONNECTION_STRING): self.ng = create_engine( CONNECTION_STRING) Base.metadata.bind = self.ng def _create_items(self, results): return [Item(code=q.code, price=q.price) for q in results] def list(self, filters): DBSession = sessionmaker(bind=self.ng) session = DBSession() query = ... return self._create_items(query.all())

  24. The use case returns the result of the business logic: entities and simple structures @blueprint.route('/items', methods=['GET']) def items(): repo = PostgresRepo(CONNECTION_STRING) use_case = uc.ItemsListUseCase(repo) result = use_case.execute(request.args)

  25. The web framework converts entities and simple structures into HTTP responses @blueprint.route('/items', methods=['GET']) def items(): repo = PostgresRepo(CONNECTION_STRING) use_case = uc.ItemsListUseCase(repo) result = use_case.execute(request.args) return Response( json.dumps(result), mimetype='application/json', status=200)

  26. Testing the use case class ItemsListUseCase: def __init__(self, repo): self.repo = repo def execute(self, params): # BUSINESS LOGIC HERE result = self.repo.list(params) # BUSINESS LOGIC HERE return result

  27. Testing the HTTP endpoint @blueprint.route('/items', methods=['GET']) def items(): repo = PostgresRepo(CONNECTION_STRING) use_case = uc.ItemsListUseCase(repo) result = use_case.execute(request.args) return Response( json.dumps(result), mimetype='application/json', status=200)

  28. Testing the repository interface: integration test class PostgresRepo: def __init__(self, CONNECTION_STRING): self.ng = create_engine( CONNECTION_STRING) Base.metadata.bind = self.ng def _create_items(self, results): return [Item(code=q.code, price=q.price) for q in results] def list(self, filters): DBSession = sessionmaker(bind=self.ng) session = DBSession() query = ... return self._create_items(query.all())

  29. Is it possible to migrate an existing system?

  30. Is this the defjnitive architecture?

  31. Leonardo Giordani Clean Architectures in Python A practical approach to better software design bit.ly/getpycabook

  32. Harry Percival, Bob Gregory Enterprise Architecture Patterns with Python github.com/python-leap/book (Published by O’Reilly)

  33. Thank you! @tw_lgiordani - @thedigicat - bit.ly/getpycabook https://speakerdeck.com/lgiordani

Recommend


More recommend