N copies of identical collection-management methods the agent must verify match on every edit. A bug fix in one copy must be ported to all others; the agent has no static guarantee the copies stayed consistent.
One Composite superclass the agent reads once and trusts thereafter. Sibling classes are short enough to load entirely in context; the agent verifies only the distinctive surface.
Before the refactoring
// Two sibling classes each carry the same line-item collection logic.class Order {constructor(customer) {this.customer = customer;this.lineItems = [];}addLineItem(item) { this.lineItems.push(item); }removeLineItem(item) {const index = this.lineItems.indexOf(item);if (index >= 0) this.lineItems.splice(index, 1);}total() { return this.lineItems.reduce((sum, i) => sum + i.amount, 0); }ship() { /* Order-specific */ }}class Invoice {constructor(customer, dueDate) {this.customer = customer;this.dueDate = dueDate;this.lineItems = [];}addLineItem(item) { this.lineItems.push(item); }removeLineItem(item) {const index = this.lineItems.indexOf(item);if (index >= 0) this.lineItems.splice(index, 1);}total() { return this.lineItems.reduce((sum, i) => sum + i.amount, 0); }markPaid() { /* Invoice-specific */ }}
After the refactoring
// Collection management lives once in a Composite superclass.class LineItemContainer {constructor(customer) {this.customer = customer;this.lineItems = [];}addLineItem(item) { this.lineItems.push(item); }removeLineItem(item) {const index = this.lineItems.indexOf(item);if (index >= 0) this.lineItems.splice(index, 1);}total() { return this.lineItems.reduce((sum, i) => sum + i.amount, 0); }}class Order extends LineItemContainer {ship() { /* Order-specific */ }}class Invoice extends LineItemContainer {constructor(customer, dueDate) {super(customer);this.dueDate = dueDate;}markPaid() { /* Invoice-specific */ }}
Duplicated collection logic across N siblings × M methods = N×M cells the agent must hold to verify consistency. The agent's edit budget on a single collection-method change is N times what it would be with the Composite in place.
Inheritance hides behaviour in the superclass that callers may not know to look for; the agent must traverse the class hierarchy to know what a sibling can do. Method resolution order issues complicate static reasoning when subclasses override partial behaviours.
Collection-handling logic lives at the Composite class at one file; sibling classes hold only their leaf-specific work; tests against the Composite cover the tree-walking logic without per-sibling duplication of the same setup.
A bloated Composite forces the agent to load a large superclass before reading any sibling. If sibling behaviours diverge later, the agent must constantly cross-check superclass methods against per-sibling overrides — context cost migrates from duplication to inheritance traversal.