C l e a n A r c h i t e c t u r e s i n P y t h
- n
A t a l e
- f
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
“Who wrote this code?”
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
Vitruvius, De architectura
Vitruvius, De architectura
Ivar Jacobson (1992)
Object Oriented Software Engineering: A Use-Case Driven Approach
Design Patterns
Robert Martin (2000)
Design Principles and Design Patterns
Eric Evans (2003)
Domain-Driven Design: Tackling Complexity in the Heart of Software
Enterprise Integration Patterns: Designing, Building, and Deploying Messaging Solutions
A practical approach to better software design
Leonardo Giordani
class Item: def __init__(self, code, price): self.code = code self.price = price
use_case = uc.ItemsListUseCase() use_case.execute()
@blueprint.route('/items', methods=['GET']) def items(): pass
@blueprint.route('/items', methods=['GET']) def items(): use_case = uc.ItemsListUseCase() use_case.execute(request.args)
@blueprint.route('/items', methods=['GET']) def items(): use_case = uc.ItemsListUseCase() use_case.execute(request.args)
@blueprint.route('/items', methods=['GET']) def items(): use_case = uc.ItemsListUseCase() use_case.execute(request.args)
@blueprint.route('/items', methods=['GET']) def items(): repo = PostgresRepo(CONNECTION_STRING) use_case = uc.ItemsListUseCase(repo) use_case.execute(request.args)
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
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 = ...
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())
@blueprint.route('/items', methods=['GET']) def items(): repo = PostgresRepo(CONNECTION_STRING) use_case = uc.ItemsListUseCase(repo) result = use_case.execute(request.args)
@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)
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
@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)
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())
A practical approach to better software design
Leonardo Giordani
Harry Percival, Bob Gregory