Exercise 2: A Second New Discount Type — Possible Solution ==================================================================== THE NEW CLASS ------------------------------ class SilverDiscount(DiscountStrategy): def apply(self, price): return price * 0.85 Follows the same pattern as this chapter's own PlatinumDiscount - a new subclass of DiscountStrategy, nothing else touched. VERIFYING ALL FIVE EXISTING CLASSES STAYED UNCHANGED ------------------------------ PricingEngine unchanged: True DiscountStrategy unchanged: True NoDiscount unchanged: True GoldDiscount unchanged: True PlatinumDiscount unchanged: True Every one of the five classes that existed before this exercise's own extension - including PlatinumDiscount, which was itself the "new" class in this chapter's own original example - is confirmed byte- identical afterward. Extending the hierarchy a second time didn't require touching the first extension either. VERIFYING THE NEW DISCOUNT WORKS CORRECTLY ------------------------------ PricingEngine correctly applies the new SilverDiscount: 85.0 (expected 85.0) PricingEngine(SilverDiscount()).calculate(100) correctly returns 85.0 - and PricingEngine's own source was one of the five confirmed unchanged above. WHY THIS CONFIRMS OPEN/CLOSED HOLDS FOR REPEATED EXTENSION, NOT JUST ONE ------------------------------ This chapter's own finding showed the hierarchy staying closed for ONE extension (adding Platinum). This exercise confirms the SAME guarantee holds for a SECOND, independent extension (adding Silver) - and, critically, that the first extension doesn't need to be touched or even re-read to add the second one. Each new discount type is a fully self-contained addition; the hierarchy's own "closed for modification" property doesn't erode as more extensions accumulate. WHY THIS WORKS AS AN ANSWER ------------------------------ A second, genuinely new discount class is added using this chapter's own established pattern, all five now-existing classes (not just the originally-tested four) are verified unchanged, and the new discount's own correct behavior is verified through the confirmed-unmodified PricingEngine.