Skip to content
Agentmart
Submit a tool

simplify-abstractions

Evaluate abstractions and inheritance for over-coupling.

Skill by nitrictech

IndexedMIT★ 1
Write a review

Chalk Labs

Need help deploying simplify-abstractions?

Chalk Labs sets up agents like this inside real teams: connected to your tools, tested on your data, with a human in the loop where it matters.

Book a call

Install

Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.

npx agentmarket install skill/nitrictech-simplify-abstractions

Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.

Get the weekly diff

The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.

We use your email only for this newsletter. Privacy

About

Evaluate abstractions and inheritance for over-coupling. Simplify by removing premature abstractions, replacing inheritance with composition, and using interfaces only when justified.

No reviews yet. Installed it? Reviews come from verified installers only. How reviews work

Permissions

What this skill can do and what it asks for, from its SKILL.md. Checked Oct 25, 2026.

Tools
No tools found
Secrets
None asked for
Install scripts
None found

Network hosts it talks to 1

  • codeload.github.com · found in install command

Files it touches

  • ~/.claude/skills/simplify-abstractions

Tools it pre-approves 5

From allowed-tools in SKILL.md: the agent may use these without asking you each time.

  • Read,
  • Edit,
  • Grep,
  • Glob,
  • Bash

What's inside

Skill name
simplify-abstractions
Description
Evaluate abstractions and inheritance for over-coupling. Simplify by removing premature abstractions, replacing inheritance with composition, and using interfaces only when justified.
License
MIT
Allowed tools
Read,, Edit,, Grep,, Glob,, Bash
Instructions
440 lines in SKILL.md · view on GitHub

Before installing

  • Pre-approves any shell command

Files (1)

  • SKILL.md

SKILL.md (first lines)

# Simplify Abstractions

When invoked, review the specified code for over-abstraction, premature interfaces, and problematic inheritance hierarchies. Identify coupling introduced by abstractions that do not earn their keep. Recommend and apply simplifications: remove unjustified abstractions, replace inheritance with composition, and introduce interfaces only where the coupling cost is justified by real value.

If the user has not specified a scope (file or directory), ask them which file or directory to focus on before proceeding.

## Core Rules: Abstraction Tradeoffs

1. **Every abstraction adds coupling.** For every bit of abstraction you add, you increase coupling equally. The coupling cost must be justified by concrete value, not theoretical future value.

2. **Do not abstract just because code looks similar.** Two classes that happen to share a field assignment or a method name are not necessarily candidates for a shared parent or interface. Similarity alone is insufficient justification.

3. **An abstraction is NOT worth it when:**
   - There are only 1-2 implementations.
   - The shared code is trivial (assigning a variable, calling a single method).
   - The if-statement or switch selecting between implementations is simple and localized to one place.
   - The coupling constrains future changes with no offsetting benefit.

4. **An abstraction IS worth it when:**
   - There are 3 or more implementations (or strong evidence a third is imminent).
   - You need to defer or repeat usage -- e.g., a scheduler, retry mechanism, or pipeline that invokes the abstraction at a different time or place from where the decision was made.
   - The decision of *which* implementation to use and the *usage* of that implementation are far apart in the code (different modules, different request phases, different lifecycle stages).

5. **A little code duplication is preferable to premature coupling.** Duplicated code is independent -- you can change one copy without risking the other. Coupled code must change together, and the coupling may constrain changes you haven't anticipated yet.

## Core Rules: Inheritance vs. Composition

6. **Inheritance couples the child to the parent's entire structure.** Not just the methods you want to reuse, but all the parent's fields, lifecycle, and assumptions. The child inherits everything, whether it makes sense or not.

7. **Inheritance forces children to implement or inherit methods that may be irrelevant.** If a child does not need `load()` and `save()` but the parent declares them abstract, the child is forced to provide dummy implementations that throw exceptions or return null -- a sign that the hierarchy is wrong.

8. **Inheritance breaks when requirements change.** Adding a new axis of variation (e.g., an image that can be drawn on but does not come from a file) requires restructuring the entire hierarchy, breaking all existing subclasses and their consumers. Change is the enemy of inheritance.

9. **Prefer composition.** Separate concerns into independent classes. Each class represents one capability. Combine classes by passing them as parameters (dependency injection) rather than bundling them through inheritance.

10. **Use interfaces (not parent classes) for abstraction.** When you genuinely need polymorphism -- calling a method without knowing which implementation runs -- use an interface. Interfaces define only the critical contract methods and are lightweight. Parent classes share everything by default, making them rigid and expensive to change.

11. **If inheritance is truly unavoidable** (e.g., framework requirement, or 100+ classes needing identical boilerplate where refactoring the plugin model is prohibitively expensive):
    - Avoid protected variables with direct access.
    - Create an explicit protected API -- specific methods that subclasses are meant to override.
    - Make everything else `private`, `final`, or `sealed`.
    - This prevents bugs from subclasses making assumptions about parent internals.

## Procedure

1. **Identify inheritance hierarchies.** For each hierarchy, assess:
   - How many subclasses exist?
   - Are any subclasses forced to implement irrelevant methods (throwing `NotImplementedException`, returning null, providing empty implementations)?
   - Could a new reasonable requirement break the hierarchy?
   - If yes to any → flag for refactoring to composition.

2. **Identify shared interfaces and abstract classes.** For each, count implementations:
   - Fewer than 3 implementations → evaluate whether the coupling is justified by a concrete need (deferred usage, decision/usage separation, testability).
   - If not justified → flag for possible removal (inline the abstraction).

3. **Identify parent classes sharing trivial code.** If a parent class exists only to share one field or one simple method → flag. The coupling cost exceeds the saved duplication.

4. **Refactor inheritance to composition.** For each flagged hierarchy:
   - Remove the parent class.
   - Extract reusable behavior into standalone classes.
   - Have the former subclasses accept these standalone classes as dependencies (constructor parameters).
   - Replace parent-class abstractions with focused interfaces containing only the methods callers actually use.

5. **Remove premature abstractions.** For interfaces with 1-2 implementations and no deferred/repeated usage:
   - Remove the interface.
   - Let the concrete classes stand alone.
   - Use a simple if-statement or switch at the call site.
   - Explain to the user when the abstraction *would* become justified (e.g., "if a third notification channel is added, reintroduce the interface").

6. **Present changes** with a brief explanation of why each abstraction was simplified and when it might be worth re-introducing.

## Adapt to the User's Language

Apply composition using the idioms of the user's language. In languages without interfaces (Python, JavaScript), use protocols, duck typing, or simple function parameters. In languages with explicit interfaces (Java, C#, Go, TypeScript), use interface types. In functional languages, use higher-order functions or type classes.

---

## Examples

### Example A: Premature Interface Removal

An interface with only two implementations, used in one place behind a simple if-statement:

**Before:**

```typescript
interface NotificationSender {
    send(userId: string, message: string): Promise<void>;
}

class EmailSender implements NotificationSender {
    constructor(private smtpConfig: SmtpConfig) {}

    async send(userId: string, message: string): Promise<void> {
        const email = await lookupEmail(userId);
        await this.smtpClient.send(email, message);
    }
}

class SmsSender implements NotificationSender {
    constructor(private twilioKey: string) {}

    async send(userId: string, message: string): Promise<void> {
        const phone = await lookupPhone(userId);
        await this.twilioClient.send(phone, message);
    }
}

// Factory
function createNotificationSender(channel: string): NotificationSender {
    if (channel === "email") return new EmailSender(config.smtp);
    if (channel === "sms") return new SmsSender(config.twilioKey);
    throw new Error(`Unknown channel: ${channel}`);
}

// Usage -- only one call site in the entire codebase
async function notifyUser(userId: string, message: string, channel: string) {
    const sender = createNotificationSender(channel);
    await sender.send(userId, message);

From nitrictech/skills, MIT.

Signals

Stars
1
Forks
0
Open issues
0
Last commit (this folder)
Apr 13, 2026 (6 months ago)

From GitHub (fetched Oct 24, 2026).

Details

License
MIT
First seen
Oct 24, 2026
Last checked
Oct 24, 2026

More from nitrictech

Done for you

Rather not set it up yourself?

Chalk Labs scopes, builds and runs agents for your team: the task audit, the eval harness, the integrations and the weekly ops report. Fixed scope, priced before we start.

See how we build AI agents →Read the case studies

Chalk Labs is a two-founder AI and growth studio. We build AI agents, CRMs and MVPs for Web3 and AI companies, and have shipped 50+ product and token launches.

launches shipped
50+
launches shipped
media placements
500+
media placements
founders on every account
2
founders on every account

Press we've placed: Forbes · CoinDesk · Decrypt · Cointelegraph · The Block

Rahil Jain, Co-founder, Chalk Labs. Ex-Goldman Sachs engineer. You talk to the person who builds it.

Get simplify-abstractions running in your business

Tell us what you want to automate. A founder replies within one working day with a plan, not a pitch deck.

Goes to the Chalk Labs founders, not the newsletter. Privacy

Need help deploying simplify-abstractions?

CallGet help
Cite this page

simplify-abstractions skill. Agent Mart. https://agentmart.dev/skills/nitrictech-simplify-abstractions (last updated 2026-10-24)