Friday, February 19, 2016

Refactoring - extract surrounding method

Apply this refactoring when two or more methods are identical except a piece of code somewhere in the middle.

You can create a function to contain the common code that receives a closure or a function to deal with the difference in code.

Consider we have couple of functions as follows. One is displaying the squares and the other one the cubes for values between one and ten.

func printSquares() {
    print("---")
    for i in 1...10 {
        print (i*i)
    }
    print("---")
}


func printCubes() {
    print("---")
    for i in 1...10 {
        print (i*i*i)
    }
    print("---")
}

printSquares()
printCubes()

We notice that the functions are identical, except the bold code.

We can create two functions for the that difference in functionality.

func square(number:Int) -> Int {
    return number * number
}

func cube(number:Int) -> Int {
    return number * number * number
}

Our refactored function will receive a function as a parameter

func printExponential(f:(Int)->Int){
    print("---")
    for i in 1...10 {
        print (f(i))
    }
    print("---")
}

Obviously, now we can invoke our new function in the following way

printExponential(square)

printExponential(cube)

The big advantage is now our code is very flexible. If we want to obtain a list of fourth power, we just need to write another function and invoke it without writing the main code again:

func fourthPower(number:Int) -> Int {
    return number * number * number * number
}


printExponential(fourthPower)

As I mentioned we can use directly closures:

printExponential { (n:Int) -> Int in
    n*n*n*n
}

As the parameter type is known, we can simplify even more:

printExponential { n in
    n*n*n*n
}

And even more:

printExponential ( {$0 * $0 * $0 * $0} )


No comments:

Post a Comment