Repository navigation
Expand file tree
/
Copy path02-inline-function.ts
More file actions
107 lines (86 loc) · 3.25 KB
/
Copy path02-inline-function.ts
File metadata and controls
107 lines (86 loc) · 3.25 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
/**
* INLINE FUNCTION
*
* Replace a function call with the body of the function.
* The inverse of Extract Function.
*
* Motivation:
* - When a function body is as clear as its name
* - When you have a group of badly factored functions
* - When indirection is needless and irritating
* - When you want to refactor a group of functions (inline first, then re-extract)
*
* Mechanics:
* 1. Check that the function is not polymorphic (no overrides)
* 2. Find all callers of the function
* 3. Replace each call with the function body
* 4. Test after each replacement
* 5. Remove the function definition
*/
// ============================================================================
// BEFORE: Overly extracted functions
// ============================================================================
class DriverBefore {
private numberOfLateDeliveries: number;
constructor(lateDeliveries: number) {
this.numberOfLateDeliveries = lateDeliveries;
}
get lateDeliveries(): number {
return this.numberOfLateDeliveries;
}
}
function moreThanFiveLateDeliveries(driver: DriverBefore): boolean {
return driver.lateDeliveries > 5;
}
function getRatingBefore(driver: DriverBefore): number {
return moreThanFiveLateDeliveries(driver) ? 2 : 1;
}
// Another example: function that just delegates
function reportLinesBefore(customer: { name: string; location: string }): string[] {
const lines: string[] = [];
gatherCustomerData(lines, customer);
return lines;
}
function gatherCustomerData(out: string[], customer: { name: string; location: string }): void {
out.push(`Name: ${customer.name}`);
out.push(`Location: ${customer.location}`);
}
// ============================================================================
// AFTER: Inlined functions where appropriate
// ============================================================================
class Driver {
private numberOfLateDeliveries: number;
constructor(lateDeliveries: number) {
this.numberOfLateDeliveries = lateDeliveries;
}
get lateDeliveries(): number {
return this.numberOfLateDeliveries;
}
}
// The condition is simple enough to be inline
function getRating(driver: Driver): number {
return driver.lateDeliveries > 5 ? 2 : 1;
}
// The delegation is removed, logic is inline
function reportLines(customer: { name: string; location: string }): string[] {
const lines: string[] = [];
lines.push(`Name: ${customer.name}`);
lines.push(`Location: ${customer.location}`);
return lines;
}
// ============================================================================
// USAGE DEMONSTRATION
// ============================================================================
console.log("=== Inline Function Refactoring ===\n");
const driver1 = new Driver(3);
const driver2 = new Driver(7);
console.log("--- Driver Ratings ---");
console.log(`Driver with 3 late deliveries: Rating ${getRating(driver1)}`);
console.log(`Driver with 7 late deliveries: Rating ${getRating(driver2)}`);
console.log("\n--- Customer Report ---");
const customer = { name: "Acme Corp", location: "New York" };
const lines = reportLines(customer);
lines.forEach((line) => console.log(line));
// Key insight: Not every piece of code needs its own function.
// Simple, clear expressions can be inline.
export {};