Claude
Skills
Sign in
Back

code-quality-standards

Included with Lifetime
$97 forever

Code quality standards including SOLID principles, design patterns, code smells, refactoring techniques, naming conventions, and technical debt management. Use when reviewing code, refactoring, ensuring quality, or detecting code smells.

Design

What this skill does


# Code Quality Standards

This skill provides comprehensive guidance for writing clean, maintainable, and high-quality code.

## SOLID Principles

### S - Single Responsibility Principle

**Definition**: A class should have only one reason to change.

```typescript
// ❌ BAD - Multiple responsibilities
class UserManager {
  createUser(data: UserData) {
    // Validation logic
    if (!data.email.includes('@')) throw new Error('Invalid email');

    // Database logic
    const user = database.insert('users', data);

    // Email logic
    emailService.send(data.email, 'Welcome!');

    // Logging logic
    logger.info(`User created: ${data.email}`);

    return user;
  }
}

// ✅ GOOD - Single responsibility per class
class UserValidator {
  validate(data: UserData): void {
    if (!data.email.includes('@')) {
      throw new Error('Invalid email');
    }
  }
}

class UserRepository {
  create(data: UserData): User {
    return database.insert('users', data);
  }
}

class UserNotificationService {
  sendWelcomeEmail(email: string): void {
    emailService.send(email, 'Welcome!');
  }
}

class UserService {
  constructor(
    private validator: UserValidator,
    private repository: UserRepository,
    private notificationService: UserNotificationService,
    private logger: Logger
  ) {}

  async createUser(data: UserData): Promise<User> {
    this.validator.validate(data);
    const user = await this.repository.create(data);
    await this.notificationService.sendWelcomeEmail(user.email);
    this.logger.info(`User created: ${user.email}`);
    return user;
  }
}
```

### O - Open/Closed Principle

**Definition**: Classes should be open for extension but closed for modification.

```typescript
// ❌ BAD - Must modify class to add new payment methods
class PaymentProcessor {
  process(type: string, amount: number) {
    if (type === 'credit_card') {
      // Process credit card
    } else if (type === 'paypal') {
      // Process PayPal
    } else if (type === 'bitcoin') {
      // Process Bitcoin
    }
  }
}

// ✅ GOOD - Can extend without modifying
interface PaymentMethod {
  process(amount: number): Promise<PaymentResult>;
}

class CreditCardPayment implements PaymentMethod {
  async process(amount: number): Promise<PaymentResult> {
    // Process credit card
    return { success: true };
  }
}

class PayPalPayment implements PaymentMethod {
  async process(amount: number): Promise<PaymentResult> {
    // Process PayPal
    return { success: true };
  }
}

class PaymentProcessor {
  async process(method: PaymentMethod, amount: number): Promise<PaymentResult> {
    return await method.process(amount);
  }
}

// Add new payment method without modifying existing code
class BitcoinPayment implements PaymentMethod {
  async process(amount: number): Promise<PaymentResult> {
    // Process Bitcoin
    return { success: true };
  }
}
```

### L - Liskov Substitution Principle

**Definition**: Subtypes must be substitutable for their base types.

```typescript
// ❌ BAD - Violates LSP
class Rectangle {
  constructor(protected width: number, protected height: number) {}

  setWidth(width: number) {
    this.width = width;
  }

  setHeight(height: number) {
    this.height = height;
  }

  getArea(): number {
    return this.width * this.height;
  }
}

class Square extends Rectangle {
  setWidth(width: number) {
    this.width = width;
    this.height = width; // Violates expectation
  }

  setHeight(height: number) {
    this.width = height; // Violates expectation
    this.height = height;
  }
}

// ✅ GOOD - Separate abstractions
interface Shape {
  getArea(): number;
}

class Rectangle implements Shape {
  constructor(private width: number, private height: number) {}

  getArea(): number {
    return this.width * this.height;
  }
}

class Square implements Shape {
  constructor(private side: number) {}

  getArea(): number {
    return this.side * this.side;
  }
}
```

### I - Interface Segregation Principle

**Definition**: Clients shouldn't be forced to depend on interfaces they don't use.

```typescript
// ❌ BAD - Fat interface
interface Worker {
  work(): void;
  eat(): void;
  sleep(): void;
  getPaid(): void;
}

class HumanWorker implements Worker {
  work() { /* ... */ }
  eat() { /* ... */ }
  sleep() { /* ... */ }
  getPaid() { /* ... */ }
}

class RobotWorker implements Worker {
  work() { /* ... */ }
  eat() { /* Not applicable */ }
  sleep() { /* Not applicable */ }
  getPaid() { /* Not applicable */ }
}

// ✅ GOOD - Segregated interfaces
interface Workable {
  work(): void;
}

interface Eatable {
  eat(): void;
}

interface Sleepable {
  sleep(): void;
}

interface Payable {
  getPaid(): void;
}

class HumanWorker implements Workable, Eatable, Sleepable, Payable {
  work() { /* ... */ }
  eat() { /* ... */ }
  sleep() { /* ... */ }
  getPaid() { /* ... */ }
}

class RobotWorker implements Workable {
  work() { /* ... */ }
}
```

### D - Dependency Inversion Principle

**Definition**: Depend on abstractions, not concretions.

```typescript
// ❌ BAD - Depends on concrete implementation
class UserService {
  private database = new MySQLDatabase(); // Tight coupling

  async getUser(id: string) {
    return this.database.query(`SELECT * FROM users WHERE id = ${id}`);
  }
}

// ✅ GOOD - Depends on abstraction
interface Database {
  query(sql: string): Promise<any>;
}

class MySQLDatabase implements Database {
  async query(sql: string): Promise<any> {
    // MySQL implementation
  }
}

class PostgreSQLDatabase implements Database {
  async query(sql: string): Promise<any> {
    // PostgreSQL implementation
  }
}

class UserService {
  constructor(private database: Database) {} // Dependency injection

  async getUser(id: string) {
    return this.database.query(`SELECT * FROM users WHERE id = ${id}`);
  }
}

// Can easily swap database implementations
const userService = new UserService(new PostgreSQLDatabase());
```

## DRY (Don't Repeat Yourself)

### Identifying Duplication

```typescript
// ❌ BAD - Repeated validation logic
function createUser(data: UserData) {
  if (!data.email || !data.email.includes('@')) {
    throw new Error('Invalid email');
  }
  if (!data.password || data.password.length < 8) {
    throw new Error('Password too short');
  }
  // Create user
}

function updateUser(id: string, data: UserData) {
  if (!data.email || !data.email.includes('@')) {
    throw new Error('Invalid email');
  }
  if (!data.password || data.password.length < 8) {
    throw new Error('Password too short');
  }
  // Update user
}

// ✅ GOOD - Extract common logic
function validateUserData(data: UserData): void {
  if (!data.email || !data.email.includes('@')) {
    throw new Error('Invalid email');
  }
  if (!data.password || data.password.length < 8) {
    throw new Error('Password too short');
  }
}

function createUser(data: UserData) {
  validateUserData(data);
  // Create user
}

function updateUser(id: string, data: UserData) {
  validateUserData(data);
  // Update user
}
```

## KISS (Keep It Simple, Stupid)

```typescript
// ❌ BAD - Over-engineered
class NumberProcessor {
  private strategy: ProcessingStrategy;

  constructor(strategy: ProcessingStrategy) {
    this.strategy = strategy;
  }

  process(numbers: number[]): number[] {
    return this.strategy.execute(numbers);
  }
}

interface ProcessingStrategy {
  execute(numbers: number[]): number[];
}

class MultiplyByTwoStrategy implements ProcessingStrategy {
  execute(numbers: number[]): number[] {
    return numbers.map(n => n * 2);
  }
}

// ✅ GOOD - Simple and clear
function multiplyByTwo(numbers: number[]): number[] {
  return numbers.map(n => n * 2);
}
```

## YAGNI (You Aren't Gonna Need It)

```typescript
// ❌ BAD - Building features you might need
class User {
  id: string;
  email: string;
  name: string;

  // Future features that aren't needed yet
  preferences?: UserPreferences;
  badges?: Badge[];
  followers?: User[];
  following?: User[];
  achievements?: Achievement[];
  not

Related in Design