Skip to content

Latest commit

History

History
157 lines (104 loc) 路 6.95 KB

File metadata and controls

157 lines (104 loc) 路 6.95 KB

General Coding Principles

These are foundational guidelines applicable to almost any programming context, promoting robust, readable, and maintainable code.


1. Favor Modularity and Single Responsibility

Advice: Each function, class, or module should have one, and only one, reason to change. Break down complex tasks into smaller, focused units.

Why:

  • Easier Reasoning: Smaller units are easier to understand, write, and debug.
  • Increased Reusability: Highly focused modules are more likely to be reusable in different contexts.
  • Simplified Testing: Testing a component with a single responsibility is straightforward.
  • Reduced Impact of Changes: A change in one module is less likely to break unrelated parts of the system.

Example: Instead of a UserService that handles user data, authentication, and UI notifications, separate it into UserService (data), AuthService (auth logic), and a NotificationComposable (UI).


2. Embrace Immutability

Advice: When working with data, especially objects and arrays, prefer creating new copies or derived versions instead of directly modifying existing ones.

Why:

  • Predictability: State changes are explicit and easier to track. You know exactly when and where data is being altered.
  • Easier Debugging: Avoids subtle bugs caused by unexpected side effects when multiple parts of the application hold references to the same mutable object.
  • Simplified Reactivity (Vue.js): In Vue, reassigning a ref.value with a new object/array (even if derived from the old one) is a clear signal for reactivity updates, which can be more predictable than deep mutations for complex objects.
  • Concurrency Safety: While less common in typical frontend JavaScript, immutability is fundamental for safe concurrent programming.

Example:

// Avoid:
const user = { name: "Alice", age: 30 };
user.age = 31; // Mutates original object

// Prefer:
const user = { name: "Alice", age: 30 };
const updatedUser = { ...user, age: 31 }; // Creates a new object

3. Practice Defensive Programming

Advice: Anticipate potential issues and write code that can gracefully handle unexpected inputs, missing data, or error conditions.

Why:

  • Robustness: Makes your application more resilient to real-world data and user behavior.
  • Fewer Runtime Errors: Prevents crashes and provides a better user experience by handling errors before they propagate.
  • Clearer Error Paths: Explicitly defining how errors are handled makes the code easier to follow.

Examples:

  • Input Validation: Always validate user input or data from APIs.
  • Optional Chaining (?.) and Nullish Coalescing (??): Safely access nested properties (user?.address?.street) or provide default values (data ?? 'N/A').
  • Guard Clauses: Exit early from functions if preconditions are not met.
    function processUser(user: User | null) {
      if (!user) {
        console.warn("No user to process.");
        return; // Exit early
      }
      // ... rest of logic assuming user is not null
    }
  • Default Parameters: Provide sensible defaults for function arguments.

4. Consistent and Descriptive Naming

Advice: Use clear, unambiguous, and consistent naming conventions for variables, functions, classes, components, and files.

Why:

  • Readability: Good names reduce the need for comments and make the code self-documenting.
  • Maintainability: Easier for others (and your future self) to understand the purpose and behavior of code.
  • Searchability: Consistent names make it easier to find relevant code sections.

Examples:

  • Functions: Use verbs (e.g., fetchUsers, calculateTotalPrice, updateProfile).
  • Booleans: Use prefixes like is, has, can (e.g., isLoading, hasPermission, canSubmit).
  • Components: PascalCase (e.g., UserProfileCard, AppHeader).
  • Variables: camelCase (e.g., userName, totalAmount).
  • Files: match component/module name (e.g., UserProfileCard.vue, userService.ts).

5. Smart Error Handling & User Feedback

Advice: Beyond just logging errors, ensure your application provides meaningful feedback to the user and considers how errors impact UX.

Why:

  • User Experience: Inform users when something goes wrong and (ideally) suggest what they can do next.
  • Debugging in Production: Good logging and error reporting to monitoring tools are critical for identifying issues in live environments.
  • Graceful Degradation: The application should not crash or become unusable.

Examples:

  • Notifications/Toasts: Display transient messages for successful operations, warnings, or non-critical errors.
  • Error Pages/Components: Provide fallback UI for critical errors (e.g., "Something went wrong" page).
  • Retry Mechanisms: For intermittent network errors, offer a "Retry" button.
  • Loading States: Clearly indicate when data is being fetched to avoid user confusion.
  • Input Error Messages: Provide immediate, specific feedback for form validation errors.

6. Performance Awareness

Advice: Be mindful of performance implications, especially in large-scale applications.

Why:

  • User Experience: Faster applications lead to better user satisfaction.
  • SEO: Page load speed is a ranking factor for search engines.
  • Accessibility: Performance can impact users on slower networks or less powerful devices.

Examples:

  • Lazy Loading: Components, routes, and large libraries.
  • Virtual Scrolling: For long lists.
  • Debouncing/Throttling: For frequently triggered events (e.g., input, scroll).
  • Optimizing Network Requests: Reducing payload size, caching, consolidating requests.
  • Vue Specifics: Use v-once for static content, v-memo for memoization, understand reactivity pitfalls (e.g., unnecessary deep reactivity).

7. Continuous Learning & Refactoring

Advice: Software development is an evolving field. Continuously learn new patterns, tools, and best practices. Don't be afraid to refactor existing code to improve its quality, especially if you discover better approaches.

Why:

  • Adaptability: Keeps your codebase modern and relevant.
  • Reduced Tech Debt: Prevents small issues from accumulating into large, unmanageable problems.
  • Developer Growth: Fosters a culture of improvement and professional development.

8. Code Reviews & Pair Programming

Advice: Regularly conduct code reviews with your team members and consider pair programming for complex tasks.

Why:

  • Quality Improvement: Fresh eyes can spot bugs, logical flaws, and areas for improvement.
  • Knowledge Sharing: Disseminates knowledge about the codebase and different approaches.
  • Consistency: Helps enforce coding standards and architectural guidelines.
  • Mentorship: Provides opportunities for learning and growth within the team.
  • Increased Ownership: Fosters shared ownership of the codebase.