당신을 데리고 전방 공사(10): 재구성
9079 단어 javascript 전단
이른바 재구성(refactoring)은 이러한 과정이다. 코드의 외적 행위를 바꾸지 않는 전제에서 코드를 수정하여 프로그램의 내부 구조를 개선한다.재구성은 여러 가지 단련을 거쳐 형성된 질서정연한 절차 정리 방법으로 정리 과정에서 오류가 도입될 확률을 최대한 줄일 수 있다.본질적으로 재구성은 코드를 다 쓴 후에 디자인을 개선하는 것이다.
재구성과 성능 최적화는 공통점도 있고 차이점도 있다.
같은 점은 프로그램 기능을 바꾸지 않고 코드를 수정하는 것이다.다른 점은 재구성은 코드를 더욱 쉽게 이해하고 수정하기 위한 것이고 성능 최적화는 프로그램을 더욱 빨리 실행하기 위한 것이다.여기서 한 가지 더 중점적으로 말하자면, 측면의 중점이 다르기 때문에 재구성은 프로그램을 더욱 빨리 실행할 수도 있고, 프로그램을 더욱 느리게 실행할 수도 있다.
재구성은 코드를 쓰면서 재구성할 수도 있고, 프로그램을 다 쓴 후에 일정 시간 동안 전문적으로 재구성할 수도 있다.어떤 방식이 더 좋은지는 말하지 않고 개인의 상황을 보고 결정한다.만약 당신이 전문적으로 시간을 가지고 재구성을 한다면, 코드를 재구성한 후 즉시 테스트를 진행하는 것을 권장합니다.이렇게 하면 코드를 너무 많이 수정해서 오류가 발생할 때 오류점을 찾을 수 없다는 것을 피할 수 있다.
재구성의 원칙
재구성법
《재구성2》 이 책에는 수백 가지에 달하는 재구성 기법이 소개되어 있다.그러나 나는 다음과 같은 8가지가 비교적 자주 사용된다고 생각한다.
검색 데이터의 인터페이스가 있다고 가정하십시오.
/getUserData?age=17&city=beijing
현재 필요한 것은 사용자 데이터: { age: 17, city: 'beijing' }
를 URL 매개 변수로 바꾸는 것입니다.let result = ''
const keys = Object.keys(data) // { age: 17, city: 'beijing' }
keys.forEach(key => {
result += '&' + key + '=' + data[key]
})
result.substr(1) // age=17&city=beijing
만약 이 인터페이스만 변환이 필요하다면 함수로 봉하지 않는 것은 문제없다.그러나 여러 인터페이스에 이런 수요가 있다면 그것을 함수로 봉해야 한다.
function JSON2Params(data) {
let result = ''
const keys = Object.keys(data)
keys.forEach(key => {
result += '&' + key + '=' + data[key]
})
return result.substr(1)
}
너무 많은 함수 분할
다음은 청구서를 인쇄하는 프로그램입니다.
function printBill(data = []) {
//
const total = {}
data.forEach(item => {
if (total[item.department] === undefined) {
total[item.department] = 0
}
total[item.department] += item.value
})
//
const keys = Object.keys(total)
keys.forEach(key => {
console.log(`${key} :${total[key]}`)
})
}
printBill([
{
department: ' ',
value: 89,
},
{
department: ' ',
value: 132,
},
{
department: ' ',
value: 78,
},
{
department: ' ',
value: 90,
},
{
department: ' ',
value: 56,
},
{
department: ' ',
value: 120,
},
])
이
printBill()
함수는 실제적으로 두 가지 기능을 포함하는데 그것이 바로 집합과 인쇄이다.우리는 전체 데이터의 코드를 추출하여 하나의 함수로 봉인할 수 있다.이렇게 하면 printBill()
함수는 인쇄 기능에만 관심을 기울일 수 있다.function printBill(data = []) {
const total = calculateBillData(data)
const keys = Object.keys(total)
keys.forEach(key => {
console.log(`${key} :${total[key]}`)
})
}
function calculateBillData(data) {
const total = {}
data.forEach(item => {
if (total[item.department] === undefined) {
total[item.department] = 0
}
total[item.department] += item.value
})
return total
}
변수/함수 개명
변수 이름이든 함수 이름이든 간에 가능한 한 다른 사람이 당신의 변수/함수가 무엇을 하는지 알게 해야 합니다.변수 명칭의 규칙은'무엇인가'에 중점을 두고 함수 명칭의 규칙은'무엇을 하는가'에 중점을 두고 있다.
변량
const a = width * height
위의 이 변수는 그다지 좋지 않아서
a
그것이 무엇인지 알아보기 어렵다.const area = width * height
이렇게 바꾸면 이해하기 쉽다. 원래 이 변수는 면적을 표시하는 것이다.
함수.
function cache(data) {
const result = []
data.forEach(item => {
if (item.isCache) {
result.push(item)
}
})
return result
}
이 함수 명칭은 사람을 매우 의심하게 할 것이다.
cache
는 무엇을 대표하는가?캐시를 설정하시겠습니까, 제거하시겠습니까?코드를 다시 자세히 보니, 아, 캐시 데이터를 얻었구나.그래서 이 함수의 명칭을 getCache()
로 바꾸는 것이 더욱 적합하다.대체 알고리즘
function foundPersonData(person) {
if (person == 'Tom') {
return {
name: 'Tom',
age: 18,
id: 21,
}
}
if (person == 'Jim') {
return {
name: 'Jim',
age: 20,
id: 111,
}
}
if (person == 'Lin') {
return {
name: 'Lin',
age: 19,
id: 10,
}
}
return null
}
위의 이 함수의 기능은 사용자 이름에 따라 사용자의 상세한 정보를 찾는 것이다. 이 함수는 세 번
if
판단을 했고 데이터를 찾지 못하면 되돌아온다null
.이 함수는 확장에 불리합니다. 사용자마다 if
문장을 많이 써야 합니다. 우리는 더욱 편리한 '찾기표' 로 바꿀 수 있습니다.function foundPersonData(person) {
const data = {
'Tom': {
name: 'Tom',
age: 18,
id: 21,
},
'Jim': {
name: 'Jim',
age: 20,
id: 111,
},
'Lin': {
name: 'Lin',
age: 19,
id: 10,
},
}
return data[person] || null
}
수정 후 코드 구조가 더욱 뚜렷해 보이고 미래에 확장하기에도 편리하다.
함수 호출로 내연 코드를 대체하다
만약 일부 코드가 한 일이 기존 함수의 기능과 중복된다면, 이 코드들을 함수 호출로 대체하는 것이 가장 좋다.
let hasApple = false
for (const fruit of fruits) {
if (fruit == 'apple') {
hasApple = true
break
}
}
예를 들어 위의 코드는 배열
includes()
방법으로 대체할 수 있습니다.const hasApple = fruits.includes('apple')
수정 후 코드가 더욱 간결하다.
이동 문
관련된 것이 함께 나타나게 하면 코드를 더욱 쉽게 이해할 수 있다.만약 일부 코드가 한 곳에 작용한다면, 다른 코드 사이에 섞이지 않고 그것들을 함께 놓는 것이 가장 좋다.가장 간단한 경우 이동 문구만 사용하면 모일 수 있다.다음 예와 같습니다.
const name = getName()
const age = getAge()
let revenue
const address = getAddress()
// ...
const name = getName()
const age = getAge()
const address = getAddress()
let revenue
// ...
두 데이터 영역의 기능이 다르기 때문에 이동 문장을 제외하고 나는 그것들 사이에 한 줄을 비워서 사람들로 하여금 그것들 사이의 차이를 더욱 쉽게 구분하게 한다.
내포 조건 표현식
여러 조건 표현식이 중첩되면 코드를 읽기 어려워집니다.
function getPayAmount() {
if (isDead) {
return deadAmount()
} else {
if (isSeparated) {
return separatedAmount()
} else if (isRetired) {
return retireAmount()
} else {
return normalAmount()
}
}
}
function getPayAmount() {
if (isDead) return deadAmount()
if (isSeparated) return separatedAmount()
if (isRetired) return retireAmount()
return normalAmount()
}
조건 표현식을 분리한 후 코드의 읽기성이 크게 강화되었다.
조회 함수와 수정 함수를 분리하다
일반적인 조회 함수는 모두 값을 얻는 데 쓰인다. 예를 들어
getUserData()
,getAget()
,getName()
등이다.때때로, 우리는 편의를 위해 검색 함수에 다른 기능을 추가할 수도 있다.예를 들어 다음 함수는 다음과 같습니다.function getValue() {
let result = 0
this.data.forEach(val => result += val)
//
sendBill()
return result
}
절대 이렇게 하지 마세요. 함수의 중요한 기능은 직책 분리입니다.그래서 우리는 그것들을 분리해야 한다.
function getValue() {
let result = 0
this.data.forEach(val => result += val)
return result
}
function sendBill() {
// ...
}
이런 함수의 기능은 매우 뚜렷하다.
소결
옛사람이 말하기를 책을 다 믿는 것보다 책이 없는 것이 낫다고 했다.《재구성2》도 예외가 아니다. 이 책을 볼 때 반드시 비판적인 시선을 가지고 읽어야 한다.
안에 소개된 재구성 기법은 수백 가지에 달하지만 모두 적용되는 것은 아니다.그래서 반드시 취사가 있어야 한다. 안에 있는 유용한 수법을 베껴서 수시로 몇 번 보아야 한다.이렇게 하면 코드를 쓸 때 재구성이 호흡처럼 자연스러워져서 사용해도 모른다.
참고 자료
너를 데리고 전방 공사에 들어가겠다 전체 텍스트 카탈로그:
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
JavaScript 베이스(7)콜 () 과 apply () 를 호출하면 대상을 첫 번째 인자로 지정할 수 있습니다. Math.floor () 는 한 수를 아래로 가져올 수 있습니다. Math.round () 는 한 수를 반올림하여 정돈할 수 있다...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.