Pair Programming Techniques with Claude Sonnet 3.5

Pair programming techniques with Claude
Advanced dialogue with AI for software development
Mauto 6 min

After exploring the basics of collaborating with Claude, let’s see how to take the interaction to the next level. The key is knowing how to structure the conversation to get the most out of the AI.

Collaborative Refactoring

When we need to refactor complex code, Claude shines at analysis and suggestions. Here’s a real example:

Me: I have this 500-line monolithic controller that handles every operation on orders. 
How can I refactor it?

Claude: To help you effectively, I'd need to see:
1. The controller code
2. The main dependencies
3. The most common usage patterns

Can you share this information?

Me: [I share the controller code]

Claude: Let's analyze the code step by step. I can see several responsibilities mixed together:
- Authentication and authorization
- Input validation
- Order business logic
- Notifications
- Logging

I suggest we start by separating these concerns. 
Let's begin with authentication. 
Do you want to see how to extract this part into a separate service?

Me: Yes, show me how to separate authentication

Claude: Let's first create the authentication service interface:
interface AuthenticationService {
    validateToken(token: string): Promise<User>;
    checkPermissions(user: User, resource: string): Promise<boolean>;
}
This lets you:
1. Test the controller with a mocked authentication
2. Swap implementations without touching the controller
3. Reuse the logic in other controllers

Do you want to see the full implementation?

[the conversation continues...]

Prompt Engineering Example for Code Review

To get an effective code review, structure your prompt like this:

Can you do a code review of this class? Focus on:
- SOLID principles
- Error handling
- Performance
- Security

[code to review]

Claude: I'll analyze the code according to the requested criteria.

SOLID:
- Single Responsibility: The class handles both authentication and logging
- Open/Closed: There's no interface for extending the auth methods

Error Handling:
- generic catch could hide critical errors
- missing structured logs for debugging

Performance:
- The cache is invalidated too frequently
- DB queries are not optimized

Security:
- Password hash doesn't use a salt
- JWT token with no expiration

Do you want to dig deeper into any of these aspects?

Dev: Let's dig into the security part

Claude: Here are the changes needed for security:

1. Password hashing:
import { hash, compare } from 'bcrypt';

// Before
password: await crypto.hash(password)

// After
const SALT_ROUNDS = 12;
password: await hash(password, SALT_ROUNDS)

JWT token:

// Before
jwt.sign({ userId }, SECRET_KEY)

// After
jwt.sign({
    userId,
    exp: Math.floor(Date.now() / 1000) + (60 * 60), // 1h
    iat: Math.floor(Date.now() / 1000)
}, SECRET_KEY)

Do you want me to add rate limiting and brute force protection too?

AI-Guided Refactoring

For refactoring, use incremental prompts:

Dev: I need to refactor this monolithic controller:
[300-line controller code]

Claude: Let's start by identifying the responsibilities:
1. Authentication handling
2. Input validation
3. Business logic
4. HTTP responses

I'd suggest starting by separating authentication. Shall we go step by step?

Dev: Yes, let's start with authentication

Claude: First, let's extract the interface:

interface AuthService {
  validateToken(token: string): Promise<User>;
  refreshToken(token: string): Promise<string>;
}

Now let's create the implementation...

Collaborative Debugging

Claude excels at analyzing errors and suggesting solutions. Example:

Me: I have this error in production that I can't reproduce locally:
TypeError: Cannot read property 'items' of undefined
at OrderProcessor.calculateTotal (orderProcessor.ts:45)

Claude: To debug this error, I need to know:
1. The OrderProcessor code
2. Where the items data comes from
3. Under what conditions the error occurs
4. The production logs related to the error

Can you provide this information?

Me: [I share the code and the logs]

Claude: Looking at the code and the logs, I see two possible scenarios:
1. OrderProcessor receives an undefined order when the database is overloaded
2. The race condition on line 43 can cause items to be accessed before the order is fully loaded

I'd suggest adding these checks:
calculateTotal(order: Order) {
    if (!order) {
        throw new OrderNotFoundError('Order is undefined');
    }
    
    if (!order.items) {
        throw new InvalidOrderError('Order has no items');
    }
    
    // rest of the code...
}
Do you also want me to show you how to add structured logging to better track these cases?

Test Generation

Claude can help identify edge cases and generate tests:

Me: I need to write tests for this payment service. Which scenarios should I test?

Claude: Let's analyze the service to identify the critical scenarios. I see it handles:
- Card payments
- PayPal
- Bank transfers

Each payment method has its own edge cases. Let's start with card payments:
describe('CreditCardPayment', () => {
    it('processes a valid payment', async () => {
        // test implementation
    });

    it('handles an expired card', async () => {
        // test implementation
    });

    it('handles insufficient funds', async () => {
        // test implementation
    });
});
Do you want to see the detailed implementation of these tests, or would you rather move on to the PayPal scenarios?

[the conversation continues...]

Interaction Best Practices

To get the most out of Claude:


Provide Complete Context

Me: How can I improve this code?
[I share the order.php code]

Claude: To give you relevant suggestions, I'd need to know:
- What the purpose of this code is
- In what context it's used  
- What the non-functional requirements are
- What technical constraints exist

Can you provide this information?

Me: It's an order management system for an e-commerce site. It uses PHP 7.4 and MySQL. It needs to handle about 1,000 orders a day.

Claude: Thanks for the context. I see several areas for improvement:
1. Error handling is missing
2. There's no input validation
3. The queries could be optimized 

Shall we start with error handling?

Me: Yes, show me how you would implement error handling

Claude: Here's an example of structured error handling...
[the conversation continues with a detailed implementation]

Incremental Iteration

Me: I have a performance problem with this endpoint.

Claude: Let's tackle the problem step by step:
1. Can I see the endpoint code?
2. Do you have data on the current performance?
3. Are there any response time constraints?

Me: The endpoint runs a product search. It responds in 3 seconds and we'd like to get it under one second.
[I share the code]

Claude: Let's look at the potential bottlenecks:
1. The query doesn't use indexes
2. Pagination is missing
3. There's an N+1 query problem

Let's start by optimizing the query. Can I see the database schema?

Me: [I share the schema]

Claude: OK, I'd suggest these immediate changes:
1. Add a composite index on (category, price)  
2. Implement pagination
3. Eager loading of relationships

Do you want to see the implementation of any of these?

Summing Up: Best Practices for Talking to Claude

Provide Context: Always include:

  • Dependency versions
  • Project constraints
  • Specific use cases

Ask for Explanations: If a solution isn’t clear, have Claude walk you through its reasoning

  • Verify the Solutions: Don’t blindly implement the suggestions
  • Progressive Iteration: Tackle one problem at a time

Limitations and Workarounds

Claude has some limitations you need to be aware of:

  • It Can’t Test the Code: Always give feedback on the implementation
  • Limited Context: Keep Claude updated on previous changes
  • Theoretical Patterns: Adapt the suggestions to your specific case

Conclusion

Advanced pair programming with Claude works best when:

  • The prompts are specific
  • It receives complete context
  • It can analyze the problem incrementally
  • It’s guided with specific questions

In the next article of the series, we’ll see how to use Claude for code optimization.

Copiato