yanko-belov

single-responsibility-principle

5
0
# Install this skill:
npx skills add yanko-belov/code-craft --skill "single-responsibility-principle"

Install specific skill from multi-skill repository

# Description

Use when creating or modifying classes, modules, or functions. Use when feeling pressure to add functionality to existing code. Use when class has multiple reasons to change.

# SKILL.md


name: single-responsibility-principle
description: Use when creating or modifying classes, modules, or functions. Use when feeling pressure to add functionality to existing code. Use when class has multiple reasons to change.


Single Responsibility Principle (SRP)

Overview

A class should have only one reason to change.

Every module, class, or function should have responsibility over a single part of functionality. If you can describe what a class does using "AND", it has too many responsibilities.

When to Use

  • Creating any new class, module, or service
  • Adding methods to existing classes
  • Reviewing code that "does multiple things"
  • Feeling pressure to "just add it here"

The Iron Rule

NEVER add functionality that introduces a second reason to change.

No exceptions:
- Not for "it's faster this way"
- Not for "it's just one more method"
- Not for "refactoring would take too long"
- Not for "my tech lead said so"
- Not for "it's already in production"

Violating SRP under pressure is still violating SRP.

Detection: The "AND" Test

Describe your class in one sentence. If it contains "AND", split it.

Description Verdict
"Handles user authentication" ✅ Single responsibility
"Handles authentication AND sends emails" ❌ Two responsibilities
"Manages orders AND processes payments AND tracks inventory" ❌ Three responsibilities

Detection: Reasons to Change

List why this class might need to change:

// ❌ BAD: UserManager - 4 reasons to change
class UserManager {
  login() {}           // Auth logic changes
  updateProfile() {}   // Profile requirements change  
  sendEmail() {}       // Email provider changes
  trackAnalytics() {}  // Analytics requirements change
}

// ✅ GOOD: Split by responsibility
class AuthService { login() {} }
class ProfileService { updateProfile() {} }
class NotificationService { sendEmail() {} }
class AnalyticsService { track() {} }

Pressure Resistance Protocol

When pressured to violate SRP, follow this:

1. Time Pressure

"Just make it work quickly"

Response: Creating a god class takes the same time as creating focused classes. The "quick" solution creates technical debt that costs 10x more later.

Action: Create separate classes. It's not slower.

2. Sunk Cost Pressure

"The class already exists, just add to it"

Response: Adding to a bloated class makes it worse. The fact that it's already wrong doesn't justify making it more wrong.

Action: Create a new focused class. Refactor the existing one if time permits.

3. Authority Pressure

"My tech lead said put it all in one class"

Response: Respectfully push back with evidence. If overruled, document your concern and comply—but NEVER silently create god classes.

Action:

"I'd recommend splitting this because [specific reason]. 
If we keep it together, we'll likely need to refactor when [consequence].
Should I proceed with the split, or document this as tech debt?"

4. Scope Creep

"While you're in there, also add X"

Response: New functionality = new class (or existing appropriate class).

Action: "X belongs in its own service. I'll create XService."

Red Flags - STOP and Reconsider

If you notice ANY of these, you're about to violate SRP:

  • Adding a method unrelated to the class's core purpose
  • Class file exceeds 200 lines
  • Class has more than 5-7 public methods
  • You need section comments to navigate the class
  • Multiple developers would edit this class for unrelated features
  • Class name contains "Manager", "Handler", "Processor", "Service" with no specific domain

All of these mean: Split the class.

Refactoring Existing Violations

When you encounter an existing god class:

  1. Don't make it worse - Never add more responsibilities
  2. Extract on touch - When modifying, extract the part you're touching
  3. Document debt - If you can't refactor now, create a ticket
// Found: OrderService with 500 lines handling orders, payments, inventory, emails

// ❌ WRONG: Add shipping logic to OrderService
// ✅ RIGHT: Create ShippingService, note that OrderService needs refactoring

Common Rationalizations (All Invalid)

Excuse Reality
"It's faster to put it in one class" It's not. You type the same code either way.
"Small classes are over-engineering" Small classes are correct engineering.
"It's just one more method" That's how god classes start. Every time.
"We can refactor later" You won't. Tech debt compounds.
"The class is already big" That's a reason to stop, not continue.
"It's related functionality" Related ≠ same responsibility.
"Section comments help navigate" If you need navigation, class is too big.

Quick Reference

Symptom Action
Class does X AND Y Split into XService and YService
Adding unrelated method Create new class
File > 200 lines Look for extraction opportunities
Multiple reasons to change One class per reason
"Manager/Handler/Processor" name Be more specific or split

The Bottom Line

One class. One responsibility. One reason to change.

When pressured to violate this: push back, document, or create the right structure anyway.

God classes are never the answer, regardless of time pressure, existing code, or authority demands.

# Supported AI Coding Agents

This skill is compatible with the SKILL.md standard and works with all major AI coding agents:

Learn more about the SKILL.md standard and how to use these skills with your preferred AI coding agent.