Skip to content

Bits of .NET

Daily micro-tips for C#, SQL, performance, and scalable backend engineering.

  • Asp.Net Core
  • C#
  • SQL
  • JavaScript
  • CSS
  • About
  • ErcanOPAK.com
  • No Access
  • Privacy Policy
AI

AI Prompt: Refactor Legacy Code to Modern Standards

- 30.03.26 - ErcanOPAK

🔧 Modernize Legacy Code Fast

Inherited spaghetti code from 2010? 500-line function? No tests? AI refactors to modern patterns, breaks into testable units, explains every change.

The Refactoring Prompt

Refactor this legacy code to modern standards:

Current code:
[paste legacy code]

Language/Framework: [JavaScript/Python/C#/etc.]
Target version: [ES2023/Python 3.11/C# 12/etc.]

Requirements:
1. Break down into smaller, single-responsibility functions
2. Apply modern language features (async/await, destructuring, etc.)
3. Improve naming (variables, functions, classes)
4. Add error handling where missing
5. Remove code duplication
6. Apply design patterns where appropriate
7. Make code testable (dependency injection, pure functions)
8. Add type safety if applicable (TypeScript, type hints)
9. Follow SOLID principles
10. Maintain exact same functionality (behavior must not change!)

For each change:
- Explain what you changed
- Why it's better
- Show before/after comparison

Provide step-by-step refactoring (don't change everything at once).

📋 Example: JavaScript Modernization

// ❌ Legacy Code (ES5, 2012)
function processUserData(userId, callback) {
  var xhr = new XMLHttpRequest();
  xhr.open('GET', '/api/users/' + userId);
  xhr.onload = function() {
    if (xhr.status === 200) {
      var user = JSON.parse(xhr.responseText);
      var orders = [];
      
      for (var i = 0; i < user.orderIds.length; i++) {
        var orderXhr = new XMLHttpRequest();
        orderXhr.open('GET', '/api/orders/' + user.orderIds[i], false);  // Sync!
        orderXhr.send();
        orders.push(JSON.parse(orderXhr.responseText));
      }
      
      var total = 0;
      for (var j = 0; j < orders.length; j++) {
        total = total + orders[j].amount;
      }
      
      user.totalSpent = total;
      callback(null, user);
    } else {
      callback(new Error('User not found'));
    }
  };
  xhr.send();
}

// ✅ AI Refactored (Modern ES2023)
async function getUserWithOrders(userId) {
  try {
    const user = await fetchUser(userId);
    const orders = await fetchUserOrders(user.orderIds);
    const totalSpent = calculateTotalSpent(orders);
    
    return { ...user, totalSpent, orders };
  } catch (error) {
    throw new Error(`Failed to load user ${userId}: ${error.message}`);
  }
}

// Extracted helper functions (testable, reusable)
async function fetchUser(userId) {
  const response = await fetch(`/api/users/${userId}`);
  if (!response.ok) {
    throw new Error('User not found');
  }
  return response.json();
}

async function fetchUserOrders(orderIds) {
  // Parallel requests instead of synchronous loop!
  const orderPromises = orderIds.map(id => 
    fetch(`/api/orders/${id}`).then(r => r.json())
  );
  return Promise.all(orderPromises);
}

function calculateTotalSpent(orders) {
  return orders.reduce((sum, order) => sum + order.amount, 0);
}

// Changes Made:
// 1. XMLHttpRequest → fetch (modern API)
// 2. Callbacks → async/await (cleaner async)
// 3. Synchronous XHR → parallel async (faster!)
// 4. String concatenation → template literals
// 5. var → const (block scope)
// 6. for loops → map/reduce (functional)
// 7. One big function → 4 testable functions
// 8. Better error messages
// 9. Object spread for immutability

Pattern Application Prompt

This code has code smells and anti-patterns. Refactor using appropriate design patterns:

[paste code]

Identify patterns to apply:
- Strategy pattern for conditional logic
- Factory pattern for object creation
- Observer pattern for event handling
- Dependency injection for testability
- Repository pattern for data access
- Command pattern for operations
- etc.

For each pattern:
1. Explain why it fits
2. Show refactored code
3. Explain benefits gained

🎯 Example: Strategy Pattern

// ❌ Before: Giant if-else
function calculateShipping(order) {
  if (order.method === 'standard') {
    if (order.weight < 5) return 5;
    else if (order.weight < 10) return 10;
    else return 15;
  } else if (order.method === 'express') {
    if (order.weight < 5) return 15;
    else if (order.weight < 10) return 25;
    else return 40;
  } else if (order.method === 'overnight') {
    if (order.weight < 5) return 30;
    else if (order.weight < 10) return 50;
    else return 75;
  }
  return 0;
}

// ✅ After: Strategy Pattern
class StandardShipping {
  calculate(weight) {
    if (weight < 5) return 5;
    if (weight < 10) return 10;
    return 15;
  }
}

class ExpressShipping {
  calculate(weight) {
    if (weight < 5) return 15;
    if (weight < 10) return 25;
    return 40;
  }
}

class OvernightShipping {
  calculate(weight) {
    if (weight < 5) return 30;
    if (weight < 10) return 50;
    return 75;
  }
}

const shippingStrategies = {
  standard: new StandardShipping(),
  express: new ExpressShipping(),
  overnight: new OvernightShipping()
};

function calculateShipping(order) {
  const strategy = shippingStrategies[order.method];
  if (!strategy) {
    throw new Error(`Unknown shipping method: ${order.method}`);
  }
  return strategy.calculate(order.weight);
}

// Benefits:
// - Easy to add new shipping methods (just add class)
// - Each strategy is testable in isolation
// - No complex if-else chains
// - Open/Closed principle (open for extension, closed for modification)

TypeScript Migration Prompt

Convert this JavaScript code to TypeScript with full type safety:

[paste JS code]

Requirements:
- Add proper type annotations for all functions
- Define interfaces for data structures
- Use generics where appropriate
- Add return types
- Make nullable values explicit (| null)
- Use enums for constants
- Enable strict mode compliance
- Add JSDoc comments for complex types

Show gradual migration path (don't need to convert everything at once).

✅ What AI Helps Refactor

  • God classes: Break into single-responsibility classes
  • Long methods: Extract smaller, testable functions
  • Code duplication: Extract to reusable functions
  • Callback hell: Convert to async/await
  • Magic numbers: Extract to named constants
  • Tight coupling: Introduce dependency injection

💡 Pro Tips

  • Refactor incrementally: Ask AI to refactor in steps, test each step
  • Preserve behavior: Emphasize "functionality must not change"
  • Request tests: "Generate unit tests for refactored code"
  • Explain reasoning: Understanding why helps you learn
  • Review carefully: AI can miss edge cases, always review

🎯 Refactoring Checklist

Code Smell Refactoring
Long method (>50 lines) Extract method
Duplicate code Extract function/class
Deep nesting (>3 levels) Guard clauses, early returns
Many parameters (>4) Parameter object
Switch statements Polymorphism, Strategy pattern

"Inherited 2000-line controller from developer who left. Used AI to refactor into 15 service classes with clear responsibilities. Code went from untestable nightmare to 95% test coverage. AI explained every pattern it applied."

— Tech Lead

Related posts:

AI Prompt: Generate Realistic Test Data for Development

AI Prompt — Detect Hidden Race Conditions

AI Prompt: Convert Legacy Code to Modern Patterns

Post Views: 3

Post navigation

AI Prompt: Optimize Slow SQL Queries with AI Analysis
Windows 11: Install PowerToys for 20+ Productivity Features

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

April 2026
M T W T F S S
 12345
6789101112
13141516171819
20212223242526
27282930  
« Mar    

Most Viewed Posts

  • Get the User Name and Domain Name from an Email Address in SQL (950)
  • How to add default value for Entity Framework migrations for DateTime and Bool (858)
  • Get the First and Last Word from a String or Sentence in SQL (836)
  • How to select distinct rows in a datatable in C# (805)
  • How to make theater mode the default for Youtube (751)
  • Add Constraint to SQL Table to ensure email contains @ (578)
  • How to enable, disable and check if Service Broker is enabled on a database in SQL Server (564)
  • Average of all values in a column that are not zero in SQL (531)
  • How to use Map Mode for Vertical Scroll Mode in Visual Studio (489)
  • Find numbers with more than two decimal places in SQL (447)

Recent Posts

  • C#: Use Init-Only Setters for Immutable Objects After Construction
  • C#: Use Expression-Bodied Members for Concise Single-Line Methods
  • C#: Enable Nullable Reference Types to Eliminate Null Reference Exceptions
  • C#: Use Record Types for Immutable Data Objects
  • SQL: Use CTEs for Readable Complex Queries
  • SQL: Use Window Functions for Advanced Analytical Queries
  • .NET Core: Use Background Services for Long-Running Tasks
  • .NET Core: Use Minimal APIs for Lightweight HTTP Services
  • Git: Use Cherry-Pick to Apply Specific Commits Across Branches
  • Git: Use Interactive Rebase to Clean Up Commit History Before Merge

Most Viewed Posts

  • Get the User Name and Domain Name from an Email Address in SQL (950)
  • How to add default value for Entity Framework migrations for DateTime and Bool (858)
  • Get the First and Last Word from a String or Sentence in SQL (836)
  • How to select distinct rows in a datatable in C# (805)
  • How to make theater mode the default for Youtube (751)

Recent Posts

  • C#: Use Init-Only Setters for Immutable Objects After Construction
  • C#: Use Expression-Bodied Members for Concise Single-Line Methods
  • C#: Enable Nullable Reference Types to Eliminate Null Reference Exceptions
  • C#: Use Record Types for Immutable Data Objects
  • SQL: Use CTEs for Readable Complex Queries

Social

  • ErcanOPAK.com
  • GoodReads
  • LetterBoxD
  • Linkedin
  • The Blog
  • Twitter
© 2026 Bits of .NET | Built with Xblog Plus free WordPress theme by wpthemespace.com