The first group of refactorings were:

Extract Function Extract Variable

The opposite refactoring:

Inline Function/Inline Variable Inline Variable

Extract function/inline function

It’s a bad example, but it goes something like this:

// Take an example of refining a function
func Cal(a int8)int8{ / / before the refactoring
    a = a + 1
    a = a * 5
    return a
}

func Cal(a int8)int8{ / / after the refactoring
    return multi5(add1(a))
}


// An example of an inline function
func Cal(a int8)int8{ / / before the refactoring
    a = add1(a)
    a = multi5(a)
    return a
}

func Cal(a int8)int8{ / / after the refactoring
    return add1Andmulti5(a)
}
Copy the code

Refine variables/inline variables

// Extract a variable as an example
func Cal(a int8)int8{ / / before the refactoring
    return ((a + 1) *5) /2
}
 
func Cal(a int8)int8{ / / after the refactoring
    b := a + 1
    c := b * 5
    return c/2
}

// Encapsulate variables in reverse order
Copy the code

DEMO

Assuming that we need to obtain the price of a commodity in our service, there are two tables for the price of the commodity, one is the temporary activity table to record the temporary preferential price of the activity, and the other is the original price table to record the original price of the commodity. If the data sources are not uniform, we hope to obtain the current price of the commodity:

func GetProductCurrentPrice(productID uint64)(float,error){... tempPrice = rbac.GetTempPrice(productID)// .... price = rbac.GetPrice(productID)// ....// Does something extra to return the final price by comparing the two prices.return price,nil
}
Copy the code

There are a number of problems with this approach:

  1. Should calling the Rbac service interface extract a separate function?
  2. If you need to do something to return the final price, should you consider refining the function?

Corresponding refactoring:

The method in calling the RBAC service should be wrapped as a separate function, which is decoupled from the RBAC service. In this way, when the RPC interface changes, only the function in GetPrice method needs to be modified, instead of global search and replacement:

func GetPrice(productID uint64)(int){
    return rbac.GetPrice(productID)
}
Copy the code

In the same way:

func GetTempPrice(productID)(int){
    return rbac.GetTempPrice(productID)
}
Copy the code

If you really need to compare the two prices and return the new price, then you need to do a refining function, because if it takes a little browsing to figure out the intent of the code, then you need to do a refining function:

func comparePrice(price,tempPrice int)(int){
    // ...
}
Copy the code

Therefore, in view of the above method, the extracted function after reconstruction should be:

func GetPrice(a){
    // 
}

func GetTempPrice(a){
    // 
}

func comparePrice(a){
    // 
}

func GetLowerPrice(productID uint64)(int,error){... price = GetPrice(productID) ... tempPrice = GetTempPrice(productID) ...return comparePrice(price,tempPrice),nil
}
Copy the code

Or use inline functions:

func GetLowerPrice(productID uint64)(int,error){
    return comparePrice(GetPrice(productID), GetTempPrice(productID)),nil
}
Copy the code

It looks much more elegant. 😛

conclusion

The key to refining is naming. Forming and naming functions, and changing function declarations, which can change the name of a function, can also be used to add or modify parameters, are the lowest level of refactoring but the most useful. Comments are often a good function name, try naming/renaming comments to functions, try making all comments redundant.