Combinatorial subclass explosion or feature-flag-laden monoliths the agent must verify exhaustively on every behavioural change. 2^N combinations means N×(N-1) feature-interaction cells the agent reasons about; feature flags inside one class make the class's behaviour parametric on flag combinations.
N small wrapper classes the agent reads one at a time. Feature composition is explicit in the construction expression; each wrapper's behaviour is its own one-file unit; tests cover each wrapper × wrappee combination compositionally.
Before the pattern
class EmailNotifier {send(message) { /* email */ }}class EmailAndSmsNotifier {send(message) { /* email + sms */ }}class EmailAndSlackNotifier {send(message) { /* email + slack */ }}class EmailAndSmsAndSlackNotifier {send(message) { /* email + sms + slack */ }}// N channels → 2^N notifier classes. Adding 'Discord' doubles the// hierarchy. Each new combination repeats the orchestration logic.
After the pattern
class EmailNotifier {send(message) { /* email */ }}class SmsDecorator {constructor(wrapped) { this.wrapped = wrapped; }send(message) {this.wrapped.send(message);/* also send sms */}}class SlackDecorator {constructor(wrapped) { this.wrapped = wrapped; }send(message) {this.wrapped.send(message);/* also post to slack */}}// Compose at the call site:const notifier = new SlackDecorator(new SmsDecorator(new EmailNotifier()));notifier.send('Build failed');// N channels → N classes. Adding 'Discord' = 1 new decorator.
Combinatorial hierarchy growth turns 'add a feature' into 'edit every existing combination'. Feature-flag monoliths concentrate the verification burden into one mega-class whose behaviour the agent must trace through every flag-permutation. Both shapes consume context budget that should be spent on the calling code.
Wrapping chains are stack-allocated indirection the agent must navigate per operation. Tracing why `notifier.send(msg)` produced a specific side effect requires the agent to walk the wrapping chain — and the chain's composition is dynamic, set at the construction site that may live in a different module.
Per-feature edits scope to one decorator file; verification scales linearly with feature count. Stack traces map decorators 1:1 to call frames; the agent can localize bugs by reading one wrapper at a time. Compositional tests cover combinations without enumerating them.
Decorators whose semantics depend on wrapping order (RetryDecorator(LoggingDecorator(X)) vs LoggingDecorator(RetryDecorator(X))) force the agent to verify order-correctness on every construction site. The construction expression becomes part of the spec; PR review must catch wrong-order regressions the type system cannot.