Skip to main content

Conditional and Data Restructuring Clinic

This clinic exercises Cluster 4: Replace Conditional with Polymorphism, Introduce Parameter Object, Preserve Whole Object, Decompose Conditional, Consolidate Conditional Expression. The key skill is choosing the right move for the smell, and defending that choice.

Retrieval Prompts

  1. What is the recurrence rule for Replace Conditional with Polymorphism?
  2. What three signals say "introduce a parameter object"?
  3. When does Preserve Whole Object create a coupling you do not want?
  4. Name the difference between Decompose Conditional and Consolidate Conditional Expression.
  5. Why is a single switch not necessarily a smell?

Compare and Distinguish

  • Replace Conditional with Polymorphism vs Decompose Conditional (cross-function vs single-function)
  • State pattern vs subclass hierarchy (does the discriminator change over time?)
  • Introduce Parameter Object vs Preserve Whole Object (does the whole already exist?)
  • Consolidate Conditional Expression vs separate guard clauses (independent rules vs one rule with pieces)

Common Mistake Check

  1. "I saw one switch (type) and built a 4-class hierarchy."
  2. "I consolidated three conditions with ||, not realizing two of them had side effects."
  3. "I introduced a parameter object for 3 parameters that came from 3 unrelated call-site variables."
  4. "I preserved the whole User object into a function in the logging module."
  5. "I added isNotEligibleForDisability() and then kept the three original guards."

Mini Application

Clinic Case 1: Is It Polymorphism Time?

Given:

function plumage(bird) {
switch (bird.type) {
case 'EuropeanSwallow': return 'average';
case 'AfricanSwallow': return bird.numberOfCoconuts > 2 ? 'tired' : 'average';
case 'NorwegianBlueParrot':return bird.voltage > 100 ? 'scorched' : 'beautiful';
default: return 'unknown';
}
}

Search the codebase (pretend; design the search). Under what condition do you apply Replace Conditional with Polymorphism? Under what condition do you apply Decompose Conditional instead? Write the two-line decision rule.

Then: assuming another function airSpeedVelocity(bird) has the same switch, apply Replace Conditional with Polymorphism. Produce:

  • the Bird superclass and 3 subclasses
  • the factory birdFor(data)
  • unchanged behavior verified by test

Clinic Case 2: Parameter Object or Preserve Whole?

Given:

function amountInvoiced(customer, startDate, endDate) { /* ... */ }
function amountReceived(customer, startDate, endDate) { /* ... */ }
function amountOverdue (customer, startDate, endDate) { /* ... */ }

And separately:

const low  = room.daysTempRange.low;
const high = room.daysTempRange.high;
if (plan.withinRange(low, high)) alert("room temperature within range");

For each snippet, choose the move (Introduce Parameter Object vs Preserve Whole Object) and justify in two sentences. Then apply it.

Clinic Case 3: Decompose or Consolidate?

Given:

function carCharge(car) {
if (car.status === "retired") return 0;
if (car.mileage > 150000) return 0;
if (car.lastService === null) return 0;
const base = car.rate * (car.isHeavy ? 1.5 : 1.0);
const late = car.wasLate && car.isHeavy ? 50 : 0;
return base + late;
}

Apply Consolidate Conditional Expression on the three guards. Extract them into isNotEligible(car). Then apply Decompose Conditional on the "base" calculation. End with a function where the top reads like: if (isNotEligible(car)) return 0; return base(car) + lateFee(car);.

Clinic Case 4: Data Clump Scavenger Hunt

In code you work with, find three parameter lists that share a clump of 2 or more variables. For the most common clump, sketch the parameter object: name, fields, and one method that would migrate onto it from a caller.

Evidence Check

This clinic is complete only if:

  • you produced a written two-line decision rule for polymorphism vs decomposition
  • you applied each of the five moves in at least one case with before/after code
  • you identified at least one real data clump in your code and produced a parameter-object sketch
  • you can explain why the wrong move for a given smell is worse than no move at all