All skills
asyrafhussin avatar

/clean-code-principles

@680deef

SOLID principles, design patterns, DRY, KISS, and clean code fundamentals. Use when reviewing architecture, checking code quality, refactoring, or discussing design decisions. Triggers on "review architecture", "check code quality", "SOLID principles", "design patterns", or "clean code".

Use this Skill: https://skilld.dev/gh/asyrafhussin/agent-skills/clean-code-principles

This session only. Nothing lands on disk.

rulescore-dry.md

≈1.9k tokens on demand. Your agent reads this file only when SKILL.md points to it.

Don't Repeat Yourself (DRY)

Why It Matters

"Don't Repeat Yourself" means every piece of knowledge should have a single, authoritative representation. Duplication leads to inconsistencies, increases maintenance burden, and makes bugs harder to fix. When you change one copy but forget others, bugs creep in.

Incorrect

// ❌ Duplicated validation logic
class UserController {
  createUser(data) {
    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...
  }

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

// ❌ Duplicated business rules
function calculateOrderTotal(items) {
  let total = 0;
  for (const item of items) {
    total += item.price * item.quantity;
  }
  if (total > 100) {
    total = total * 0.9; // 10% discount over $100
  }
  return total;
}

function calculateCartTotal(cartItems) {
  let total = 0;
  for (const item of cartItems) {
    total += item.price * item.quantity; // Duplicated
  }
  if (total > 100) {
    total = total * 0.9; // Duplicated discount logic
  }
  return total;
}

// ❌ Duplicated constants
// file: checkout.ts
const TAX_RATE = 0.08;
const FREE_SHIPPING_THRESHOLD = 50;

// file: cart.ts
const TAX_RATE = 0.08; // Duplicated
const FREE_SHIPPING_THRESHOLD = 50; // Duplicated

Correct

Extract Shared Validation

// ✅ Single validation module
// validators/user.ts
export class UserValidator {
  static validateEmail(email: string): void {
    if (!email || !email.includes('@')) {
      throw new ValidationError('Invalid email address');
    }
  }

  static validatePassword(password: string): void {
    if (!password || password.length < 8) {
      throw new ValidationError('Password must be at least 8 characters');
    }
  }

  static validate(data: UserData): void {
    this.validateEmail(data.email);
    this.validatePassword(data.password);
  }
}

// controller.ts
class UserController {
  createUser(data) {
    UserValidator.validate(data);
    // create user...
  }

  updateUser(id, data) {
    UserValidator.validate(data);
    // update user...
  }
}

Extract Shared Business Logic

// ✅ Single source of truth for pricing
// services/pricing.ts
export class PricingService {
  private static readonly BULK_DISCOUNT_THRESHOLD = 100;
  private static readonly BULK_DISCOUNT_RATE = 0.1;

  static calculateSubtotal(items: LineItem[]): number {
    return items.reduce(
      (sum, item) => sum + item.price * item.quantity,
      0
    );
  }

  static applyDiscount(subtotal: number): number {
    if (subtotal > this.BULK_DISCOUNT_THRESHOLD) {
      return subtotal * (1 - this.BULK_DISCOUNT_RATE);
    }
    return subtotal;
  }

  static calculateTotal(items: LineItem[]): number {
    const subtotal = this.calculateSubtotal(items);
    return this.applyDiscount(subtotal);
  }
}

// Both order and cart use the same logic
const orderTotal = PricingService.calculateTotal(order.items);
const cartTotal = PricingService.calculateTotal(cart.items);

Centralize Constants

// ✅ Single constants file
// constants/pricing.ts
export const PRICING = {
  TAX_RATE: 0.08,
  FREE_SHIPPING_THRESHOLD: 50,
  BULK_DISCOUNT_THRESHOLD: 100,
  BULK_DISCOUNT_RATE: 0.1,
} as const;

// Used everywhere
import { PRICING } from '@/constants/pricing';

const tax = subtotal * PRICING.TAX_RATE;
const freeShipping = total >= PRICING.FREE_SHIPPING_THRESHOLD;

Extract Shared Components

// ❌ Duplicated UI patterns
function UserCard({ user }) {
  return (
    <div className="p-4 rounded-lg shadow bg-white">
      <img src={user.avatar} className="w-12 h-12 rounded-full" />
      <h3 className="font-bold">{user.name}</h3>
      <p className="text-gray-600">{user.email}</p>
    </div>
  );
}

function TeamMemberCard({ member }) {
  return (
    <div className="p-4 rounded-lg shadow bg-white"> {/* Same styles */}
      <img src={member.avatar} className="w-12 h-12 rounded-full" />
      <h3 className="font-bold">{member.name}</h3>
      <p className="text-gray-600">{member.role}</p>
    </div>
  );
}

// ✅ Reusable component
function Card({ children, className }) {
  return (
    <div className={cn("p-4 rounded-lg shadow bg-white", className)}>
      {children}
    </div>
  );
}

function Avatar({ src, alt }) {
  return <img src={src} alt={alt} className="w-12 h-12 rounded-full" />;
}

function UserCard({ user }) {
  return (
    <Card>
      <Avatar src={user.avatar} alt={user.name} />
      <h3 className="font-bold">{user.name}</h3>
      <p className="text-gray-600">{user.email}</p>
    </Card>
  );
}

function TeamMemberCard({ member }) {
  return (
    <Card>
      <Avatar src={member.avatar} alt={member.name} />
      <h3 className="font-bold">{member.name}</h3>
      <p className="text-gray-600">{member.role}</p>
    </Card>
  );
}

Extract Shared Hooks

// ❌ Duplicated fetch logic
function UserProfile() {
  const [user, setUser] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    fetch('/api/user')
      .then(res => res.json())
      .then(setUser)
      .catch(setError)
      .finally(() => setLoading(false));
  }, []);
  // ...
}

function ProductList() {
  const [products, setProducts] = useState(null);
  const [loading, setLoading] = useState(true); // Duplicated
  const [error, setError] = useState(null); // Duplicated

  useEffect(() => {
    fetch('/api/products') // Same pattern
      .then(res => res.json())
      .then(setProducts)
      .catch(setError)
      .finally(() => setLoading(false));
  }, []);
  // ...
}

// ✅ Custom hook (or use React Query)
function useFetch<T>(url: string) {
  const [data, setData] = useState<T | null>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<Error | null>(null);

  useEffect(() => {
    fetch(url)
      .then(res => res.json())
      .then(setData)
      .catch(setError)
      .finally(() => setLoading(false));
  }, [url]);

  return { data, loading, error };
}

function UserProfile() {
  const { data: user, loading, error } = useFetch<User>('/api/user');
  // ...
}

function ProductList() {
  const { data: products, loading, error } = useFetch<Product[]>('/api/products');
  // ...
}

When NOT to DRY

// ⚠️ Don't extract coincidentally similar code
// These might look similar but serve different purposes

function validateUserAge(age: number) {
  return age >= 18; // Legal adult age
}

function validateMinimumOrderQuantity(quantity: number) {
  return quantity >= 18; // Business rule: minimum order
}

// These should remain separate even though both check >= 18
// Their reasons for change are different

Rule of Three

Wait until you see duplication three times before extracting.
Two occurrences might be coincidental. Three indicates a pattern.

Benefits

  • Single source of truth
  • Fix bugs in one place
  • Consistent behavior across codebase
  • Easier refactoring
  • Reduced code size
  • Lower maintenance cost

Source: SKILL.md on GitHub

1 warning16d5 checks · Risk SAFE
  • Gen Agent Trust Hub16d

    This skill contains language-agnostic guidelines, examples, and reference material for clean code and SOLID principles. It consists purely of static documentation and contains no executable code or security risks.

  • Socket16d

    No alerts

  • Snyk16d

    Risk: LOW · No issues

  • Runlayer6mo

    5/29 files flagged

  • ZeroLeaks5mo

    Score: 93/100 · 2 sections analyzed

Signed by skilld at 680deef. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub last month.

Steadyupdated 7 months ago
metadata
{
  "author": "AsyrafHussin",
  "version": "1.0.2"
}

README badge

README badge for asyrafhussin/agent-skills/clean-code-principles