Refactoring (리펙토링)
[Refactoring] 1-1. 리펙토링이란?, 리펙토링의 예시
jake-kim
2021. 12. 31. 01:52
리펙토링이랑?
- 겉으로 드러나는 코드의 기능은 바꾸지 않으면서 내부 구조를 개선하는 방식
- 코드를 작성하고 난 뒤에 설계를 개선하는 일
- 보통 소프트웨어 개발 시 설계 후 코드를 작성하지만, 시간이 흐르면서 설계에 맞춘 구조는 점차 뒤죽박죽이 되어가므로 리펙토링이 필요
- 리펙토링이란 기존 흐름과 반대의 작업: 엉망이 되어가는 코드 또는 엉망인 설계를 가져다가 체계적으로 설계된 코드로 탈바꿈이 가능
- 처음부터 완벽한 설계를 갖추기보다 개발을 진행하면서 지속적으로 설계하는 일이며 시스템을 구축하는 과정에서 더 나은 설계가 무엇인지 배우는 것(= 우수한 설계를 유지하게 되는 효과)
리펙토링 예시
- 연극의 장르, 관객수 데이터를 받아서 계산하여 영수증을 출력하는 프로그램
- 데이터 모델
- Customer: 연극 의뢰자
- Content: 연극 정보
struct Customer { let name: String let requestPerformance: [Content] } struct Content { enum Name { case hamlet case othello var genre: String { switch self { case .hamlet: return "comedy" case .othello: return "tragedy" } } } let playId: Name let audienceCount: Int }
- Mock 데이터
- jake라는 사람이 연극을 해달라고 요청하는 상황이고, 연극 내용은 requestPerformance에 등재
func getMock() -> Customer { Customer( name: "jake", requestPerformance: [ Content( playId: Content.Name.hamlet, audienceCount: 55 ), Content( playId: Content.Name.othello, audienceCount: 32 ), Content( playId: Content.Name.othello, audienceCount: 72 ), ] ) }
- jake라는 사람이 연극을 해달라고 요청하는 상황이고, 연극 내용은 requestPerformance에 등재
- 연극 정보를 받아서 영수증 출력하는 메소드 구현
func getInvoiceInfo(customer: Customer) -> String { var totalAmount = 0 // 토탈 비용 var volumnCredits = 0 // 포인트 적립 var result = "청구 내역 (고객명: \(customer.name))\n" for performance in customer.requestPerformance { var thisAmount = 0 switch performance.playId.genre { case "comedy": // 희극 thisAmount = 40000 if performance.audienceCount > 30 { thisAmount += 1000 * (performance.audienceCount - 30) } case "tragedy": // 비극 thisAmount = 30000 if performance.audienceCount > 20 { thisAmount += 10000 + 500 * (performance.audienceCount - 30) } default: fatalError() } // 포인트 적립 volumnCredits += max(performance.audienceCount - 30, 0) // 희극 관란객 5명마다 추가 포인트 제공 if performance.playId.genre == "comedy" { volumnCredits += performance.audienceCount / 5 } // 청구 내역 출력 result += " \(performance.playId): \(thisAmount)원 \(performance.audienceCount)좌석\n" totalAmount += thisAmount } result += "총액: \(totalAmount)원\n" result += "적립 포인트: \(volumnCredits)점\n\n" return result } - 사용
let jake = getMock() let invoice = getInvoiceInfo(customer: jake) print(invoice)
-> 만약 100줄이 넘는 큰 메소드였다면 어떻게 접근할지?
-> 기능을 새로 추가해야 한다면 어떻게 접근할지?
-> 급하게 기능만 추가하지 말고, 여러 함수로 쪼개고 프로그램 요소를 재구성하는 등의 구조를 먼저 변경한 후 기능 추가할 것
[Refactoring] 1-2. 리펙토링이란?, 리펙토링의 예시에서 계속
* 참고
- Refactoring (Martin Flowler)