Use when implementing language-agnostic patterns like layered architecture, dependency injection, error handling, or code organization principles across any technology stack.
Use when implementing language-agnostic patterns like layered architecture, dependency injection, error handling, or code organization principles across any technology stack.
// BAD: Multiple responsibilities
function processUser(user) {
validateUser(user);
saveToDatabase(user);
sendEmail(user);
logAnalytics(user);
}
// GOOD: Single responsibility
function validateUser(user) { /* validation only */ }
function saveUser(user) { /* persistence only */ }
function notifyUser(user) { /* notification only */ }
Dependency Injection
Inject dependencies rather than creating them internally.
// BAD: Hard dependency
class UserService {
constructor() {
this.db = new Database(); // Hard-coded
}
}
// GOOD: Injected dependency
class UserService {
constructor(db) {
this.db = db; // Injected
}
}
Interface Segregation
Prefer many specific interfaces over one general interface.
Validate inputs early and fail immediately on invalid data.
function processOrder(order) {
// Validate early
if (!order) throw new Error('Order required');
if (!order.items?.length) throw new Error('Order must have items');
if (!order.customerId) throw new Error('Customer ID required');
// Process only after validation passes
return executeOrder(order);
}
Error Boundaries
Contain errors at appropriate boundaries.
// API boundary - catch and format errors
async function apiHandler(req, res) {
try {
const result = await processRequest(req);
res.json({ success: true, data: result });
} catch (error) {
res.status(error.statusCode || 500).json({
success: false,
error: error.message
});
}
}
Result Types (Where Supported)
Use Result/Either types instead of exceptions for expected failures.
Using strings where enums/types would be safer. Use type systems.
Copy-Paste Programming
Duplicating code instead of abstracting. But: prefer duplication over wrong abstraction.
Boolean Parameters
Functions with boolean flags that change behavior. Split into explicit functions.
// BAD
function process(data, isAdmin) { /* behaves differently based on flag */ }
// GOOD
function processUserData(data) { /* user logic */ }
function processAdminData(data) { /* admin logic */ }
Performance Principles
Measure First: Profile before optimizing
Lazy Loading: Load resources only when needed
Caching: Cache expensive computations and API calls
Pagination: Don't load everything at once
Batch Operations: Combine multiple operations when possible
Async/Parallel: Use concurrency for independent operations
Security Principles
Input Validation: Never trust user input
Output Encoding: Encode data for its context (HTML, SQL, etc.)
Least Privilege: Request minimum permissions needed
Defense in Depth: Multiple layers of security
Fail Secure: Default to denying access on errors
Secrets Management: Never hardcode secrets, use environment variables
Universal patterns applicable to all technology stacks