mirror of
https://github.com/x1xhlol/system-prompts-and-models-of-ai-tools.git
synced 2026-02-08 16:00:50 +00:00
Add 25 world-class Claude Code skills for comprehensive software development
Created comprehensive skill collection covering all aspects of modern software development with production-ready patterns, best practices, and detailed documentation. ## Skills Organized by Domain ### Code Quality & Architecture (2 skills) - advanced-code-refactoring: SOLID principles, design patterns, refactoring patterns - code-review: Automated/manual review, security, performance, maintainability ### API & Integration (2 skills) - api-integration-expert: REST/GraphQL/WebSocket with auth, retry, caching - graphql-schema-design: Schema design, resolvers, optimization, subscriptions ### Database & Data (3 skills) - database-optimization: SQL/NoSQL tuning, indexing, query optimization - data-pipeline: ETL/ELT with Airflow, Spark, dbt - caching-strategies: Redis, Memcached, CDN, invalidation patterns ### Security & Authentication (2 skills) - security-audit: OWASP Top 10, vulnerability scanning, security hardening - auth-implementation: OAuth2, JWT, session management, SSO ### Testing & Quality (2 skills) - test-automation: Unit/integration/E2E tests, TDD/BDD, coverage - performance-profiling: CPU/memory profiling, Core Web Vitals optimization ### DevOps & Infrastructure (3 skills) - docker-kubernetes: Containerization, orchestration, production deployments - ci-cd-pipeline: GitHub Actions, automated testing, deployment strategies - logging-monitoring: Observability with Datadog, Prometheus, Grafana, ELK ### Frontend Development (3 skills) - frontend-accessibility: WCAG 2.1 compliance, ARIA, keyboard navigation - ui-component-library: Design systems with React/Vue, Storybook - mobile-responsive: Responsive design, mobile-first, PWAs ### Backend & Scaling (2 skills) - backend-scaling: Load balancing, sharding, microservices, horizontal scaling - real-time-systems: WebSockets, SSE, WebRTC for real-time features ### ML & AI (1 skill) - ml-model-integration: Model serving, inference optimization, monitoring ### Development Tools (2 skills) - git-workflow-optimizer: Git workflows, branching strategies, conflict resolution - dependency-management: Package updates, security patches, version conflicts ### Code Maintenance (3 skills) - error-handling: Robust error patterns, logging, graceful degradation - documentation-generator: API docs, README, technical specifications - migration-tools: Database/framework migrations with zero downtime ## Key Features Each skill includes: - YAML frontmatter with name, description, allowed tools - Clear purpose and when to use - Comprehensive capabilities overview - Production-ready code examples - Best practices and patterns - Success criteria - Tool-specific configurations ## Highlights - 25 comprehensive skills covering full development lifecycle - Production-ready patterns and examples - Security-first approach throughout - Performance optimization built-in - Comprehensive testing strategies - DevOps automation and infrastructure as code - Modern frontend with accessibility focus - Scalable backend architectures - Data engineering and ML integration - Advanced Git workflows ## File Structure claude_skills/ ├── README.md (comprehensive documentation) ├── advanced-code-refactoring/ │ ├── SKILL.md (main skill definition) │ ├── reference.md (design patterns, SOLID principles) │ └── examples.md (refactoring examples) ├── api-integration-expert/ │ └── SKILL.md (REST/GraphQL/WebSocket integration) ├── [23 more skills...] Total: 25 skills + comprehensive README + supporting documentation ## Usage Personal skills: cp -r claude_skills/* ~/.claude/skills/ Project skills: cp -r claude_skills/* .claude/skills/ Skills automatically activate based on context and description triggers.
This commit is contained in:
145
claude_skills/advanced-code-refactoring/SKILL.md
Normal file
145
claude_skills/advanced-code-refactoring/SKILL.md
Normal file
@@ -0,0 +1,145 @@
|
||||
---
|
||||
name: advanced-code-refactoring
|
||||
description: Expert-level code refactoring applying SOLID principles, design patterns, and architectural improvements. Use when refactoring legacy code, improving code structure, applying design patterns, or modernizing codebases.
|
||||
allowed-tools: Read, Write, Edit, Grep, Glob, Bash
|
||||
---
|
||||
|
||||
# Advanced Code Refactoring Expert
|
||||
|
||||
## Purpose
|
||||
This skill enables deep, architectural-level code refactoring with a focus on maintainability, scalability, and best practices. It applies proven design patterns, SOLID principles, and modern architectural approaches.
|
||||
|
||||
## When to Use
|
||||
- Refactoring legacy or monolithic code
|
||||
- Applying design patterns (Factory, Strategy, Observer, etc.)
|
||||
- Improving code modularity and separation of concerns
|
||||
- Extracting duplicated code into reusable utilities
|
||||
- Converting imperative code to declarative patterns
|
||||
- Modernizing codebases (callbacks → promises → async/await)
|
||||
- Improving testability through dependency injection
|
||||
|
||||
## Capabilities
|
||||
|
||||
### 1. **Design Pattern Application**
|
||||
- **Creational**: Factory, Builder, Singleton, Prototype
|
||||
- **Structural**: Adapter, Decorator, Facade, Proxy
|
||||
- **Behavioral**: Strategy, Observer, Command, Template Method
|
||||
|
||||
### 2. **SOLID Principles**
|
||||
- **S**ingle Responsibility: One class, one reason to change
|
||||
- **O**pen/Closed: Open for extension, closed for modification
|
||||
- **L**iskov Substitution: Subtypes must be substitutable
|
||||
- **I**nterface Segregation: Many specific interfaces over one general
|
||||
- **D**ependency Inversion: Depend on abstractions, not concretions
|
||||
|
||||
### 3. **Architectural Improvements**
|
||||
- Extract Service Layer from Controllers
|
||||
- Implement Repository Pattern for data access
|
||||
- Create Domain-Driven Design (DDD) boundaries
|
||||
- Separate Business Logic from Infrastructure
|
||||
- Apply Clean Architecture / Hexagonal Architecture
|
||||
|
||||
### 4. **Code Smell Detection & Resolution**
|
||||
- Long methods → Extract method/class
|
||||
- Large classes → Split responsibilities
|
||||
- Duplicated code → Extract common utilities
|
||||
- Feature envy → Move method to appropriate class
|
||||
- Primitive obsession → Create value objects
|
||||
- Switch statements → Replace with polymorphism
|
||||
|
||||
## Workflow
|
||||
|
||||
1. **Analyze Current Code**
|
||||
- Identify code smells and anti-patterns
|
||||
- Map dependencies and coupling
|
||||
- Find duplicated logic
|
||||
- Assess testability
|
||||
|
||||
2. **Design Refactoring Plan**
|
||||
- Choose appropriate patterns
|
||||
- Define new abstractions
|
||||
- Plan incremental changes
|
||||
- Identify breaking changes
|
||||
|
||||
3. **Execute Refactoring**
|
||||
- Preserve existing tests (or create them first)
|
||||
- Make small, incremental changes
|
||||
- Run tests after each change
|
||||
- Update documentation
|
||||
|
||||
4. **Verify Improvements**
|
||||
- All tests pass
|
||||
- Code coverage maintained or improved
|
||||
- Complexity metrics improved
|
||||
- No regression in functionality
|
||||
|
||||
## Best Practices
|
||||
|
||||
- **Test First**: Ensure comprehensive tests exist before refactoring
|
||||
- **Small Steps**: Make incremental changes, not massive rewrites
|
||||
- **Preserve Behavior**: Refactoring should not change functionality
|
||||
- **Measure Impact**: Use metrics (cyclomatic complexity, coupling, cohesion)
|
||||
- **Document Decisions**: Explain why patterns were chosen
|
||||
- **Review Thoroughly**: Refactoring requires careful code review
|
||||
|
||||
## Tools & Techniques
|
||||
|
||||
### Static Analysis
|
||||
- ESLint, TSLint, Prettier (JavaScript/TypeScript)
|
||||
- Pylint, Black, mypy (Python)
|
||||
- RuboCop (Ruby)
|
||||
- SonarQube (Multi-language)
|
||||
|
||||
### Complexity Metrics
|
||||
- Cyclomatic Complexity (McCabe)
|
||||
- Cognitive Complexity
|
||||
- Lines of Code (LOC)
|
||||
- Coupling Between Objects (CBO)
|
||||
- Lack of Cohesion in Methods (LCOM)
|
||||
|
||||
### Refactoring Patterns
|
||||
```typescript
|
||||
// Before: Long method with multiple responsibilities
|
||||
function processOrder(order) {
|
||||
// Validation (20 lines)
|
||||
// Price calculation (30 lines)
|
||||
// Inventory update (25 lines)
|
||||
// Email notification (15 lines)
|
||||
}
|
||||
|
||||
// After: Single Responsibility
|
||||
function processOrder(order) {
|
||||
const validator = new OrderValidator();
|
||||
const calculator = new PriceCalculator();
|
||||
const inventory = new InventoryService();
|
||||
const notifier = new EmailNotifier();
|
||||
|
||||
validator.validate(order);
|
||||
const total = calculator.calculate(order);
|
||||
inventory.update(order);
|
||||
notifier.sendConfirmation(order);
|
||||
}
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
Refactoring follows these priorities:
|
||||
1. **Safety**: Never break existing functionality
|
||||
2. **Clarity**: Code should be more readable after refactoring
|
||||
3. **Testability**: Improve test coverage and ease of testing
|
||||
4. **Performance**: Maintain or improve performance
|
||||
5. **Maintainability**: Reduce future maintenance burden
|
||||
|
||||
## Dependencies
|
||||
- Testing framework (Jest, pytest, RSpec, etc.)
|
||||
- Linter configured for project
|
||||
- Type checker (TypeScript, mypy, etc.) if applicable
|
||||
|
||||
## Success Criteria
|
||||
- ✓ All existing tests pass
|
||||
- ✓ Code complexity reduced (measured)
|
||||
- ✓ Duplication eliminated or minimized
|
||||
- ✓ Design patterns appropriately applied
|
||||
- ✓ SOLID principles followed
|
||||
- ✓ Documentation updated
|
||||
- ✓ No performance regressions
|
||||
355
claude_skills/advanced-code-refactoring/examples.md
Normal file
355
claude_skills/advanced-code-refactoring/examples.md
Normal file
@@ -0,0 +1,355 @@
|
||||
# Advanced Code Refactoring Examples
|
||||
|
||||
## Example 1: Applying Strategy Pattern
|
||||
|
||||
### Before - Switch Statement Anti-Pattern
|
||||
```typescript
|
||||
class PaymentProcessor {
|
||||
processPayment(amount: number, method: string) {
|
||||
switch(method) {
|
||||
case 'credit_card':
|
||||
// 50 lines of credit card logic
|
||||
break;
|
||||
case 'paypal':
|
||||
// 40 lines of PayPal logic
|
||||
break;
|
||||
case 'crypto':
|
||||
// 60 lines of crypto logic
|
||||
break;
|
||||
default:
|
||||
throw new Error('Unknown payment method');
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### After - Strategy Pattern
|
||||
```typescript
|
||||
// Strategy interface
|
||||
interface PaymentStrategy {
|
||||
process(amount: number): Promise<PaymentResult>;
|
||||
}
|
||||
|
||||
// Concrete strategies
|
||||
class CreditCardStrategy implements PaymentStrategy {
|
||||
async process(amount: number): Promise<PaymentResult> {
|
||||
// 50 lines of credit card logic
|
||||
}
|
||||
}
|
||||
|
||||
class PayPalStrategy implements PaymentStrategy {
|
||||
async process(amount: number): Promise<PaymentResult> {
|
||||
// 40 lines of PayPal logic
|
||||
}
|
||||
}
|
||||
|
||||
class CryptoStrategy implements PaymentStrategy {
|
||||
async process(amount: number): Promise<PaymentResult> {
|
||||
// 60 lines of crypto logic
|
||||
}
|
||||
}
|
||||
|
||||
// Context
|
||||
class PaymentProcessor {
|
||||
private strategies = new Map<string, PaymentStrategy>([
|
||||
['credit_card', new CreditCardStrategy()],
|
||||
['paypal', new PayPalStrategy()],
|
||||
['crypto', new CryptoStrategy()],
|
||||
]);
|
||||
|
||||
async processPayment(amount: number, method: string) {
|
||||
const strategy = this.strategies.get(method);
|
||||
if (!strategy) throw new Error('Unknown payment method');
|
||||
return strategy.process(amount);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Example 2: Dependency Injection for Testability
|
||||
|
||||
### Before - Hard Dependencies
|
||||
```typescript
|
||||
class UserService {
|
||||
async createUser(data: UserData) {
|
||||
const db = new DatabaseConnection(); // Hard dependency
|
||||
const emailer = new EmailService(); // Hard dependency
|
||||
|
||||
const user = await db.insert('users', data);
|
||||
await emailer.sendWelcome(user.email);
|
||||
return user;
|
||||
}
|
||||
}
|
||||
|
||||
// Testing is difficult - requires real DB and email service
|
||||
```
|
||||
|
||||
### After - Dependency Injection
|
||||
```typescript
|
||||
interface Database {
|
||||
insert(table: string, data: any): Promise<any>;
|
||||
}
|
||||
|
||||
interface Emailer {
|
||||
sendWelcome(email: string): Promise<void>;
|
||||
}
|
||||
|
||||
class UserService {
|
||||
constructor(
|
||||
private db: Database,
|
||||
private emailer: Emailer
|
||||
) {}
|
||||
|
||||
async createUser(data: UserData) {
|
||||
const user = await this.db.insert('users', data);
|
||||
await this.emailer.sendWelcome(user.email);
|
||||
return user;
|
||||
}
|
||||
}
|
||||
|
||||
// Testing is easy - inject mocks
|
||||
const mockDb = { insert: jest.fn() };
|
||||
const mockEmailer = { sendWelcome: jest.fn() };
|
||||
const service = new UserService(mockDb, mockEmailer);
|
||||
```
|
||||
|
||||
## Example 3: Repository Pattern
|
||||
|
||||
### Before - Data Access Scattered
|
||||
```typescript
|
||||
class OrderController {
|
||||
async getOrder(id: string) {
|
||||
const result = await db.query('SELECT * FROM orders WHERE id = ?', [id]);
|
||||
return result[0];
|
||||
}
|
||||
|
||||
async createOrder(data: OrderData) {
|
||||
return db.query('INSERT INTO orders...', [data]);
|
||||
}
|
||||
}
|
||||
|
||||
class ReportController {
|
||||
async getOrderStats() {
|
||||
const result = await db.query('SELECT COUNT(*) FROM orders...');
|
||||
return result;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### After - Repository Pattern
|
||||
```typescript
|
||||
interface OrderRepository {
|
||||
findById(id: string): Promise<Order | null>;
|
||||
create(data: OrderData): Promise<Order>;
|
||||
findByStatus(status: string): Promise<Order[]>;
|
||||
count(): Promise<number>;
|
||||
}
|
||||
|
||||
class SQLOrderRepository implements OrderRepository {
|
||||
constructor(private db: Database) {}
|
||||
|
||||
async findById(id: string): Promise<Order | null> {
|
||||
const result = await this.db.query('SELECT * FROM orders WHERE id = ?', [id]);
|
||||
return result[0] || null;
|
||||
}
|
||||
|
||||
async create(data: OrderData): Promise<Order> {
|
||||
return this.db.query('INSERT INTO orders...', [data]);
|
||||
}
|
||||
|
||||
async findByStatus(status: string): Promise<Order[]> {
|
||||
return this.db.query('SELECT * FROM orders WHERE status = ?', [status]);
|
||||
}
|
||||
|
||||
async count(): Promise<number> {
|
||||
const result = await this.db.query('SELECT COUNT(*) as count FROM orders');
|
||||
return result[0].count;
|
||||
}
|
||||
}
|
||||
|
||||
class OrderController {
|
||||
constructor(private orderRepo: OrderRepository) {}
|
||||
|
||||
async getOrder(id: string) {
|
||||
return this.orderRepo.findById(id);
|
||||
}
|
||||
|
||||
async createOrder(data: OrderData) {
|
||||
return this.orderRepo.create(data);
|
||||
}
|
||||
}
|
||||
|
||||
class ReportController {
|
||||
constructor(private orderRepo: OrderRepository) {}
|
||||
|
||||
async getOrderStats() {
|
||||
return this.orderRepo.count();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Example 4: Extract Method Refactoring
|
||||
|
||||
### Before - Long Method
|
||||
```typescript
|
||||
function processUserRegistration(userData: any) {
|
||||
// Validation - 30 lines
|
||||
if (!userData.email) throw new Error('Email required');
|
||||
if (!userData.email.includes('@')) throw new Error('Invalid email');
|
||||
if (!userData.password) throw new Error('Password required');
|
||||
if (userData.password.length < 8) throw new Error('Password too short');
|
||||
if (!/[A-Z]/.test(userData.password)) throw new Error('Password needs uppercase');
|
||||
// ... 25 more lines of validation
|
||||
|
||||
// Password hashing - 15 lines
|
||||
const salt = crypto.randomBytes(16);
|
||||
const hash = crypto.pbkdf2Sync(userData.password, salt, 10000, 64, 'sha512');
|
||||
// ... more hashing logic
|
||||
|
||||
// Database insertion - 20 lines
|
||||
const id = uuid.v4();
|
||||
const created = new Date();
|
||||
// ... database logic
|
||||
|
||||
// Email sending - 25 lines
|
||||
const template = loadTemplate('welcome');
|
||||
const rendered = renderTemplate(template, userData);
|
||||
// ... email logic
|
||||
}
|
||||
```
|
||||
|
||||
### After - Extracted Methods
|
||||
```typescript
|
||||
function processUserRegistration(userData: UserData) {
|
||||
validateUserData(userData);
|
||||
const hashedPassword = hashPassword(userData.password);
|
||||
const user = createUserInDatabase({ ...userData, password: hashedPassword });
|
||||
sendWelcomeEmail(user);
|
||||
return user;
|
||||
}
|
||||
|
||||
function validateUserData(userData: UserData): void {
|
||||
validateEmail(userData.email);
|
||||
validatePassword(userData.password);
|
||||
validateUsername(userData.username);
|
||||
}
|
||||
|
||||
function validateEmail(email: string): void {
|
||||
if (!email) throw new ValidationError('Email required');
|
||||
if (!email.includes('@')) throw new ValidationError('Invalid email');
|
||||
// ... more validation
|
||||
}
|
||||
|
||||
function validatePassword(password: string): void {
|
||||
if (!password) throw new ValidationError('Password required');
|
||||
if (password.length < 8) throw new ValidationError('Password too short');
|
||||
if (!/[A-Z]/.test(password)) throw new ValidationError('Needs uppercase');
|
||||
// ... more validation
|
||||
}
|
||||
|
||||
function hashPassword(password: string): string {
|
||||
const salt = crypto.randomBytes(16);
|
||||
return crypto.pbkdf2Sync(password, salt, 10000, 64, 'sha512').toString('hex');
|
||||
}
|
||||
|
||||
function createUserInDatabase(userData: UserData): User {
|
||||
const id = uuid.v4();
|
||||
const created = new Date();
|
||||
// ... database logic
|
||||
return user;
|
||||
}
|
||||
|
||||
function sendWelcomeEmail(user: User): void {
|
||||
const template = loadTemplate('welcome');
|
||||
const rendered = renderTemplate(template, user);
|
||||
// ... email logic
|
||||
}
|
||||
```
|
||||
|
||||
## Example 5: Replace Conditional with Polymorphism
|
||||
|
||||
### Before - Type Checking
|
||||
```typescript
|
||||
class Animal {
|
||||
type: 'dog' | 'cat' | 'bird';
|
||||
|
||||
makeSound() {
|
||||
if (this.type === 'dog') return 'Woof';
|
||||
if (this.type === 'cat') return 'Meow';
|
||||
if (this.type === 'bird') return 'Tweet';
|
||||
}
|
||||
|
||||
move() {
|
||||
if (this.type === 'dog') return 'runs';
|
||||
if (this.type === 'cat') return 'walks';
|
||||
if (this.type === 'bird') return 'flies';
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### After - Polymorphism
|
||||
```typescript
|
||||
abstract class Animal {
|
||||
abstract makeSound(): string;
|
||||
abstract move(): string;
|
||||
}
|
||||
|
||||
class Dog extends Animal {
|
||||
makeSound() { return 'Woof'; }
|
||||
move() { return 'runs'; }
|
||||
}
|
||||
|
||||
class Cat extends Animal {
|
||||
makeSound() { return 'Meow'; }
|
||||
move() { return 'walks'; }
|
||||
}
|
||||
|
||||
class Bird extends Animal {
|
||||
makeSound() { return 'Tweet'; }
|
||||
move() { return 'flies'; }
|
||||
}
|
||||
```
|
||||
|
||||
## Metrics Improvement Examples
|
||||
|
||||
### Cyclomatic Complexity Reduction
|
||||
```typescript
|
||||
// Before: Complexity = 12
|
||||
function getDiscount(user, amount) {
|
||||
if (user.isPremium) {
|
||||
if (amount > 1000) {
|
||||
if (user.yearsActive > 5) return 0.25;
|
||||
else if (user.yearsActive > 2) return 0.20;
|
||||
else return 0.15;
|
||||
} else if (amount > 500) {
|
||||
return 0.10;
|
||||
} else {
|
||||
return 0.05;
|
||||
}
|
||||
} else {
|
||||
if (amount > 500) return 0.05;
|
||||
else return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// After: Complexity = 3 (per function)
|
||||
function getDiscount(user, amount) {
|
||||
if (user.isPremium) return getPremiumDiscount(user, amount);
|
||||
return getStandardDiscount(amount);
|
||||
}
|
||||
|
||||
function getPremiumDiscount(user, amount) {
|
||||
if (amount <= 500) return 0.05;
|
||||
if (amount <= 1000) return 0.10;
|
||||
return getLargeOrderDiscount(user.yearsActive);
|
||||
}
|
||||
|
||||
function getLargeOrderDiscount(yearsActive) {
|
||||
if (yearsActive > 5) return 0.25;
|
||||
if (yearsActive > 2) return 0.20;
|
||||
return 0.15;
|
||||
}
|
||||
|
||||
function getStandardDiscount(amount) {
|
||||
return amount > 500 ? 0.05 : 0;
|
||||
}
|
||||
```
|
||||
419
claude_skills/advanced-code-refactoring/reference.md
Normal file
419
claude_skills/advanced-code-refactoring/reference.md
Normal file
@@ -0,0 +1,419 @@
|
||||
# Advanced Code Refactoring Reference
|
||||
|
||||
## Design Patterns Quick Reference
|
||||
|
||||
### Creational Patterns
|
||||
|
||||
#### Factory Pattern
|
||||
**Purpose**: Create objects without specifying exact class
|
||||
**Use When**: Object creation logic is complex or needs to be centralized
|
||||
```typescript
|
||||
interface Product { use(): void; }
|
||||
class ConcreteProductA implements Product { use() { /* ... */ } }
|
||||
class ConcreteProductB implements Product { use() { /* ... */ } }
|
||||
|
||||
class ProductFactory {
|
||||
create(type: string): Product {
|
||||
if (type === 'A') return new ConcreteProductA();
|
||||
if (type === 'B') return new ConcreteProductB();
|
||||
throw new Error('Unknown type');
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Builder Pattern
|
||||
**Purpose**: Construct complex objects step by step
|
||||
**Use When**: Object has many optional parameters
|
||||
```typescript
|
||||
class QueryBuilder {
|
||||
private query = { select: [], where: [], orderBy: [] };
|
||||
|
||||
select(fields: string[]) { this.query.select = fields; return this; }
|
||||
where(condition: string) { this.query.where.push(condition); return this; }
|
||||
orderBy(field: string) { this.query.orderBy.push(field); return this; }
|
||||
build() { return this.query; }
|
||||
}
|
||||
|
||||
// Usage
|
||||
const query = new QueryBuilder()
|
||||
.select(['id', 'name'])
|
||||
.where('age > 18')
|
||||
.orderBy('name')
|
||||
.build();
|
||||
```
|
||||
|
||||
#### Singleton Pattern
|
||||
**Purpose**: Ensure only one instance exists
|
||||
**Use When**: Need exactly one instance (database connection, config)
|
||||
```typescript
|
||||
class Database {
|
||||
private static instance: Database;
|
||||
private constructor() { /* ... */ }
|
||||
|
||||
static getInstance(): Database {
|
||||
if (!Database.instance) {
|
||||
Database.instance = new Database();
|
||||
}
|
||||
return Database.instance;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Structural Patterns
|
||||
|
||||
#### Adapter Pattern
|
||||
**Purpose**: Convert interface of a class into another interface
|
||||
**Use When**: Want to use existing class with incompatible interface
|
||||
```typescript
|
||||
interface ModernAPI { requestData(): Promise<Data>; }
|
||||
class LegacyAPI { getData(callback: Function): void { /* ... */ } }
|
||||
|
||||
class LegacyAdapter implements ModernAPI {
|
||||
constructor(private legacy: LegacyAPI) {}
|
||||
|
||||
requestData(): Promise<Data> {
|
||||
return new Promise((resolve) => {
|
||||
this.legacy.getData(resolve);
|
||||
});
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Decorator Pattern
|
||||
**Purpose**: Add behavior to objects dynamically
|
||||
**Use When**: Need to add functionality without subclassing
|
||||
```typescript
|
||||
interface Coffee { cost(): number; description(): string; }
|
||||
class SimpleCoffee implements Coffee {
|
||||
cost() { return 5; }
|
||||
description() { return 'Simple coffee'; }
|
||||
}
|
||||
|
||||
class MilkDecorator implements Coffee {
|
||||
constructor(private coffee: Coffee) {}
|
||||
cost() { return this.coffee.cost() + 2; }
|
||||
description() { return this.coffee.description() + ', milk'; }
|
||||
}
|
||||
|
||||
const coffee = new MilkDecorator(new SimpleCoffee());
|
||||
```
|
||||
|
||||
#### Facade Pattern
|
||||
**Purpose**: Provide simplified interface to complex subsystem
|
||||
**Use When**: System is complex and you want simpler interface
|
||||
```typescript
|
||||
class ComplexSystemA { operationA(): void { /* ... */ } }
|
||||
class ComplexSystemB { operationB(): void { /* ... */ } }
|
||||
class ComplexSystemC { operationC(): void { /* ... */ } }
|
||||
|
||||
class Facade {
|
||||
constructor(
|
||||
private systemA: ComplexSystemA,
|
||||
private systemB: ComplexSystemB,
|
||||
private systemC: ComplexSystemC
|
||||
) {}
|
||||
|
||||
simpleOperation(): void {
|
||||
this.systemA.operationA();
|
||||
this.systemB.operationB();
|
||||
this.systemC.operationC();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Behavioral Patterns
|
||||
|
||||
#### Strategy Pattern
|
||||
**Purpose**: Define family of algorithms, make them interchangeable
|
||||
**Use When**: Need different variants of an algorithm
|
||||
```typescript
|
||||
interface SortStrategy { sort(data: number[]): number[]; }
|
||||
class QuickSort implements SortStrategy { sort(data) { /* ... */ } }
|
||||
class MergeSort implements SortStrategy { sort(data) { /* ... */ } }
|
||||
|
||||
class Sorter {
|
||||
constructor(private strategy: SortStrategy) {}
|
||||
sort(data: number[]) { return this.strategy.sort(data); }
|
||||
}
|
||||
```
|
||||
|
||||
#### Observer Pattern
|
||||
**Purpose**: Define one-to-many dependency between objects
|
||||
**Use When**: Need to notify multiple objects of state changes
|
||||
```typescript
|
||||
interface Observer { update(data: any): void; }
|
||||
|
||||
class Subject {
|
||||
private observers: Observer[] = [];
|
||||
|
||||
attach(observer: Observer) { this.observers.push(observer); }
|
||||
detach(observer: Observer) { /* remove */ }
|
||||
notify(data: any) { this.observers.forEach(o => o.update(data)); }
|
||||
}
|
||||
```
|
||||
|
||||
#### Command Pattern
|
||||
**Purpose**: Encapsulate request as an object
|
||||
**Use When**: Need to parameterize, queue, or log operations
|
||||
```typescript
|
||||
interface Command { execute(): void; undo(): void; }
|
||||
|
||||
class CopyCommand implements Command {
|
||||
execute() { /* copy logic */ }
|
||||
undo() { /* undo copy */ }
|
||||
}
|
||||
|
||||
class CommandInvoker {
|
||||
private history: Command[] = [];
|
||||
|
||||
execute(command: Command) {
|
||||
command.execute();
|
||||
this.history.push(command);
|
||||
}
|
||||
|
||||
undo() {
|
||||
const command = this.history.pop();
|
||||
command?.undo();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## SOLID Principles Detailed
|
||||
|
||||
### Single Responsibility Principle (SRP)
|
||||
**Definition**: A class should have one, and only one, reason to change
|
||||
|
||||
**Bad Example**:
|
||||
```typescript
|
||||
class User {
|
||||
save() { /* database logic */ }
|
||||
sendEmail() { /* email logic */ }
|
||||
generateReport() { /* reporting logic */ }
|
||||
}
|
||||
```
|
||||
|
||||
**Good Example**:
|
||||
```typescript
|
||||
class User { /* just user data */ }
|
||||
class UserRepository { save(user: User) { /* database */ } }
|
||||
class EmailService { send(user: User) { /* email */ } }
|
||||
class ReportGenerator { generate(user: User) { /* report */ } }
|
||||
```
|
||||
|
||||
### Open/Closed Principle (OCP)
|
||||
**Definition**: Open for extension, closed for modification
|
||||
|
||||
**Bad Example**:
|
||||
```typescript
|
||||
class Rectangle { width: number; height: number; }
|
||||
class Circle { radius: number; }
|
||||
|
||||
class AreaCalculator {
|
||||
calculate(shapes: any[]) {
|
||||
let area = 0;
|
||||
shapes.forEach(shape => {
|
||||
if (shape instanceof Rectangle) {
|
||||
area += shape.width * shape.height;
|
||||
} else if (shape instanceof Circle) {
|
||||
area += Math.PI * shape.radius ** 2;
|
||||
}
|
||||
// Need to modify this class for new shapes!
|
||||
});
|
||||
return area;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Good Example**:
|
||||
```typescript
|
||||
interface Shape { area(): number; }
|
||||
|
||||
class Rectangle implements Shape {
|
||||
constructor(private width: number, private height: number) {}
|
||||
area() { return this.width * this.height; }
|
||||
}
|
||||
|
||||
class Circle implements Shape {
|
||||
constructor(private radius: number) {}
|
||||
area() { return Math.PI * this.radius ** 2; }
|
||||
}
|
||||
|
||||
class AreaCalculator {
|
||||
calculate(shapes: Shape[]) {
|
||||
return shapes.reduce((sum, shape) => sum + shape.area(), 0);
|
||||
}
|
||||
// No modification needed for new shapes!
|
||||
}
|
||||
```
|
||||
|
||||
### Liskov Substitution Principle (LSP)
|
||||
**Definition**: Derived classes must be substitutable for base classes
|
||||
|
||||
**Bad Example**:
|
||||
```typescript
|
||||
class Bird {
|
||||
fly() { /* fly logic */ }
|
||||
}
|
||||
|
||||
class Penguin extends Bird {
|
||||
fly() { throw new Error('Cannot fly'); } // Violates LSP!
|
||||
}
|
||||
```
|
||||
|
||||
**Good Example**:
|
||||
```typescript
|
||||
class Bird { eat() { /* ... */ } }
|
||||
class FlyingBird extends Bird { fly() { /* ... */ } }
|
||||
class Penguin extends Bird { swim() { /* ... */ } }
|
||||
```
|
||||
|
||||
### Interface Segregation Principle (ISP)
|
||||
**Definition**: Clients shouldn't depend on interfaces they don't use
|
||||
|
||||
**Bad Example**:
|
||||
```typescript
|
||||
interface Worker {
|
||||
work(): void;
|
||||
eat(): void;
|
||||
sleep(): void;
|
||||
}
|
||||
|
||||
class Robot implements Worker {
|
||||
work() { /* ... */ }
|
||||
eat() { throw new Error('Robots dont eat'); } // Forced to implement!
|
||||
sleep() { throw new Error('Robots dont sleep'); }
|
||||
}
|
||||
```
|
||||
|
||||
**Good Example**:
|
||||
```typescript
|
||||
interface Workable { work(): void; }
|
||||
interface Eatable { eat(): void; }
|
||||
interface Sleepable { sleep(): void; }
|
||||
|
||||
class Human implements Workable, Eatable, Sleepable {
|
||||
work() { /* ... */ }
|
||||
eat() { /* ... */ }
|
||||
sleep() { /* ... */ }
|
||||
}
|
||||
|
||||
class Robot implements Workable {
|
||||
work() { /* ... */ }
|
||||
}
|
||||
```
|
||||
|
||||
### Dependency Inversion Principle (DIP)
|
||||
**Definition**: Depend on abstractions, not concretions
|
||||
|
||||
**Bad Example**:
|
||||
```typescript
|
||||
class MySQLDatabase {
|
||||
save(data: any) { /* MySQL specific */ }
|
||||
}
|
||||
|
||||
class UserService {
|
||||
private db = new MySQLDatabase(); // Concrete dependency!
|
||||
|
||||
createUser(data: any) {
|
||||
this.db.save(data);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Good Example**:
|
||||
```typescript
|
||||
interface Database {
|
||||
save(data: any): Promise<void>;
|
||||
}
|
||||
|
||||
class MySQLDatabase implements Database {
|
||||
save(data: any) { /* MySQL specific */ }
|
||||
}
|
||||
|
||||
class PostgresDatabase implements Database {
|
||||
save(data: any) { /* Postgres specific */ }
|
||||
}
|
||||
|
||||
class UserService {
|
||||
constructor(private db: Database) {} // Abstraction!
|
||||
|
||||
createUser(data: any) {
|
||||
this.db.save(data);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Code Smells & Refactorings
|
||||
|
||||
### Long Method
|
||||
**Smell**: Method has too many lines (>20-30)
|
||||
**Refactoring**: Extract Method
|
||||
- Break into smaller, well-named methods
|
||||
- Each method should do one thing
|
||||
|
||||
### Large Class
|
||||
**Smell**: Class has too many responsibilities
|
||||
**Refactoring**: Extract Class, Extract Subclass
|
||||
- Identify separate responsibilities
|
||||
- Create new classes for each
|
||||
|
||||
### Long Parameter List
|
||||
**Smell**: Method takes many parameters (>3-4)
|
||||
**Refactoring**: Introduce Parameter Object
|
||||
- Group related parameters into object
|
||||
- Pass object instead of individual parameters
|
||||
|
||||
### Duplicated Code
|
||||
**Smell**: Same code structure in multiple places
|
||||
**Refactoring**: Extract Method, Pull Up Method
|
||||
- Extract duplicated code into shared method
|
||||
- Place in common location
|
||||
|
||||
### Feature Envy
|
||||
**Smell**: Method uses more features of another class
|
||||
**Refactoring**: Move Method
|
||||
- Move method to the class it's envious of
|
||||
|
||||
### Primitive Obsession
|
||||
**Smell**: Using primitives instead of small objects
|
||||
**Refactoring**: Replace Data Value with Object
|
||||
```typescript
|
||||
// Before
|
||||
function distance(x1: number, y1: number, x2: number, y2: number) { /* ... */ }
|
||||
|
||||
// After
|
||||
class Point { constructor(public x: number, public y: number) {} }
|
||||
function distance(p1: Point, p2: Point) { /* ... */ }
|
||||
```
|
||||
|
||||
### Switch Statements
|
||||
**Smell**: Complex switch/if-else chains
|
||||
**Refactoring**: Replace Conditional with Polymorphism
|
||||
- Create subclass for each case
|
||||
- Use polymorphic behavior instead
|
||||
|
||||
## Refactoring Checklist
|
||||
|
||||
Before refactoring:
|
||||
- [ ] Ensure comprehensive test coverage exists
|
||||
- [ ] All tests are passing
|
||||
- [ ] Understand the code's current behavior
|
||||
- [ ] Identify specific code smells or issues
|
||||
- [ ] Plan the refactoring approach
|
||||
- [ ] Commit current working state
|
||||
|
||||
During refactoring:
|
||||
- [ ] Make small, incremental changes
|
||||
- [ ] Run tests after each change
|
||||
- [ ] Commit frequently with clear messages
|
||||
- [ ] Don't add features while refactoring
|
||||
- [ ] Keep system fully functional at all times
|
||||
|
||||
After refactoring:
|
||||
- [ ] All tests still pass
|
||||
- [ ] Code is more readable
|
||||
- [ ] Complexity reduced (measured)
|
||||
- [ ] No duplication
|
||||
- [ ] Documentation updated
|
||||
- [ ] Performance maintained or improved
|
||||
- [ ] Peer review conducted
|
||||
Reference in New Issue
Block a user