TIL
[클라우딩 어플리케이션 엔지니어링 TIL] - 7주차 리팩토링
blackmilktea
2024. 5. 28. 01:12
리팩토링(Refactoring)
리팩토링은 주로 가독성을 높이고 유지보수를 편하게 하기 위해서 코드의 구조를 재조정하는 것을 뜻한다. 리팩토링을 통해 코드의 기반 구조를 단단하게 하고 코드의 이해도를 높일 수 있다면 소프트웨어가 어떻게 설계 되었는지 빠르게 파악할 수 있고 수정이 보다 간단해지며 버그가 발생했을 경우 찾기 쉬워진다.
즉. 리팩토링은 소프트웨어의 설계, 구조 및 구현을 개선하기 위한 고민이라고 할 수 있다.
퍼즐 게임 리팩토링
1. 조건문 단순화
조건문을 보다 명확하게 구성
// 이전에 선택한 이미지가 없다면
if (!previouslySelecetedElement) {...}
// 선택한 이미지가 있다면
else {
// 이전에 선택한 이미지와 현재 선택한 이미지가 같을 경우
if (previouslySelecetedElement === currentElement) {...}
// 이전에 선택한 이미지와 다를 경우
else {...}
}
↓
// 이전에 선택한 이미지가 없다면
if (!previouslySelecetedElement) {...}
// 전에 선택한 이미지와 현재 선택한 이미지가 같을 경우
else if (previouslySelecetedElement === currentElement) {...}
// 전에 선택한 이미지와 다를 경우
else {...}
2) 데이터 관리
전역오염 방지를 위해 하나의 객체 안에 넣어서 관리
// gameData.js
let gameData = {
imageIndexesArray: [],
imageSet: 1,
previouslySelecetedElement: null,
changeOriginalImageSet: function() {
this.imageSet = Math.floor(Math.random() * 3) + 1
const originalImage = document.getElementById('originalImage')
originalImage.setAttribute('src', `./data/image${this.imageSet}/originalImage.png`)
},
generateImageIndexes: function() {
const uniqueNumber = new Set()
while (uniqueNumber.size < 9) {uniqueNumber.add(Math.ceil(Math.random() * 9))}
this.imageIndexesArray = [...uniqueNumber]
},
updatePreviouslySelectedElement: function(newElement) {
this.previouslySelecetedElement = newElement
}
}
export default gameData
3) 함수화 및 파일 모듈화
함수화를 통해 중복된 코드를 최대한 제거하고
코드를 독립적인 모듈로 사용할 수 있는 파일 구조로 분리해서 복잡도를 낮춤.
// script.js
import { handleClick } from "./src/eventHandlers.js"
import gameData from "./src/gameData.js"
import { createImageContainer, loadPuzzleImages } from "./src/utils.js"
const startButton = document.querySelector('button')
const puzzleContainer = document.querySelector('.container')
const changeImageButton = document.querySelector('#changeImage')
startButton.addEventListener('click', function () {
const gameScreen = document.querySelector('.game-screen')
gameScreen.classList.remove('hide')
const startScreen = document.querySelector('.start-screen')
startScreen.classList.add('hide')
gameData.changeOriginalImageSet()
gameData.generateImageIndexes()
for (let i = 0; i < 9; i++) {
const div = createImageContainer(gameData.imageSet, gameData.imageIndexesArray[i])
div.addEventListener('click', handleClick)
puzzleContainer.appendChild(div)
}
})
changeImageButton.addEventListener('click', function () {
gameData.changeOriginalImageSet()
loadPuzzleImages(gameData.imageSet, gameData.imageIndexesArray)
})