Praveen Shirali
Test Architect, RiptideIO
BangPypers MeetUp - December 17th 2016, Bangalore, India.
Car
|
|----\ Exterior
| |-- Body
| |-- Wheels
| |...
|
|----\ Interior
| |-- Dashboard
| |-- Steering Assembly
| |...
|
|----\ EngineBay
| |-- Engine
| |...
|
|----\ Some other components...
...
SomeOOPApplication
|
|----\ Frontend
| |-- Frontend Dependency 1
| |-- Frontend Dependency 2
| |...
|
|----\ Server
| |-- Server Dependency 1
| |-- It's dependency ...
| |...
|
|----\ Database
| |-- DB Dependency 1
| |...
|
|----\ Some other components...
...
from app.frontend import Frontend
from app.server import Server
from app.database import Database
class RockSolidApplication(object):
def __init__(self):
self.frontend = FrontEnd()
self.server = Server()
self.database = Database()
def run(self):
...
...
if __name__ == "__main__":
app = RockSolidApplication()
app.run()
from app.frontend import Frontend
from app.server import Server
from app.database import Database
class RockSolidApplication(object): <-- Can't reuse application for something else
def __init__(self):
self.frontend = FrontEnd() <-- Dependencies are built from within
self.server = Server() <-- Can't introduce other/better deps
self.database = Database() <-- Bring your own deps. Hard to share.
def run(self):
...
...
if __name__ == "__main__":
app = RockSolidApplication() <-- Rock solid. Will this float on water?
app.run()
from app.frontend import Frontend
from app.server import Server
from app.database import Database
class RockSolidApplication(object):
def __init__(self, frontend, server, database):
self.frontend = frontend
self.server = server
self.backend = database
def run(self):
...
...
if __name__ == "__main__":
app = RockSolidApplication(
frontend=FrontEnd(),
server=Server(),
database=Database()
)
app.run()
from app.frontend import PrettierFrontend
from app.server import BetterServer
from app.database import FasterDatabase
class RockSolidApplication(object):
def __init__(self, frontend, server, database):
self.frontend = frontend
self.server = server
self.backend = database
def run(self):
...
...
if __name__ == "__main__":
app = RockSolidApplication(
frontend=PrettierFrontEnd(), <-- replace with better components
server=BetterServer(), <-- or replace them with test doubles
database=FasterDatabase() <-- mocks/stubs/etc for testing
)
app.run()
from app.frontend import PrettierFrontend
from app.server import BetterServer
from app.database import FasterDatabase
from app.base import BaseApplication
class AirborneApplication(BaseApplication): <-- this can fly!
...
class BuoyantApplication(BaseApplication): <-- this floats on water
...
class RockSolidApplication(BaseApplication): <-- this doesnt
...
if __name__ == "__main__":
app = BuoyantApplication(
frontend=PrettierFrontEnd(mermaids=True),
server=BetterServer(food="unlimited", drinks="bottomless"),
database=FasterDatabase(i_haz_nos=True)
)
app.run()
from darshini.kitchen.steamcooker import Idly
from darshini.kitchen.wetgrinder import Chutney
from darshini.kitchen.largebucket import Sambar
from darshini.self_service.counter import Plate, Spoon, Fork, Bowl
from bangalore.citizen import Me
from datetime import datetime
if __name__ == "__main__":
one_plate_idly = Plate()
one_plate_idly.add(Spoon(), Fork())
one_plate_idly.add(Idly(), Idly())
one_plate_idly.add(Bowl(Sambar()))
one_plate_idly.add(Bowl(Chutney()))
me = Me() # singleton
me.eat(one_plate_idly, at=datetime.now())
from darshini.service_wing import get_waiter
from darshini.service_wing import Menu
from bangalore.citizen import Me
from datetime import datetime
if __name__ == "__main__":
me = Me() # singleton
waiter = get_waiter() # returns a waiter who is available
menu = Menu()
me.see(menu.page1)
idly_plate = me.say(menu.page1.idly_plate, to=waiter) # blocking call
me.eat(idly_plate)
assert me.status == "Happy!"
from aglyph.context import XMLContext
from aglyph.asssembler import Assembler
if __name__ == "__main__":
context = XMLContext("app-context.xml")
assembler = Assembler(context)
# this will build app.core.Application and inject all 3 dependencies
app = assembler.assemble("my-app")