Exercise 2: Fixing OrderRepositoryBad by Moving the Discount Out — Possible Solution ==================================================================== THE FIXED DATA LAYER, FOLLOWING THIS CHAPTER'S OWN OrderRepository SHAPE ------------------------------ class OrderRepositoryFixed: def __init__(self): self._orders = {} def save(self, order_id, items_total, is_loyalty_member): self._orders[order_id] = (items_total, is_loyalty_member) def get(self, order_id): items_total, is_loyalty_member = self._orders[order_id] return items_total # raw value only - no business rule here anymore def get_loyalty_status(self, order_id): items_total, is_loyalty_member = self._orders[order_id] return is_loyalty_member get() now returns exactly what was stored, unmodified - matching this chapter's own original (non-broken) OrderRepository's own get() exactly. A new get_loyalty_status() method exposes the RAW loyalty flag, still with no decision made about what to do with it. THE NEW BUSINESS LAYER, FOLLOWING THIS CHAPTER'S OWN OrderService SHAPE ------------------------------ class OrderBillingService: def __init__(self, repository): self.repository = repository def get_discounted_total(self, order_id): raw_total = self.repository.get(order_id) is_loyalty_member = self.repository.get_loyalty_status(order_id) if is_loyalty_member: return raw_total * 0.9 return raw_total The discount decision now lives here, in a business-layer class, not inside the data layer's own get(). VERIFYING audit_raw_total() NOW GETS THE TRUE RAW VALUE ------------------------------ audit_raw_total (should be true raw 100): 100 Fixed - this chapter's own audit_raw_total() function, completely unchanged, now correctly receives 100, not 90.0 like it did against the original OrderRepositoryBad. VERIFYING THE BILLING SERVICE STILL APPLIES THE DISCOUNT CORRECTLY ------------------------------ billing service discounted total (should be 90.0): 90.0 The discount still gets applied correctly for callers that actually want it - it just now happens in the business layer, where a caller has to explicitly ask for OrderBillingService.get_discounted_total() rather than getting it forced on them by every call to get(). WHY THIS WORKS AS AN ANSWER ------------------------------ The fix follows this chapter's own established Repository/Service split exactly, moving the misplaced business rule out of the data layer without losing it - both the "audit gets the true raw value again" claim and the "the discount still works correctly for callers that want it" claim are verified directly, confirming the fix repairs the original bug without introducing a new one.