developer-ai 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +241 -0
- package/bin/developer-ai.js +2 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +219 -0
- package/dist/cli.js.map +1 -0
- package/dist/config/index.d.ts +7 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +82 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/schema.d.ts +115 -0
- package/dist/config/schema.d.ts.map +1 -0
- package/dist/config/schema.js +29 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/constants.d.ts +8 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +8 -0
- package/dist/constants.js.map +1 -0
- package/dist/core/agent.d.ts +38 -0
- package/dist/core/agent.d.ts.map +1 -0
- package/dist/core/agent.js +155 -0
- package/dist/core/agent.js.map +1 -0
- package/dist/core/system-prompt.d.ts +6 -0
- package/dist/core/system-prompt.d.ts.map +1 -0
- package/dist/core/system-prompt.js +44 -0
- package/dist/core/system-prompt.js.map +1 -0
- package/dist/core/types.d.ts +42 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +6 -0
- package/dist/core/types.js.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp/client.d.ts +13 -0
- package/dist/mcp/client.d.ts.map +1 -0
- package/dist/mcp/client.js +202 -0
- package/dist/mcp/client.js.map +1 -0
- package/dist/providers/ollama.d.ts +13 -0
- package/dist/providers/ollama.d.ts.map +1 -0
- package/dist/providers/ollama.js +60 -0
- package/dist/providers/ollama.js.map +1 -0
- package/dist/providers/openai.d.ts +9 -0
- package/dist/providers/openai.d.ts.map +1 -0
- package/dist/providers/openai.js +40 -0
- package/dist/providers/openai.js.map +1 -0
- package/dist/skills/loader.d.ts +25 -0
- package/dist/skills/loader.d.ts.map +1 -0
- package/dist/skills/loader.js +93 -0
- package/dist/skills/loader.js.map +1 -0
- package/dist/tests/tools.test.d.ts +2 -0
- package/dist/tests/tools.test.d.ts.map +1 -0
- package/dist/tests/tools.test.js +170 -0
- package/dist/tests/tools.test.js.map +1 -0
- package/dist/tools/index.d.ts +5 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +19 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/list-files.d.ts +3 -0
- package/dist/tools/list-files.d.ts.map +1 -0
- package/dist/tools/list-files.js +60 -0
- package/dist/tools/list-files.js.map +1 -0
- package/dist/tools/read-file.d.ts +3 -0
- package/dist/tools/read-file.d.ts.map +1 -0
- package/dist/tools/read-file.js +46 -0
- package/dist/tools/read-file.js.map +1 -0
- package/dist/tools/registry.d.ts +24 -0
- package/dist/tools/registry.d.ts.map +1 -0
- package/dist/tools/registry.js +37 -0
- package/dist/tools/registry.js.map +1 -0
- package/dist/tools/run-command.d.ts +3 -0
- package/dist/tools/run-command.d.ts.map +1 -0
- package/dist/tools/run-command.js +114 -0
- package/dist/tools/run-command.js.map +1 -0
- package/dist/tools/search-text.d.ts +3 -0
- package/dist/tools/search-text.d.ts.map +1 -0
- package/dist/tools/search-text.js +103 -0
- package/dist/tools/search-text.js.map +1 -0
- package/dist/tools/utils.d.ts +6 -0
- package/dist/tools/utils.d.ts.map +1 -0
- package/dist/tools/utils.js +14 -0
- package/dist/tools/utils.js.map +1 -0
- package/dist/tools/web-search.d.ts +3 -0
- package/dist/tools/web-search.d.ts.map +1 -0
- package/dist/tools/web-search.js +80 -0
- package/dist/tools/web-search.js.map +1 -0
- package/dist/tools/write-file.d.ts +3 -0
- package/dist/tools/write-file.d.ts.map +1 -0
- package/dist/tools/write-file.js +66 -0
- package/dist/tools/write-file.js.map +1 -0
- package/package.json +54 -0
- package/skills/accessibility/SKILL.md +496 -0
- package/skills/api-design/SKILL.md +419 -0
- package/skills/code-review/SKILL.md +267 -0
- package/skills/debugging/SKILL.md +332 -0
- package/skills/documentation/SKILL.md +496 -0
- package/skills/error-handling/SKILL.md +504 -0
- package/skills/git-workflow/SKILL.md +448 -0
- package/skills/human-like-coding/SKILL.md +400 -0
- package/skills/performance-optimization/SKILL.md +412 -0
- package/skills/prompt-engineering/SKILL.md +362 -0
- package/skills/refactoring/SKILL.md +457 -0
- package/skills/security-audit/SKILL.md +453 -0
- package/skills/testing-strategy/SKILL.md +501 -0
- package/skills/webapp-testing/SKILL.md +309 -0
|
@@ -0,0 +1,457 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: refactoring
|
|
3
|
+
description: Guide for improving code quality through refactoring. Use when cleaning up technical debt, improving performance, simplifying complex code, or preparing for new features. Covers code smells, refactoring patterns, and safe refactoring practices.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Refactoring Skill
|
|
7
|
+
|
|
8
|
+
This skill provides guidance for safely improving code quality through systematic refactoring.
|
|
9
|
+
|
|
10
|
+
## Overview
|
|
11
|
+
|
|
12
|
+
Refactoring is the process of restructuring code without changing its external behavior. Good refactoring improves readability, maintainability, and often performance.
|
|
13
|
+
|
|
14
|
+
## Code Smells
|
|
15
|
+
|
|
16
|
+
### Long Functions
|
|
17
|
+
|
|
18
|
+
**Smell:** Functions doing too many things
|
|
19
|
+
```javascript
|
|
20
|
+
// BEFORE: 50+ line function
|
|
21
|
+
function processOrder(order) {
|
|
22
|
+
// Validate order (10 lines)
|
|
23
|
+
// Calculate totals (15 lines)
|
|
24
|
+
// Apply discounts (10 lines)
|
|
25
|
+
// Update inventory (10 lines)
|
|
26
|
+
// Send notifications (15 lines)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// AFTER: Extracted into focused functions
|
|
30
|
+
function processOrder(order) {
|
|
31
|
+
validateOrder(order);
|
|
32
|
+
const totals = calculateTotals(order);
|
|
33
|
+
const finalTotal = applyDiscounts(totals, order.customer);
|
|
34
|
+
updateInventory(order.items);
|
|
35
|
+
sendOrderNotifications(order);
|
|
36
|
+
return finalTotal;
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Duplicate Code
|
|
41
|
+
|
|
42
|
+
**Smell:** Same logic repeated in multiple places
|
|
43
|
+
```javascript
|
|
44
|
+
// BEFORE: Duplicated validation
|
|
45
|
+
function createUser(data) {
|
|
46
|
+
if (!data.email || !data.email.includes('@')) {
|
|
47
|
+
throw new Error('Invalid email');
|
|
48
|
+
}
|
|
49
|
+
// ...
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function updateUser(data) {
|
|
53
|
+
if (!data.email || !data.email.includes('@')) {
|
|
54
|
+
throw new Error('Invalid email');
|
|
55
|
+
}
|
|
56
|
+
// ...
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// AFTER: Extracted to reusable function
|
|
60
|
+
function validateEmail(email) {
|
|
61
|
+
if (!email || !email.includes('@')) {
|
|
62
|
+
throw new Error('Invalid email');
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function createUser(data) {
|
|
67
|
+
validateEmail(data.email);
|
|
68
|
+
// ...
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function updateUser(data) {
|
|
72
|
+
validateEmail(data.email);
|
|
73
|
+
// ...
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### Large Classes
|
|
78
|
+
|
|
79
|
+
**Smell:** Class with too many responsibilities
|
|
80
|
+
```javascript
|
|
81
|
+
// BEFORE: God class
|
|
82
|
+
class UserManager {
|
|
83
|
+
createUser() { }
|
|
84
|
+
deleteUser() { }
|
|
85
|
+
validateEmail() { }
|
|
86
|
+
hashPassword() { }
|
|
87
|
+
sendWelcomeEmail() { }
|
|
88
|
+
sendPasswordReset() { }
|
|
89
|
+
generateReport() { }
|
|
90
|
+
exportToCSV() { }
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// AFTER: Split by responsibility
|
|
94
|
+
class UserService {
|
|
95
|
+
createUser() { }
|
|
96
|
+
deleteUser() { }
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
class UserValidator {
|
|
100
|
+
validateEmail() { }
|
|
101
|
+
validatePassword() { }
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
class EmailService {
|
|
105
|
+
sendWelcomeEmail() { }
|
|
106
|
+
sendPasswordReset() { }
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
class UserReporter {
|
|
110
|
+
generateReport() { }
|
|
111
|
+
exportToCSV() { }
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### Feature Envy
|
|
116
|
+
|
|
117
|
+
**Smell:** Method uses another class's data more than its own
|
|
118
|
+
```javascript
|
|
119
|
+
// BEFORE: Order method accessing customer internals
|
|
120
|
+
class Order {
|
|
121
|
+
calculateDiscount() {
|
|
122
|
+
if (this.customer.loyaltyYears > 5 &&
|
|
123
|
+
this.customer.totalPurchases > 10000 &&
|
|
124
|
+
this.customer.tier === 'gold') {
|
|
125
|
+
return this.total * 0.2;
|
|
126
|
+
}
|
|
127
|
+
return 0;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// AFTER: Move logic to the appropriate class
|
|
132
|
+
class Customer {
|
|
133
|
+
getDiscountRate() {
|
|
134
|
+
if (this.loyaltyYears > 5 &&
|
|
135
|
+
this.totalPurchases > 10000 &&
|
|
136
|
+
this.tier === 'gold') {
|
|
137
|
+
return 0.2;
|
|
138
|
+
}
|
|
139
|
+
return 0;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
class Order {
|
|
144
|
+
calculateDiscount() {
|
|
145
|
+
return this.total * this.customer.getDiscountRate();
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### Primitive Obsession
|
|
151
|
+
|
|
152
|
+
**Smell:** Using primitives instead of small objects
|
|
153
|
+
```javascript
|
|
154
|
+
// BEFORE: Phone number as string
|
|
155
|
+
function formatPhoneNumber(phone) {
|
|
156
|
+
return `(${phone.slice(0,3)}) ${phone.slice(3,6)}-${phone.slice(6)}`;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// AFTER: Encapsulate in value object
|
|
160
|
+
class PhoneNumber {
|
|
161
|
+
constructor(number) {
|
|
162
|
+
this.number = number.replace(/\D/g, '');
|
|
163
|
+
if (this.number.length !== 10) {
|
|
164
|
+
throw new Error('Invalid phone number');
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
format() {
|
|
169
|
+
return `(${this.areaCode}) ${this.exchange}-${this.subscriber}`;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
get areaCode() { return this.number.slice(0, 3); }
|
|
173
|
+
get exchange() { return this.number.slice(3, 6); }
|
|
174
|
+
get subscriber() { return this.number.slice(6); }
|
|
175
|
+
}
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
### Deep Nesting
|
|
179
|
+
|
|
180
|
+
**Smell:** Excessive conditional nesting
|
|
181
|
+
```javascript
|
|
182
|
+
// BEFORE: Deeply nested
|
|
183
|
+
function processPayment(order) {
|
|
184
|
+
if (order) {
|
|
185
|
+
if (order.items.length > 0) {
|
|
186
|
+
if (order.customer) {
|
|
187
|
+
if (order.customer.paymentMethod) {
|
|
188
|
+
if (order.customer.paymentMethod.isValid()) {
|
|
189
|
+
// Process payment
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// AFTER: Early returns (guard clauses)
|
|
198
|
+
function processPayment(order) {
|
|
199
|
+
if (!order) return { error: 'No order' };
|
|
200
|
+
if (order.items.length === 0) return { error: 'Empty order' };
|
|
201
|
+
if (!order.customer) return { error: 'No customer' };
|
|
202
|
+
if (!order.customer.paymentMethod) return { error: 'No payment method' };
|
|
203
|
+
if (!order.customer.paymentMethod.isValid()) return { error: 'Invalid payment' };
|
|
204
|
+
|
|
205
|
+
// Process payment
|
|
206
|
+
}
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
## Refactoring Patterns
|
|
210
|
+
|
|
211
|
+
### Extract Function
|
|
212
|
+
|
|
213
|
+
```javascript
|
|
214
|
+
// BEFORE
|
|
215
|
+
function printBill(order) {
|
|
216
|
+
console.log('=========');
|
|
217
|
+
console.log('RECEIPT');
|
|
218
|
+
console.log('=========');
|
|
219
|
+
|
|
220
|
+
for (const item of order.items) {
|
|
221
|
+
console.log(`${item.name}: $${item.price}`);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
const total = order.items.reduce((sum, item) => sum + item.price, 0);
|
|
225
|
+
console.log('=========');
|
|
226
|
+
console.log(`Total: $${total}`);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// AFTER
|
|
230
|
+
function printBill(order) {
|
|
231
|
+
printHeader();
|
|
232
|
+
printItems(order.items);
|
|
233
|
+
printTotal(calculateTotal(order.items));
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
function printHeader() {
|
|
237
|
+
console.log('=========');
|
|
238
|
+
console.log('RECEIPT');
|
|
239
|
+
console.log('=========');
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
function printItems(items) {
|
|
243
|
+
for (const item of items) {
|
|
244
|
+
console.log(`${item.name}: $${item.price}`);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
function calculateTotal(items) {
|
|
249
|
+
return items.reduce((sum, item) => sum + item.price, 0);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
function printTotal(total) {
|
|
253
|
+
console.log('=========');
|
|
254
|
+
console.log(`Total: $${total}`);
|
|
255
|
+
}
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
### Replace Conditional with Polymorphism
|
|
259
|
+
|
|
260
|
+
```javascript
|
|
261
|
+
// BEFORE
|
|
262
|
+
function calculateShipping(order) {
|
|
263
|
+
switch (order.shippingType) {
|
|
264
|
+
case 'standard':
|
|
265
|
+
return order.weight * 1.5;
|
|
266
|
+
case 'express':
|
|
267
|
+
return order.weight * 3.0 + 10;
|
|
268
|
+
case 'overnight':
|
|
269
|
+
return order.weight * 5.0 + 25;
|
|
270
|
+
default:
|
|
271
|
+
throw new Error('Unknown shipping type');
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
// AFTER
|
|
276
|
+
class ShippingCalculator {
|
|
277
|
+
calculate(order) {
|
|
278
|
+
throw new Error('Must implement');
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
class StandardShipping extends ShippingCalculator {
|
|
283
|
+
calculate(order) {
|
|
284
|
+
return order.weight * 1.5;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
class ExpressShipping extends ShippingCalculator {
|
|
289
|
+
calculate(order) {
|
|
290
|
+
return order.weight * 3.0 + 10;
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
class OvernightShipping extends ShippingCalculator {
|
|
295
|
+
calculate(order) {
|
|
296
|
+
return order.weight * 5.0 + 25;
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
// Factory to get correct calculator
|
|
301
|
+
const shippingCalculators = {
|
|
302
|
+
standard: new StandardShipping(),
|
|
303
|
+
express: new ExpressShipping(),
|
|
304
|
+
overnight: new OvernightShipping(),
|
|
305
|
+
};
|
|
306
|
+
|
|
307
|
+
function calculateShipping(order) {
|
|
308
|
+
return shippingCalculators[order.shippingType].calculate(order);
|
|
309
|
+
}
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
### Introduce Parameter Object
|
|
313
|
+
|
|
314
|
+
```javascript
|
|
315
|
+
// BEFORE: Too many parameters
|
|
316
|
+
function searchProducts(category, minPrice, maxPrice, inStock, sortBy, sortOrder) {
|
|
317
|
+
// ...
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
searchProducts('electronics', 100, 500, true, 'price', 'asc');
|
|
321
|
+
|
|
322
|
+
// AFTER: Parameter object
|
|
323
|
+
function searchProducts(options) {
|
|
324
|
+
const { category, minPrice, maxPrice, inStock, sortBy, sortOrder } = options;
|
|
325
|
+
// ...
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
searchProducts({
|
|
329
|
+
category: 'electronics',
|
|
330
|
+
minPrice: 100,
|
|
331
|
+
maxPrice: 500,
|
|
332
|
+
inStock: true,
|
|
333
|
+
sortBy: 'price',
|
|
334
|
+
sortOrder: 'asc',
|
|
335
|
+
});
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
### Replace Magic Numbers with Constants
|
|
339
|
+
|
|
340
|
+
```javascript
|
|
341
|
+
// BEFORE
|
|
342
|
+
if (user.age >= 21) {
|
|
343
|
+
// ...
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
setTimeout(callback, 86400000);
|
|
347
|
+
|
|
348
|
+
// AFTER
|
|
349
|
+
const LEGAL_DRINKING_AGE = 21;
|
|
350
|
+
const ONE_DAY_MS = 24 * 60 * 60 * 1000;
|
|
351
|
+
|
|
352
|
+
if (user.age >= LEGAL_DRINKING_AGE) {
|
|
353
|
+
// ...
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
setTimeout(callback, ONE_DAY_MS);
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
### Decompose Conditional
|
|
360
|
+
|
|
361
|
+
```javascript
|
|
362
|
+
// BEFORE
|
|
363
|
+
if (date.before(SUMMER_START) || date.after(SUMMER_END)) {
|
|
364
|
+
charge = quantity * winterRate + winterServiceCharge;
|
|
365
|
+
} else {
|
|
366
|
+
charge = quantity * summerRate;
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
// AFTER
|
|
370
|
+
function isWinter(date) {
|
|
371
|
+
return date.before(SUMMER_START) || date.after(SUMMER_END);
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
function winterCharge(quantity) {
|
|
375
|
+
return quantity * winterRate + winterServiceCharge;
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
function summerCharge(quantity) {
|
|
379
|
+
return quantity * summerRate;
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
charge = isWinter(date) ? winterCharge(quantity) : summerCharge(quantity);
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
## Safe Refactoring Process
|
|
386
|
+
|
|
387
|
+
### 1. Ensure Test Coverage
|
|
388
|
+
|
|
389
|
+
```javascript
|
|
390
|
+
// Write tests BEFORE refactoring
|
|
391
|
+
describe('calculateShipping', () => {
|
|
392
|
+
it('calculates standard shipping', () => {
|
|
393
|
+
const order = { weight: 10, shippingType: 'standard' };
|
|
394
|
+
expect(calculateShipping(order)).toBe(15);
|
|
395
|
+
});
|
|
396
|
+
|
|
397
|
+
it('calculates express shipping', () => {
|
|
398
|
+
const order = { weight: 10, shippingType: 'express' };
|
|
399
|
+
expect(calculateShipping(order)).toBe(40);
|
|
400
|
+
});
|
|
401
|
+
|
|
402
|
+
// ... more tests
|
|
403
|
+
});
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
### 2. Small Steps
|
|
407
|
+
|
|
408
|
+
```javascript
|
|
409
|
+
// DON'T: Refactor everything at once
|
|
410
|
+
|
|
411
|
+
// DO: One small change at a time
|
|
412
|
+
// Step 1: Extract one method
|
|
413
|
+
// Step 2: Run tests
|
|
414
|
+
// Step 3: Extract another method
|
|
415
|
+
// Step 4: Run tests
|
|
416
|
+
// ...
|
|
417
|
+
```
|
|
418
|
+
|
|
419
|
+
### 3. Commit Frequently
|
|
420
|
+
|
|
421
|
+
```bash
|
|
422
|
+
# After each successful refactoring step
|
|
423
|
+
git add .
|
|
424
|
+
git commit -m "refactor: extract calculateTotal function"
|
|
425
|
+
|
|
426
|
+
git add .
|
|
427
|
+
git commit -m "refactor: extract printHeader function"
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
### 4. Use IDE Refactoring Tools
|
|
431
|
+
|
|
432
|
+
Most IDEs have built-in refactoring:
|
|
433
|
+
- Extract Method/Function
|
|
434
|
+
- Rename Symbol
|
|
435
|
+
- Move to File
|
|
436
|
+
- Inline Variable
|
|
437
|
+
- Extract Variable
|
|
438
|
+
|
|
439
|
+
## Refactoring Checklist
|
|
440
|
+
|
|
441
|
+
### Before Starting
|
|
442
|
+
- [ ] Tests pass
|
|
443
|
+
- [ ] Understand current behavior
|
|
444
|
+
- [ ] Identified specific improvement
|
|
445
|
+
- [ ] Have a rollback plan
|
|
446
|
+
|
|
447
|
+
### During Refactoring
|
|
448
|
+
- [ ] One change at a time
|
|
449
|
+
- [ ] Tests passing after each change
|
|
450
|
+
- [ ] Committing frequently
|
|
451
|
+
- [ ] No new features added
|
|
452
|
+
|
|
453
|
+
### After Refactoring
|
|
454
|
+
- [ ] All tests pass
|
|
455
|
+
- [ ] Code review completed
|
|
456
|
+
- [ ] Documentation updated
|
|
457
|
+
- [ ] Performance verified
|