메서드 정리 - ChoDragon9/posts GitHub Wiki
메서드 정리
메서드 추출(Extract Method)
어떤 코드를 그룹으로 묶어도 되겠다고 판단될 때
// Before
const printOwing = (amount) => {
printBanner()
console.log(`name:${_name}`)
console.log(`amount:${amount}`)
}
// After
const printOwing = (amount) => {
printBanner()
printDetails(amount)
}
const printDetails = (amount) => {
console.log(`name:${_name}`)
console.log(`amount:${amount}`)
}
메서드 내용 직접 삽입(Inline Method)
매서드 기능이 너무 단순해서 메서드명만 봐도 너무 뻔할 때
// Before
const moreThanFiveLateDeliveries = () => {
return _numberOfLateDeliveries > 5
}
const getRating = () => {
return (moreThanFiveLateDeliveries()) ? 2 : 1
}
// After
const getRating = () => {
return (_numberOfLateDeliveries > 5) ? 2 : 1
}
임시변수 내용 직접 삽입(Inline Temp)
간단한 수식을 대입받는 임시변수로 인해 다른 리팩토링 기법 적용이 힘들 때
// Before
const basePrice = anOrder.basePrice()
return basePrice > 1000
// After
return anOrder.basePrice() > 1000
임시변수를 메서드 호출로 변환(Replace Temp with Query)
수식의 결과를 저장하는 임시변수가 있을 때
// Before
const basePrice = _quantity * _itemPrice
if (basePrice > 1000) {
return basePrice * 0.95
} else {
return basePrice * 0.98
}
// After
const basePrice = () => _quantity * _itemPrice
if (basePrice() > 1000) {
return basePrice() * 0.95
} else {
return basePrice() * 0.98
}
직관적 임시변수 사용(Introduce Explaining Variable)
사용된 수식이 복잡할 때
// Before
if (
platform.toUpperCase().indexOf('MAC') > -1 &&
browser.toUpperCase().indexOf("IE") > -1 &&
wasInitialized() && resize > 0 ) {
// 기능 코드
}
// After
const isMacOs = platform.toUpperCase().indexOf('MAC') > -1
const isIEBrowser = browser.toUpperCase().indexOf("IE") > -1
const wasResized = resize > 0
if ( isMacOs && isIEBrowser && wasInitialized() && wasResized ) {
// 기능 코드
}
임시변수 분리(Split Temporary Variable)
루프 변수나 값 누적용 임시변수가 아닌 임시변수에 여러 번 값이 대입될
// Before
let temp = 2 * (_height + _width)
console.log(temp)
temp = _height * _width
console.log(temp)
// After
const perimeter = 2 * (_height + _width)
console.log(perimeter)
const area = _height * _width
console.log(area)
매개변수로의 값 대입 제거(Remove Assignments to Parameters)
매개변수로 값을 대입하는 코드가 있을 때
// Before
const discount = (inputVal, quantity, yearToDate) => {
if (inputVal > 50) {
inputVal -= 2
}
}
// After
const discount = (inputVal, quantity, yearToDate) => {
let result = inputVal
if (inputVal > 50) {
result -= 2
}
}
메서드를 메서드 객체로 전환(Replace Method with Method Object)
지역변수 때문에 메서드 추출을 적용할 수 없는 긴 메서드가 있을 때
그 메서드 자체를 객체로 전환해서 모든 지역변수를 객체의 필드로 만들자. 그런 다음 그 메서드를 객체 안의 여러 메서드로 쪼개면 된다.
// Before
class Account {
gamma (inputVal, quantity, yearToDate) {
const val1 = (inputVal * quantity) + delta()
let val2 = (inputVal * yearToDate) + 100
if ( (yearToDate - val1) > 100) {
val2 -= 20
}
const val3 = val2 * 7
return val3 - 2 * val1
}
}
// After
class Gamma {
constructor (source, inputVal, quantity, yearToDate) {
this.source = source
this.inputVal = inputVal
this.quantity = quantity
this.yearToDate = yearToDate
}
compute () {
const val1 = (this.inputVal * this.quantity) + this.source.delta()
let val2 = (this.inputVal * this.yearToDate) + 100
if ( (this.yearToDate - val1) > 100) {
val2 -= 20
}
const val3 = val2 * 7
return val3 - 2 * val1
}
}
class Account {
gamma (inputVal, quantity, yearToDate) {
return new Gamma(this, inputVal, quantity, yearToDate).compute()
}
}
알고리즘 전환(Substitute Algorithm)
알고리즘을 더 분명한 것으로 교체해야 할 때
// Before
const foundPerson = (people) => {
for (let i = 0; i < people.length; i++) {
if (people[i] === 'Don') {
return 'Don'
}
if (people[i] === 'John') {
return 'John'
}
if (people[i] === 'Kent') {
return 'Kent'
}
}
return ''
}
// After
const foundPerson = (people) => {
const candidates = ['Don', 'John', 'Kent']
for (let i = 0; i < people.length; i++) {
if (candidates.contains(people[i])) {
return people[i]
}
}
return ''
}