본문 바로가기

개발/리팩토링

[리팩토링 2판 파이썬 코드로 변경해보기] 1탄 기본 코드 세팅

반응형
리팩토링 2판의 제일 처음 나오는 예제를 파이썬 코드로 변경 하면서, 책의 내용에 따라 리팩토링 해보고 저자의 의견과 내 의견을 정리

 

책에 나오는 코드들을 파이썬으로 바꾸면 아래와 같다.

# plays.json

{
  "hamlet": {"name": "Hamlet", "type": "tragedy"},
  "as-like": {"name":  "As You Like It", "type":  "comedy"},
  "othello": {"name":  "Othello", "type":  "tragedy"}
}
#invoices.json

[
  {
    "customer": "BigCo",
    "performances": [
      {
        "playID": "hamlet",
        "audience": 55
      },
      {
        "playID": "as-like",
        "audience": 35
      },
      {
        "playID": "othello",
        "audience": 40
      }
    ]
  }
]

 

# main.py

import json
import math


def statement(invoice, plays):
    total_amount = 0
    volume_credits = 0
    result = f"청구 내역 (고객명: {invoice['customer']})\n"
    dollar_format = '${:,.2f}'

    for perf in invoice["performances"]:
        play = plays[perf["playID"]]
        this_amount = 0

        if play["type"] == "tragedy":
            this_amount = 40000
            if perf["audience"] > 30:
                this_amount += 1000 * (perf["audience"] - 30)
        elif play["type"] == "comedy":
            this_amount = 30000
            if perf["audience"] > 20:
                this_amount += 10000 + 500 * (perf["audience"] - 20)
            this_amount += 300 * perf["audience"]
        else:
            raise Exception("알 수 없는 장르")

        volume_credits += max(perf["audience"] - 30, 0)

        if play["type"] == "comedy":
            volume_credits += math.floor(perf["audience"] / 5)

        result += f' {play["name"]}: {dollar_format.format(this_amount / 100)} ({perf["audience"]}석)\n'
        total_amount += this_amount

    result += f"총액: {dollar_format.format(total_amount / 100)}\n"
    result += f"적립 포인트': {volume_credits}점\n"
    return result


if __name__ == '__main__':
    with open('invoices.json') as json_file:
        invoice = json.load(json_file)[0]

    with open('plays.json') as json_file:
        plays = json.load(json_file)

    print(statement(invoice, plays))


# 결과 값

청구 내역 (고객명: BigCo)
 Hamlet: $650.00 (55석)
 As You Like It: $580.00 (35석)
 Othello: $500.00 (40석)
총액: $1,730.00
적립 포인트': 47점

내가 최초로 작성된 위 코드를 봤을 때의 느낌은 전혀 한눈에 들어오지 않는다 였다. 함수 내에서 쓸데 없이 사용되는 변수, 의미가 모호한 이름들, 매직넘버, 함수가 맡은 역할이 많음 등등 수정할 곳이 굉장히 많아보였다. 

책에서는 위 코드에 대한 문제점을 아래와 같이 제시한다.

  1. 청구 내역을 HTML로 출력하는 기능이 필요할 때, 코드 수정이 복잡해 진다.
  2. 연극 장르와 공연료 정책이 달라질 때마다 statement() 함수를 수정해야한다.

위는 앞으로 위 코드가 확장성 있게 활용되어야 할 때, 생길 수 있는 문제들에 대해서 지적한다. 

또한 위 테스트는 현재 테스트 또한 만들어지지 않았기 때문에, 리팩토링을 했을 때 테스트로 빠르게 피드백 받기도 힘들 것으로 예상된다.

아무튼, 위 코드에 대해서 책의 내용과 그대로 리팩토링 해본 이후에, 나의 의견이 가미된 버젼으로도 따로 리팩토링 및 테스트 까지 추가해볼 예정이다.

반응형