Design by Contract (Java)

Context: FIT2099_MOC · Bertrand Meyer’s approach — client & supplier agree mutual obligations · the formal basis of LSP · a framework for correctness, debugging and QA

Quick Revision

  • 🎯 Objective: specify each method as a contract — what the client must guarantee (precondition) and what the supplier then guarantees (postcondition) âž” confidence the code is correct.
  • 📦 Core Components: precondition (client’s duty, before) · postcondition (supplier’s duty, after) · invariant (true always, before & after every method).
  • ⚡ Key Constraint: who’s to blame on a breach — a broken precondition is the client’s bug (throw an exception); a broken postcondition/invariant (when preconditions held) is the supplier’s bug (an assertion).

📝 How It Works

1. The three assertions

  • Precondition âž” what the client must ensure is true before calling the supplier’s method; violated ⇒ the client has a bug.
  • Postcondition âž” what the supplier guarantees is true after the method runs (if the precondition held); violated ⇒ usually the supplier has a bug (but not always — transient causes: network outage, server down, disk/memory).
  • Invariant âž” a condition the class keeps true at all times to stay valid — holds both before and after every supplier method.
  • Who writes it âž” the supplier’s designer defines the contract; it’s communicated via Javadoc, code comments, and executable statements (exceptions/assertions).

2. Obligations & Benefits (airport metaphor)

ObligationsBenefits
Clientensure preconditions (be at MEL 30 min early, allowable luggage, pay)may enjoy the postcondition (reach Sydney)
Supplierensure the postcondition (bring client to Sydney)may assume the precondition (no duty to carry a late/unpaid/over-luggage client)

⚙️ Breach Handling & Fail-Fast

  • Fail Fast âž” if code detects something wrong, fail immediately so the developer sees where and when; code that ignores warnings fails later, far from the cause, and is very hard to debug.
  • Cost curve âž” the cost of fixing a bug rises exponentially the later it’s found (requirements → design → test → live) — DbC catches breaches early.
  • Java note âž” assertions are disabled by default in the JVM (fine — you fix your own bugs before shipping); client-facing failures use exceptions.

⚖️ Subcontracting = Liskov Substitution

  • Scenario âž” Alice (base class + contract) can send Bob (subclass) to do the job; the client accepts Bob iff he honours Alice’s contract.
  • Rule âž” a subclass may substitute for its base if and only if its preconditions are the same or weaker AND its postconditions are the same or stronger.
    • Bob can’t demand a bigger deposit or an earlier start (that would be a stronger precondition) — rejected.
    • Bob can ask for less upfront / more days (weaker precondition) and deliver a stronger, longer-lasting driveway (stronger postcondition) — accepted; the client needn’t even know Bob exists.
  • This is the LSP âž” substitutability is exactly “weaker-or-equal preconditions, stronger-or-equal postconditions”.

đź§  Active Recall