Before, ServiceA calls ServiceB directly and waits for a response, creating tight coupling. After, ServiceA publishes an event to an EventBus, and ServiceB listens and processes events independently, enabling loose coupling and asynchronous communication.
### Before: Direct synchronous call (tight coupling)
class ServiceA:
def call_service_b(self, data):
service_b = ServiceB()
response = service_b.process(data)
return response
class ServiceB:
def process(self, data):
return f"Processed {data}"
### After: Event-driven communication (decoupled)
class EventBus:
def __init__(self):
self.subscribers = []
def subscribe(self, handler):
self.subscribers.append(handler)
def publish(self, event):
for handler in self.subscribers:
handler(event)
class ServiceA:
def __init__(self, event_bus):
self.event_bus = event_bus
def do_something(self, data):
event = {'type': 'DataEvent', 'payload': data}
self.event_bus.publish(event)
class ServiceB:
def handle_event(self, event):
if event['type'] == 'DataEvent':
print(f"ServiceB processed: {event['payload']}")
# Setup
bus = EventBus()
service_b = ServiceB()
bus.subscribe(service_b.handle_event)
service_a = ServiceA(bus)
# Usage
service_a.do_something('my data')