UI
Portal
Finance
Service
MatchingService
http
http
1. Take request from the portal.
2. Ask requested information from matching service.
3. Map received information to a data structure UI understands.
4. Respond the UI portal with structured data.
# api.py
class MatchingServiceAPI:
def get_invoice():
pass
def get_line_items():
pass
def get_orders():
pass
# mappers/invoice.py
class InvoiceMapper:
def map_invoice():
pass
# mappers/line_item.py
class LineItemMapper:
def map_line_items():
pass
# mappers/orders.py
class OrderMapper:
def map_orders():
pass
Hardware is hard to change. If you've written a software thats hard to change, then Congratulations, you've written a hardware.
If I expect change to a certain module, I don't want to hear from you that our architecture doesn't support this change.
Its bad code when you change something in one module and something else way over there breaks.
A class/module should have one and only one reason to change.
UI
Portal
Finance
Service
MatchingService
status code
status code
rpc? sockets?
http status codes?
UI
Portal
Finance
Service
MatchingService
exceptions
status code
raise InvoiceAlreadyExistsException
raise InvoiceNotFoundException
raise InvoiceModificationException
try:
pass
except InvoiceNotFoundException:
return Response(status=404)
from matching import api as MatchingAPI
def create_invoice(invoice):
try:
MatchingAPI.post_invoice(invoice)
except InvoiceAlreadyExistsException:
return Response(status=409)
except InvoiceNotFoundException:
return Response(status=404)
except InvoiceModificationException:
return Response(status=400)
Extract, and extract, and extract untill you can't extract more functions out of a module
put them in class if possible.
def map_invoice(self, invoice):
pass
def invoice_is_reconciled(self, invoice):
pass
def invoice_is_master_recon(self, invoice):
pass
def map_invoice_with_line_items(self, invoice, line_items):
pass
class Invoice:
def __init__(self, payload):
self.invoice = payload
def is_reconciled(self):
pass
def is_master_reconciled(self):
pass
def format(self):
pass
def format_with_line_items(self, line_items):
pass
class MatchingServiceAPI:
def get_document()
def get_all_documents()
def get_line_items()
def patch_line_items()
def get_orders()
raise InvoiceNotFoundExeption
raise InvoiceAlreadyExistsException
raise InvoiceModificationException
raise LineItemNotFoundExeption
raise LineItemAlreadyExistsException
raise LineItemModificationException
raise OrderNotFoundExeption
raise OrderAlreadyExistsException
raise OrderModificationException
MatchingService API
Invoice API
Line Item API
Order
API
── matching_service
│ ├── api.py
│ ├── errors.py
│ ├── exceptions.py
│ ├── invoice
│ │ ├── api.py
│ │ ├── errors.py
│ │ ├── exceptions.py
│ ├── line_item
│ │ ├── api.py
│ │ ├── errors.py
│ │ ├── exception.py
│ ├── orders
│ │ ├── api.py
│ │ ├── errors.py
│ │ ├── exceptions.py
# documents/exception.py
DocumentNotFoundExeption
DocAlreadyExistsException
DocModificationException
#line_item/exception.py
LineItemNotFoundExeption
LineItemAlreadyExistsException
LineItemModificationException
# orders/exception.py
OrderNotFoundExeption
OrderAlreadyExistsException
OrderModificationException
MatchingServiceException
from matching import api as MatchingAPI
def create_invoice(invoice):
try:
MatchingAPI.post_invoice(invoice)
except MatchingServiceException as e:
exc = HttpExceptionFactory(e)
raise exc
2. Watching Coding a better world together gave me a whole new insight of writing clean code. It changed my perspective of looking at things completely. I'd recommend everyone of us to invest time in those lectures.
3. Being a JavaScript developer, our de-facto approach to writing code in any language is the functional paradigm of things, and OO is somewhere left behind.
I rediscovered OO design and I found it making my code easier to read and easier to change.