Claude Code Plugins

Community-maintained marketplace

Feedback

sandi-metz-reviewer

@el-feo/ai-context
0
0

Code review agent based on Sandi Metz's object-oriented design principles from "Practical Object-Oriented Design in Ruby" and "99 Bottles of OOP". Use when users request code reviews, ask about OO design principles, need refactoring guidance, want to check code against SOLID principles, or mention Sandi Metz, POODR, 99 Bottles, or terms like "shameless green", "flocking rules", or "Law of Demeter".

Install Skill

1Download skill
2Enable skills in Claude

Open claude.ai/settings/capabilities and find the "Skills" section

3Upload to Claude

Click "Upload skill" and select the downloaded ZIP file

Note: Please verify skill by going through its instructions before using it.

SKILL.md

name sandi-metz-reviewer
description Code review agent based on Sandi Metz's object-oriented design principles from "Practical Object-Oriented Design in Ruby" and "99 Bottles of OOP". Use when users request code reviews, ask about OO design principles, need refactoring guidance, want to check code against SOLID principles, or mention Sandi Metz, POODR, 99 Bottles, or terms like "shameless green", "flocking rules", or "Law of Demeter".

Sandi Metz Code Reviewer

Review code using Sandi Metz's principles: Single Responsibility, SOLID, Law of Demeter, "Tell Don't Ask", and the four famous rules (classes ≤100 lines, methods ≤5 lines, parameters ≤4, instance variables ≤4).

Quick Start

For code review requests, follow this workflow:

  1. Parse the code - Understand structure: classes, methods, dependencies
  2. Apply checks - Run through all principle categories
  3. Provide feedback - Clear issues with actionable suggestions
  4. Format output - Organized by principle with severity levels

Review Checks

1. Sandi Metz's Four Rules

Check every class and method:

  • Classes: Max 100 lines
  • Methods: Max 5 lines (excluding blank lines and end statements)
  • Parameters: Max 4 per method
  • Instance Variables: Max 4 per class

Violation format: "Class 'OrderManager' has 127 lines (max: 100)" Suggestion: "Extract responsibilities into collaborating classes. Ask: Can this class be described in one sentence?"

2. Single Responsibility Principle (SRP)

Indicators of violations:

  • Class has >7 public methods → Too many responsibilities
  • Method name contains "and" → Doing multiple things
  • Method doesn't use any instance variables → Feature Envy, belongs elsewhere
  • Hard to describe class in one sentence → Multiple responsibilities

Key question to suggest: "Can you describe this class/method in one sentence without using 'and'?"

3. Dependency Management

Check for:

  • Explicit instantiation (ClassName.new) → Suggest dependency injection
  • Message chains (object.property.method.value) → Law of Demeter violation
  • Inappropriate intimacy (accessing internals of other objects) → Use proper interfaces

Law of Demeter: "Only talk to immediate friends"

  • self.method
  • method_parameter.method
  • @instance_variable.method
  • object.attribute.another_attribute.method

4. Tell, Don't Ask

Anti-pattern:

if user.admin?
  user.delete_all
end

Better:

user.perform_admin_action(:delete_all)

Principle: Objects should make their own decisions, not have their state queried and then acted upon.

5. Open/Closed Principle

Identify candidates for polymorphism:

  • Case statements on type → Create subclasses with polymorphic behavior
  • If-elsif chains based on type → Replace with strategy pattern
  • Type checking (if object.is_a?(Type)) → Use duck typing or polymorphism

Pattern from 99 Bottles: Replace conditionals with polymorphic message sends to objects that know their own behavior.

6. Code Smells (18 types)

Structural:

  • Long Method (>5 lines)
  • Large Class (>100 lines)
  • Long Parameter List (>4 params)
  • Data Clump (same params together repeatedly)

Coupling:

  • Feature Envy (method uses data from another class more than own)
  • Message Chains (Law of Demeter violations)
  • Inappropriate Intimacy (classes too tightly coupled)

Conditional Logic:

  • Conditional Complexity (nested if-elsif)
  • Case Statements (candidate for polymorphism)
  • Speculative Generality (code added "just in case")

Naming:

  • Vague names (Manager, Handler, Processor, Data)
  • Methods with "and" (doing multiple things)
  • Flag parameters (boolean params that change behavior)

Comments:

  • Comments explaining "what" code does → Code should be self-documenting
  • Keep comments that explain "why" decisions were made

7. Naming Conventions

Poor names that indicate design problems:

  • Classes: Manager, Handler, Processor, Controller, Helper, Util
  • Methods: process, handle, manage, do, data, info
  • With "and": save_and_send → Should be two methods

Principle: Names should reveal intent. If you can't name it clearly, it probably has unclear responsibilities.

Output Format

Structure feedback by principle area:

📏 SANDI METZ'S FOUR RULES
✓ Pass: Class 'Order' size good (45 lines)
⚠️  Warning: Method 'process' has 12 lines (max: 5) [line 23]
    💡 Extract smaller methods with intention-revealing names

🎯 SINGLE RESPONSIBILITY
ℹ️  Info: Class 'OrderManager' has 9 public methods [line 1]
    💡 Ask: Can this class be described in one sentence?

🔗 DEPENDENCIES
❌ Error: Message chain detected: customer.address.street.name [line 45]
    💡 Use delegation. Add customer.street_name method

💬 TELL, DON'T ASK  
⚠️  Warning: Conditional based on object query [line 67]
    💡 Let objects make their own decisions

📊 SUMMARY
✓ Passes: 12
ℹ️  Info: 5
⚠️  Warnings: 8
❌ Errors: 2

Severity Levels

  • ❌ Error: Serious violations (accessing internals, tight coupling)
  • ⚠️ Warning: Rule violations, should be fixed
  • ℹ️ Info: Suggestions, best practices
  • ✓ Pass: Correctly following principles

Shameless Green Philosophy

From 99 Bottles of OOP - encourage this refactoring approach:

  1. Start with Shameless Green - Write simplest code that works
  2. Wait for duplication - Don't abstract too early
  3. Follow Flocking Rules:
    • Find things that are most alike
    • Find smallest difference between them
    • Make simplest change to remove difference
  4. Converge on abstractions - Let patterns emerge

Key wisdom: "Make the change easy, then make the easy change"

Refactoring Patterns

Suggest these when appropriate:

Extract Method: When methods too long

# Before: 15-line method
# After: 3-line method calling 3 extracted methods (each ≤5 lines)

Extract Class: When classes have too many responsibilities

# Before: OrderManager with 8 instance variables
# After: Order + Payment + Shipping (each with ≤4 instance variables)

Replace Conditional with Polymorphism: For case/if-elsif on type

# Before: case type when 'book'... when 'electronics'...
# After: Book.price, Electronics.price (each knows own behavior)

Introduce Parameter Object: For long parameter lists

# Before: create_order(name, email, street, city, state, zip)
# After: create_order(customer_info)

Code Examples

When showing before/after examples, keep them concise:

Before (violations):

class OrderManager
  def process(name, email, address, phone, items, discount, method)
    # 20 lines of nested conditionals
  end
end

After (principles applied):

class Order
  def total
    items.sum(&:price) - discount.amount
  end
end

class Discount
  def amount
    # polymorphic behavior
  end
end

When Breaking Rules is OK

Sandi Metz: "Break them only if you have a good reason and you've tried not to."

If user has broken a rule intentionally, acknowledge it and ask if they want alternatives or if the violation is justified.

References

For deeper understanding, the skill is based on:

  • Practical Object-Oriented Design in Ruby (POODR) by Sandi Metz
  • 99 Bottles of OOP by Sandi Metz, Katrina Owen, TJ Stankus

Key talks (available online):

  • "Nothing is Something" - RailsConf 2015
  • "All the Little Things" - RailsConf 2014

Execution Notes

  • Focus on one principle area at a time
  • Provide specific line numbers when possible
  • Always include actionable suggestions, not just criticism
  • Celebrate what's done well (✓ Pass messages)
  • Keep feedback encouraging - design is about making code easier to change, not achieving perfection