agentsclimarketplace

Applying composition over inheritance

Skill msewell/agent-stuff/skills/applying-composition-over-inheritance

Like everyone else, I'm sharing my agent stuff.

Install
npx -y skills add msewell/agent-stuff --skill applying-composition-over-inheritance

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Evaluates object-oriented designs to choose composition, inheritance, or algebraic data types. Produces decision rationales, refactoring plans, and review guardrails that reduce fragile base classes and subclass explosion. Use when reviewing class hierarchies, deciding between extends vs interfaces, refactoring inheritance-heavy code, introducing dependency-injected collaborators, or defining team conventions for object modeling.

SKILL.md

4.7 KB, as published. Nobody here has run it

Applying Composition Over Inheritance

Quick start

  1. Identify the variation axis: data variant, algorithm, cross-cutting behavior, or framework constraint.
  2. Default to composition unless inheritance is explicitly justified by substitutability and stability.
  3. If the variant set is closed and data-shaped, prefer an ADT/sealed type over open inheritance.
  4. Produce a concrete migration plan with tests, rollout order, and review checkpoints.

Reference routing (progressive disclosure)

Read only the file needed for the current task:

Default workflow

  1. Assess the current model

    • List base classes, subclass count, hierarchy depth, and known pain points.
    • Mark each variation as one of: data variant, behavior strategy, or infrastructure concern.
  2. Choose mechanism (default-first)

    • Choose composition for behavior variation, runtime swapping, or multi-axis change.
    • Choose ADT/sealed type for closed, data-carrying variants requiring exhaustive handling.
    • Choose inheritance only when all conditions hold: true is-a relation, Liskov-safe substitutability, and stable hierarchy.
  3. Design the target shape

    • Define minimal collaborator contracts; introduce interfaces/protocols where volatility, multiple implementations, or independent testing justify them.
    • Use constructor injection for required collaborators.
    • Keep inheritance depth shallow (target ≤2 below unavoidable framework bases).
  4. Plan migration incrementally

    • Add characterization tests first.
    • Introduce a seam (interface/facade) before replacing internals.
    • Migrate one subclass path at a time.
    • Remove dead hierarchy pieces only after parity checks pass.
  5. Validate and guardrail

    • Run checklist-driven review.
    • Add CI metrics/checks for DIT, override ratio, and decorator depth.
    • Capture explicit waivers for framework-required inheritance.

Non-negotiable defaults

  • Prefer composition by default.
  • Do not introduce inheritance purely for code reuse.
  • Keep collaborator interfaces narrow.
  • Avoid service locator patterns; dependencies must be explicit.
  • Treat deep decorator stacks (>3) and wide inheritance trees as design smells.

Output contract

When asked for guidance, return these sections in order:

  1. Decision: composition, ADT, or inheritance.
  2. Why: coupling, change axis, runtime needs, and testability implications.
  3. Design sketch: target interfaces/types and composition root.
  4. Migration steps: small reversible steps with validation points.
  5. Review/CI checks: checklist items and measurable thresholds.

Edge cases

  • Framework-mandated inheritance: keep inheritance at the boundary; compose internally.
  • Language lacks delegation sugar: use small helper generators/templates for forwarding.
  • Performance-critical paths: measure dispatch overhead before adding indirection.
  • Tiny stable domains: sealed inheritance may be acceptable when exhaustiveness is required.

Example

Input: “We have BaseReport with 12 subclasses and every new format adds another subclass. What should we do?”

Output (shape):

  • Decision: Replace hierarchy with composition (Strategy + optional Decorator).
  • Why: multi-axis variation and override-heavy subclasses indicate taxonomy drift.
  • Design sketch: ReportRenderer, HeaderPolicy, FooterPolicy, OutputFormatter interfaces composed in one ReportService.
  • Migration: characterization tests → strategy extraction → per-subclass migration → subclass deletion.
  • Guardrails: DIT warn >3, override ratio warn >0.5, decorator depth warn >3.

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.