How the Liskov Substitution Principle Clarifies Delegation in Organizations

"You can safely leave it to this person"—this is a phrase often heard in business settings. But in reality, it's not uncommon for problems to arise after a handover. I once experienced this myself when I took over a client account from my manager. I was explicitly told to act autonomously, so I made decisions based on what I thought was best given the client’s situation. In doing so, I ended up modifying the clear guidelines passed down from my manager. For example, while working in corporate sales proposing system solutions to various companies: I was supposed to follow up on proposal progress every week, but I waited two weeks thinking “the client seems busy” I failed to push back on some “nice-to-have” requirements and brought them back to the team These decisions backfired. The process took too long, yielded no results, and the deal didn’t close. My manager gave me direct feedback: “You shouldn't change the criteria on your own.” That’s when I realized I had misunderstood what it really meant to “act autonomously.” This experience resonated deeply with a software design principle I later learned—the Liskov Substitution Principle (LSP). LSP states that a subclass should be substitutable for its superclass without altering the correctness of the program. In a business context, if a subordinate is to act in place of a superior, it’s essential to clearly identify the preconditions, postconditions, and invariants—what must be preserved and what can be improved. I made decisions without clarifying those boundaries. In software, when a subclass extends a superclass without breaking its behavioral contract, the system remains stable. The same applies to organizations: when roles are handed down from managers to subordinates, if expectations, deliverables, and standards aren't preserved, trust and results across the team can collapse. LSP, therefore, is not just a principle for software design—it also offers practical insight into how we structure role transitions and delegation within organizations. What is the LSP? Many of you may already be familiar with it, but the Liskov Substitution Principle (LSP) is an object-oriented design principle proposed by Barbara Liskov in 1987. "If S is a subtype of T, then objects of type T may be replaced with objects of type S without altering the correctness of the program." To uphold this principle, the following conditions are crucial. Let’s look at them through the example of an airline mileage program. Preconditions A subclass must require the same or weaker conditions than its superclass. An operation allowed in the superclass must not be disallowed in the subclass. Postconditions A subclass must guarantee the same or stronger outcomes than its superclass. It’s fine for a subclass to return more than what was guaranteed by the superclass, but never less. Invariants Any conditions that are always true in the superclass must remain true in the subclass. Subclasses may strengthen the rules, but must not violate or weaken them. Concrete Design Example Here, we'll use a mileage service as a case study to illustrate how the three conditions of the LSP can be applied to the design of a customer class. class Customer: def book_flight(self, seat_class): assert seat_class in ["economy", "business"] # Precondition return f"Flight booked in {seat_class} class" def get_mileage(self): return 100 # Postcondition: always grants 100 miles def is_active(self): return True # Invariant: always remains active class RoyalCustomer(Customer): def book_flight(self, seat_class): # Looser precondition: allows first class bookings assert seat_class in ["economy", "business", "first"] return f"Royal booking in {seat_class} class" def get_mileage(self): # Stronger postcondition: grants more miles return 300 def is_active(self): # Maintains the same invariant return super().is_active() As shown, the RoyalCustomer class can be substituted for the Customer class without breaking the system—and in fact, it enhances functionality. This is an example of a design that respects the Liskov Substitution Principle. Preconditions Customer: Only "economy" and "business" classes can be booked RoyalCustomer: Also allows "first" class → Loosening the precondition (✔ OK) Postconditions Customer: Grants 100 miles RoyalCustomer: Grants 300 miles → Enhancing the outcome (✔ OK) Invariants Customer: is_active() is always True RoyalCustomer: Maintains is_active() in the same way → Preserves the invariant (✔ OK) LSP-Like Behavior in the Sales Field The relationship between managers and their subordinates closely resembles class inheritance. Preconditions Manager: Only attends meetings where decision-makers are present Subordinate: Will visit ev

Apr 15, 2025 - 02:39
 0
How the Liskov Substitution Principle Clarifies Delegation in Organizations

"You can safely leave it to this person"—this is a phrase often heard in business settings. But in reality, it's not uncommon for problems to arise after a handover.

I once experienced this myself when I took over a client account from my manager. I was explicitly told to act autonomously, so I made decisions based on what I thought was best given the client’s situation. In doing so, I ended up modifying the clear guidelines passed down from my manager. For example, while working in corporate sales proposing system solutions to various companies:

  • I was supposed to follow up on proposal progress every week, but I waited two weeks thinking “the client seems busy”
  • I failed to push back on some “nice-to-have” requirements and brought them back to the team

These decisions backfired. The process took too long, yielded no results, and the deal didn’t close. My manager gave me direct feedback: “You shouldn't change the criteria on your own.” That’s when I realized I had misunderstood what it really meant to “act autonomously.”

This experience resonated deeply with a software design principle I later learned—the Liskov Substitution Principle (LSP). LSP states that a subclass should be substitutable for its superclass without altering the correctness of the program.

In a business context, if a subordinate is to act in place of a superior, it’s essential to clearly identify the preconditions, postconditions, and invariants—what must be preserved and what can be improved. I made decisions without clarifying those boundaries.

In software, when a subclass extends a superclass without breaking its behavioral contract, the system remains stable. The same applies to organizations: when roles are handed down from managers to subordinates, if expectations, deliverables, and standards aren't preserved, trust and results across the team can collapse.

LSP, therefore, is not just a principle for software design—it also offers practical insight into how we structure role transitions and delegation within organizations.

What is the LSP?

Many of you may already be familiar with it, but the Liskov Substitution Principle (LSP) is an object-oriented design principle proposed by Barbara Liskov in 1987.

"If S is a subtype of T, then objects of type T may be replaced with objects of type S without altering the correctness of the program."

To uphold this principle, the following conditions are crucial. Let’s look at them through the example of an airline mileage program.

Preconditions

  • A subclass must require the same or weaker conditions than its superclass.
  • An operation allowed in the superclass must not be disallowed in the subclass.

Postconditions

  • A subclass must guarantee the same or stronger outcomes than its superclass.
  • It’s fine for a subclass to return more than what was guaranteed by the superclass, but never less.

Invariants

  • Any conditions that are always true in the superclass must remain true in the subclass.
  • Subclasses may strengthen the rules, but must not violate or weaken them.

Concrete Design Example

Here, we'll use a mileage service as a case study to illustrate how the three conditions of the LSP can be applied to the design of a customer class.

class Customer:
    def book_flight(self, seat_class):
        assert seat_class in ["economy", "business"]  # Precondition
        return f"Flight booked in {seat_class} class"

    def get_mileage(self):
        return 100  # Postcondition: always grants 100 miles

    def is_active(self):
        return True  # Invariant: always remains active

class RoyalCustomer(Customer):
    def book_flight(self, seat_class):
        # Looser precondition: allows first class bookings
        assert seat_class in ["economy", "business", "first"]
        return f"Royal booking in {seat_class} class"

    def get_mileage(self):
        # Stronger postcondition: grants more miles
        return 300

    def is_active(self):
        # Maintains the same invariant
        return super().is_active()

As shown, the RoyalCustomer class can be substituted for the Customer class without breaking the system—and in fact, it enhances functionality. This is an example of a design that respects the Liskov Substitution Principle.

Conditions

Preconditions

  • Customer: Only "economy" and "business" classes can be booked
  • RoyalCustomer: Also allows "first" class → Loosening the precondition (✔ OK)

Postconditions

  • Customer: Grants 100 miles
  • RoyalCustomer: Grants 300 miles → Enhancing the outcome (✔ OK)

Invariants

  • Customer: is_active() is always True
  • RoyalCustomer: Maintains is_active() in the same way → Preserves the invariant (✔ OK)

LSP-Like Behavior in the Sales Field

The relationship between managers and their subordinates closely resembles class inheritance.

Preconditions

  • Manager: Only attends meetings where decision-makers are present
  • Subordinate: Will visit even at the staff level → Broadening the scope of engagement = loosening the precondition (✔ OK)

Postconditions

  • Manager: Presents a quote and clarifies the next action
  • Subordinate: Presents a quote and nails down contract details for the next visit → Turning next steps into concrete actions = enhancing the outcome (✔ OK)

Invariants

  • Manager: Always responds fairly and politely, even before a contract is signed
  • Subordinate: Responds to all inquiries within one business day regardless of contract status → Strengthening response standards while preserving the original invariant (✔ OK)

Examples of Violations (NG cases)

  • “I won’t take any action unless the client reaches out first.”

    → Making preconditions stricter (✘ Violation)

  • “We sent the quote, so we’re waiting to hear back.”

    → Weakening postconditions (✘ Violation)

  • “Whether or not we build trust depends on the situation.”

    → Breaking the invariant (✘ Violation)

Why the LSP Applies to Organizations Too

Software systems and business organizations share several key similarities:

  • They operate in a hierarchical structure (e.g., parent → child, manager → subordinate)
  • They involve the delegation of abstract contracts and responsibilities
  • They are designed for efficiency based on the assumption of substitutability

In other words, the principles behind software design can also be applied to how people and organizations function. Through my experience in sales—particularly the failures—I intuitively came to understand that freedom of action must be balanced with behavioral contracts.

The Liskov Substitution Principle put this into clear and formal language. It struck me deeply. This principle isn’t just about keeping systems stable—it can serve as a powerful guide for human decision-making as well.

References