inline-singleton

star 0

Apply Inline Singleton when you see Global Data, Inline Function, Remove Dead Code. Constructor signatures carry every dependency the class uses; the agent reads one signature to enumerate what the class touches instead of grepping for static accessor calls across the codebase.

wallacedrew By wallacedrew schedule Updated 6/1/2026

name: inline-singleton description: Apply Inline Singleton when you see Global Data, Inline Function, Remove Dead Code. Constructor signatures carry every dependency the class uses; the agent reads one signature to enumerate what the class touches instead of grepping for static accessor calls across the codebase.

Apply: 75 — Inline Singleton

Announce first: name the chain of refactorings pointing at Inline Singleton and that you're applying it before the next edit. The user reads the announcement as your contract.

Or decline first: if you don't see a chain pointing at Inline Singleton, name the decline type — no chain, taste call, cost-benefit, constraint-blocked, or insufficient context.

Symptom: Singleton accessors (Class.getInstance()) hide the agent's view of which classes depend on the collaborator. The agent must grep the codebase for every static-accessor call to know the real dependency graph; test setup requires resetting global state between cases.

Goal: Constructor signatures carry every dependency the class uses; the agent reads one signature to enumerate what the class touches instead of grepping for static accessor calls across the codebase.

// Before:
// Singleton machinery for what is effectively a regular collaborator.
class Logger {
  static instance = null;
  static getInstance() {
    if (!Logger.instance) {
      Logger.instance = new Logger();
    }
    return Logger.instance;
  }
  constructor() {
    this.entries = [];
  }
  log(message) {
    this.entries.push({ time: Date.now(), message });
  }
}

// Client code reaches into the global accessor.
function processOrder(order) {
  Logger.getInstance().log(`Processing order ${order.id}`);
  // ...
}

// After:
// Regular class; callers receive a logger through their constructor.
class Logger {
  constructor() {
    this.entries = [];
  }
  log(message) {
    this.entries.push({ time: Date.now(), message });
  }
}

class OrderProcessor {
  constructor(logger) {
    this.logger = logger;
  }
  processOrder(order) {
    this.logger.log(`Processing order ${order.id}`);
    // ...
  }
}

Example source: Illustrative example written for this site, adapted from Kerievsky's pattern description in Refactoring to Patterns (Addison-Wesley, 2004), chapter 5. The book demonstrates inlining a configuration Singleton; this JavaScript version inlines a Logger Singleton in favour of constructor injection — same payoff: testability and explicit dependencies.

Pressure: Static accessors defeat static call-graph analysis at the dependency level; the agent cannot infer from a class's interface what it actually uses. Test-order flakiness from shared static state is invisible to local reasoning and only surfaces under CI.

Tradeoff: Inlining pushes wiring code outward; the agent must reason about a composition root or DI container to verify production behaviour. Without one, the inlining may produce duplicated wiring across callers that the agent now has to verify match.

Relief: Every dependency the class uses appears in its constructor signature; the agent enumerates dependencies from one file load instead of grepping for static-accessor calls across the codebase.

Trap: Inlining without first establishing a composition root produces new Logger() calls scattered across consumer files, each creating an independent instance; generated code that assumes a shared logger picks up an isolated one and the divergence ships.

Triggered by: Global Data (smells), Inline Function (refactorings), Remove Dead Code (refactorings)

Install via CLI
npx skills add https://github.com/wallacedrew/ritl --skill inline-singleton
Repository Details
star Stars 0
call_split Forks 0
navigation Branch main
article Path SKILL.md
More from Creator