githubEdit

12. Design Coupon System

Difficulty: Medium Topics: Strategy Pattern, Chain of Responsibility, Composite Pattern Key Concepts: Decoupling validation logic from calculation logic.

Phase 1: Requirements Gathering

Goals

  • Design a flexible coupon system for an e-commerce platform.

  • Support various discount types (Percentage, Flat, Free Initial).

  • Support complex validation rules (Min Cart Value, Specific Category, Expiry).

1. Who are the actors?

  • User: Applies coupons to their cart.

  • Admin: Creates new coupons and rules.

  • System: Validates and calculates final price.

2. What are the must-have features? (Core)

  • Discount Types:

    • Percentage Off (e.g., "10% off up to $50").

    • Flat Amount Off (e.g., "$10 off").

  • Constraints:

    • Minimum Order Value.

    • Category restricted (e.g., "Electronics only").

    • Usage limits (e.g., "Once per user").

3. What are the constraints?

  • Extensibility: Marketing team needs to add new rules without code changes (ideally) or with minimal changes.

  • Performance: Coupon application should be instant (< 100ms).


Phase 2: Use Cases

UC1: Apply Coupon

Actor: User Flow:

  1. User enters Coupon Code (e.g., "SUMMER10").

  2. System fetches Coupon configuration.

  3. System runs all Validation Rules (Constraints).

  4. If valid, System calculates Discount amount using Reward Strategy.

  5. System returns Discounted Total.

UC2: Admin Creates Coupon

Actor: Admin Flow:

  1. Admin defines Code ("SAVE20").

  2. Admin selects Reward Type (Percentage: 20%).

  3. Admin attaches Constraints (MinCart: 100, Expiry: 2025-12-31).

  4. System saves Coupon structure.


Phase 3: Class Diagram

Step 1: Core Entities

  • Coupon: The main entity containing Code, Reward, and Constraints.

  • Reward: Strategy for calculating discount.

  • Constraint: Condition that must be met.

  • Cart: Context object containing Items.

UML Diagram

spinner

Phase 4: Design Patterns

1. Strategy Pattern

  • Description: Defines a family of algorithms, encapsulates each one, and makes them interchangeable.

  • Why used: Discounts can be calculated in many ways (Flat off, Percentage off, BOGO). Strategy encapsulates this calculation logic in separate classes (FlatReward, PercentageReward), making it easy to add new reward types.

2. Composite Pattern

  • Description: Composes objects into tree structures to represent part-whole hierarchies.

  • Why used: A Coupon is valid only if all its constraints are met. We can treat a list of constraints as a single "Composite Constraint" that passes only if all children pass.


Phase 5: Code Key Methods

Java Implementation


Phase 6: Discussion

Extensibility

Q: How to add "Buy One Get One" (BOGO)?

  • A: "Create a BogoReward class implementing Reward. The calculate(Cart) method would iterate items to find pairs and deduct the price of the cheapest item."

Concurrency

Q: How to handle 'First 100 Users Only'?

  • A: "This requires a GlobalCountConstraint. It would need to interact with a centralized counter (like Redis INCR).

    • validate() checks Redis.get(coupon_code) < limit.

    • However, strictly enforcing exactly 100 concurrent requests is hard. We might allow slight overbooking or use Lua scripts in Redis for atomic check-and-increment."

Stacking

Q: Can we apply multiple coupons?

  • A: "Yes. The Cart manager could hold a list of Coupons. We can apply them sequentially. Order matters (Percentage after Flat vs Flat after Percentage)."


SOLID Principles Checklist

  • S (Single Responsibility): Constraint validates, Reward calculates, Coupon holds structure.

  • O (Open/Closed): New Rewards or Constraints can be added without modifying Coupon.

  • L (Liskov Substitution): All Constraints work interchangeably.

  • D (Dependency Inversion): Coupon depends on Reward interface, not specific implementation.

Last updated