Hello, Explorer! Today is about refactoring. Consider it like organizing your favorite toys in the toybox. We're going to learn about the Extract Function
, Rename Function
, and Substitute Algorithm
refactorings. Refactoring helps us make our code cleaner and neater while keeping the functionality the same!
Imagine having a complex map. Refactoring transforms it into simpler directions. Our code gets rearranged to make it more readable and efficient without altering what it does. Let's consider a small code snippet before and after refactoring:
Go1func Calculate(total float64, quantity int) float64 { 2 price := total / float64(quantity) 3 tax := price * 0.2 4 totalPrice := price + tax 5 return totalPrice 6}
Go1func CalculateTotalPrice(total float64, quantity int) float64 { 2 price := CalculatePrice(total, quantity) 3 tax := CalculateTax(price) 4 return price + tax 5} 6 7func CalculatePrice(total float64, quantity int) float64 { 8 return total / float64(quantity) 9} 10 11func CalculateTax(price float64) float64 { 12 return price * 0.2 13}
Both versions of the code do the same thing, but the latter is simpler and easier to understand!
Imagine a large recipe for a complete breakfast. The Extract Function
technique is like having separate recipes for eggs, toast, coffee, etc., instead of one large recipe. Take a look at this code:
Go1func GreetUser(username string) string { 2 username = strings.TrimSpace(strings.ToLower(username)) // Prepare the username 3 message := "Hello, " + username + "!" // Prepare the message 4 return message // Return the prepared message 5}
Go1func CleanUsername(username string) string { 2 return strings.TrimSpace(strings.ToLower(username)) // Returns a cleaned version of the username 3} 4 5func GreetUser(username string) string { 6 username = CleanUsername(username) // Clean the username 7 message := "Hello, " + username + "!" // Prepare and return the message 8 return message 9}
Here, we moved the username preparation from GreetUser
into its own function, CleanUsername
. Nice and tidy!
Clear function names make it easy to understand our code, just as clear street names make navigating a city more accessible. Let's have a look at renaming a function:
Go1func Fx(x float64) float64 { 2 return 3.14 * (x * x) // Calculates a value that is pi times the square of x 3}
Go1func CalculateCircleArea(radius float64) float64 { 2 return 3.14 * (radius * radius) // Calculates the area of a circle with a given radius 3}
Renaming the function Fx
to CalculateCircleArea
makes it easier to understand its purpose.
A Substitute Algorithm
involves replacing a part of a code (an algorithm) with a simpler one, analogous to discovering a faster route to school. Here's an example:
Go1func FindSmallest(numbers []int) int { 2 smallest := int(^uint(0) >> 1) 3 for _, num := range numbers { 4 if num < smallest { 5 smallest = num 6 } 7 } 8 return smallest 9}
Go1func FindSmallest(numbers []int) int { 2 if len(numbers) == 0 { 3 return 0 // or other appropriate error value based on context 4 } 5 smallest := numbers[0] 6 for _, num := range numbers { 7 if num < smallest { 8 smallest = num 9 } 10 } 11 return smallest 12}
Here, we manually find the smallest number in a slice of integers using a loop, without any extra libraries.
Great work! We've learned how to use the Extract Function
, Rename Function
, and Substitute Algorithm
to keep our code clean and efficient. Now, it's time for some hands-on practice with real examples. Remember, practice makes perfect. Let's do some refactoring!