skills/arabelatso/skills-4-se/design-smell-detector

design-smell-detector

SKILL.md

Design Smell Detector

Identify and address design quality issues in code through automated smell detection and refactoring guidance.

Quick Start

Detect Design Smells

# Analyze a single file
python scripts/detect_smells.py src/app.py

# Analyze entire directory
python scripts/detect_smells.py src/

# Output as JSON
python scripts/detect_smells.py src/ --format json

Example Output

Found 5 design smell(s): 1 critical, 3 major, 1 minor

CRITICAL ISSUES:
  🔴 src/services.py:45 - God Class
     Class 'UserManager' has 25 methods (threshold: 20)
     💡 Split into multiple smaller, focused classes

MAJOR ISSUES:
  🟠 src/models.py:120 - Low Cohesion
     Class 'Order' has low cohesion (score: 0.25)
     💡 Group related methods/attributes or split class

  🟠 src/utils.py:89 - Long Method
     Method 'process_order' has 67 lines (threshold: 50)
     💡 Extract smaller methods or refactor

Design Smells Detected

Coupling Smells

High Coupling: Too many dependencies

  • Module imports > 20
  • Constructor dependencies > 10
  • Changes cascade across classes

Feature Envy: Method uses other class more than own

  • External access > internal access
  • Method should move to envied class

Inappropriate Intimacy: Classes too tightly coupled

  • Accessing private fields of other classes
  • Excessive use of getters/setters

Cohesion Smells

Low Cohesion: Class members unrelated

  • LCOM (Lack of Cohesion) > 0.7
  • Methods don't share instance variables
  • Class has multiple responsibilities

God Class: Class knows/does too much

  • Methods > 20
  • Attributes > 15
  • Lines of code > 500

Complexity Smells

High Cyclomatic Complexity: Too many decision points

  • Complexity > 10
  • Deeply nested conditionals
  • Many if/else, loops

Long Method: Method too long

  • Lines of code > 50
  • Multiple responsibilities
  • Hard to understand

Size Smells

Long Parameter List: Too many parameters

  • Parameters > 5
  • Related parameters not grouped
  • Method signature hard to understand

Large Module: Module too large

  • Classes > 20
  • Lines of code > 1000
  • Multiple responsibilities

Encapsulation Smells

Data Class: Only data, no behavior

  • Only getters/setters
  • No business logic
  • Missing encapsulation

Exposed Internal State: Implementation details exposed

  • Public mutable fields
  • Returns references to internal collections
  • Breaks encapsulation

Detection Workflow

1. Run Detection

Analyze codebase for design smells:

python scripts/detect_smells.py src/

2. Review Results

Examine detected smells by severity:

  • Critical: God classes, severe coupling issues
  • Major: Low cohesion, long methods, high complexity
  • Minor: Long parameter lists, feature envy

3. Prioritize Refactoring

Focus on:

  • Critical issues first
  • Frequently changed code
  • High-impact, low-effort improvements

4. Apply Refactoring

Use refactoring strategies based on smell type.

See refactoring_strategies.md for detailed solutions.

5. Verify Improvements

Re-run detection to measure progress:

python scripts/detect_smells.py src/

Compare metrics before/after.

Common Design Smells

God Class

Symptoms:

  • Too many methods (>20)
  • Too many attributes (>15)
  • Low cohesion
  • Multiple responsibilities

Example:

# ❌ God Class
class Application:
    # 30+ methods handling:
    # - User management
    # - Order processing
    # - Payment handling
    # - Reporting
    # - Email notifications
    # - File operations
    pass

Refactoring:

# ✅ Split by responsibility
class UserManager:
    pass

class OrderProcessor:
    pass

class PaymentHandler:
    pass

class ReportGenerator:
    pass

High Coupling

Symptoms:

  • Too many imports (>20)
  • Too many constructor dependencies
  • Changes cascade across classes

Example:

# ❌ High coupling
class UserService:
    def __init__(self):
        self.db = Database()
        self.cache = Cache()
        self.logger = Logger()
        self.validator = Validator()
        self.email = EmailService()
        self.sms = SMSService()
        # ... many more

Refactoring:

# ✅ Dependency injection
class UserService:
    def __init__(self, db, logger, notifier):
        self.db = db
        self.logger = logger
        self.notifier = notifier  # Abstraction

Low Cohesion

Symptoms:

  • Methods don't share attributes
  • Class does unrelated things
  • LCOM score > 0.7

Example:

# ❌ Low cohesion
class UserManager:
    def create_user(self):
        pass

    def send_email(self):
        pass

    def log_activity(self):
        pass

    def calculate_discount(self):
        pass

Refactoring:

# ✅ High cohesion - focused classes
class UserRepository:
    def create_user(self):
        pass

class EmailService:
    def send_email(self):
        pass

class ActivityLogger:
    def log_activity(self):
        pass

Long Method

Symptoms:

  • Method > 50 lines
  • Multiple responsibilities
  • Hard to understand

Example:

# ❌ Long method (100+ lines)
def process_order(order):
    # Validate (20 lines)
    # Calculate price (15 lines)
    # Save to DB (10 lines)
    # Send email (20 lines)
    # Update stats (10 lines)
    # Log activity (15 lines)
    pass

Refactoring:

# ✅ Extract methods
def process_order(order):
    validate_order(order)
    total = calculate_total(order)
    save_order(order, total)
    send_confirmation(order)
    update_statistics()
    log_activity(order)

Refactoring Strategies

Reduce Coupling

Dependency Injection:

# Inject dependencies instead of creating them
class OrderService:
    def __init__(self, db, logger):
        self.db = db
        self.logger = logger

Interface Abstraction:

# Depend on abstractions, not implementations
from abc import ABC, abstractmethod

class PaymentGateway(ABC):
    @abstractmethod
    def charge(self, amount):
        pass

class PaymentProcessor:
    def __init__(self, gateway: PaymentGateway):
        self.gateway = gateway

Improve Cohesion

Extract Class:

# Split into focused classes
class User:
    # User data and behavior

class UserRepository:
    # Database operations

class EmailService:
    # Email operations

Move Method:

# Move method to appropriate class
class Account:
    def get_formatted_balance(self):  # Moved from reporter
        return f"${self.balance:.2f}"

Reduce Complexity

Extract Method:

# Break complex method into smaller ones
def process_order(order):
    validate_order(order)
    calculate_total(order)
    save_order(order)

Replace Conditional with Polymorphism:

# Use inheritance instead of conditionals
class Customer:
    def calculate_price(self, base_price):
        return base_price

class PremiumCustomer(Customer):
    def calculate_price(self, base_price):
        return base_price * 0.9

For comprehensive refactoring strategies, see refactoring_strategies.md.

Metrics and Thresholds

Detection Thresholds

Smell Metric Threshold
God Class Methods > 20
God Class Attributes > 15
God Class LOC > 500
High Coupling Imports > 20
Low Cohesion LCOM > 0.7
Long Method LOC > 50
High Complexity Cyclomatic > 10
Long Parameter List Parameters > 5

Key Metrics

LCOM (Lack of Cohesion of Methods):

  • Measures how methods share instance variables
  • Range: 0.0 (high cohesion) to 1.0 (low cohesion)
  • Lower is better

Cyclomatic Complexity:

  • Number of linearly independent paths
  • Each if/while/for adds 1
  • Lower is better (< 10)

Fan-out (Coupling):

  • Number of dependencies
  • Lower is better (< 10)

Design Smell Catalog

For complete descriptions, examples, and solutions for all design smells, see smell_catalog.md.

Includes:

  • Coupling Smells: High coupling, Feature Envy, Inappropriate Intimacy
  • Cohesion Smells: Low cohesion, God Class
  • Complexity Smells: High complexity, Long Method
  • Size Smells: Long Parameter List, Large Module
  • Encapsulation Smells: Data Class, Exposed Internal State

Best Practices

1. Detect Regularly

Integrate into workflow:

# Pre-commit hook
python scripts/detect_smells.py src/

# CI/CD pipeline
make check-design-smells

2. Track Metrics Over Time

Monitor trends:

Sprint 1: 15 God classes, 45 long methods
Sprint 2: 12 God classes, 38 long methods
Sprint 3: 8 God classes, 25 long methods

3. Prioritize Strategically

Focus on:

  • Code changed frequently
  • Critical business logic
  • High-impact areas

4. Refactor Incrementally

  • Small, safe changes
  • Run tests after each change
  • Commit frequently

5. Measure Improvements

Before/after metrics:

Before: LCOM = 0.85 (low cohesion)
After:  LCOM = 0.25 (high cohesion)

Common Scenarios

Scenario 1: Legacy Codebase Modernization

Goal: Identify technical debt in legacy system

Approach:

  1. Run smell detection on entire codebase
  2. Generate metrics report
  3. Identify top 10 worst files
  4. Create refactoring backlog
  5. Tackle incrementally

Scenario 2: Code Review Enhancement

Goal: Automated design quality checks in PR reviews

Approach:

  1. Add smell detection to CI pipeline
  2. Fail build if critical smells introduced
  3. Report metrics in PR comments
  4. Require fixes before merge

Scenario 3: Architecture Assessment

Goal: Evaluate system architecture quality

Approach:

  1. Detect coupling and cohesion issues
  2. Identify God classes and large modules
  3. Analyze dependency structure
  4. Recommend architectural improvements

Integration with Development Workflow

Pre-commit Hook

#!/bin/bash
# .git/hooks/pre-commit

python scripts/detect_smells.py src/
if [ $? -ne 0 ]; then
    echo "Critical design smells detected. Commit aborted."
    exit 1
fi

CI/CD Pipeline

# .github/workflows/quality.yml
name: Design Quality Check

on: [push, pull_request]

jobs:
  check-smells:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3

      - name: Detect design smells
        run: python scripts/detect_smells.py src/

      - name: Upload report
        uses: actions/upload-artifact@v3
        with:
          name: smell-report
          path: smell-report.json

IDE Integration

Most IDEs support similar analysis through plugins:

  • PyCharm: Built-in inspections for coupling/cohesion
  • VS Code: Python linting extensions
  • SonarLint: Real-time smell detection

Troubleshooting

False Positives

Problem: Legitimate design flagged as smell

Solution:

  • Understand context and constraints
  • Consider if threshold should be adjusted
  • Document reasons for exception

Overwhelming Results

Problem: Too many smells to address

Solution:

  • Filter by severity (critical first)
  • Focus on frequently changed code
  • Set incremental goals

Refactoring Breaks Tests

Problem: Tests fail after refactoring

Solution:

  • Ensure comprehensive test coverage first
  • Refactor incrementally
  • Run tests after each small change

Reference Documentation

Design Smell Catalog

See smell_catalog.md for:

  • Complete smell definitions
  • Detection criteria and thresholds
  • Code examples (before/after)
  • Metrics explanations (LCOM, cyclomatic complexity, fan-out)
  • All coupling, cohesion, complexity, size, and encapsulation smells

Refactoring Strategies

See refactoring_strategies.md for:

  • Coupling reduction strategies (DI, interfaces, facades)
  • Cohesion improvement (extract class, move method)
  • Complexity reduction (extract method, polymorphism)
  • Size reduction (split classes, parameter objects)
  • Encapsulation improvement
  • Refactoring workflow and best practices
  • Anti-patterns to avoid
  • Success metrics
Weekly Installs
1
GitHub Stars
47
First Seen
12 days ago
Installed on
amp1
cline1
opencode1
cursor1
kimi-cli1
codex1