가장 많이 쓰는 리팩토링 패턴 중에 변수, 함수, 메서드 추출 vs 인라인이 있다.


코드에서 따로 변수, 함수를 뽑아내는 게 추출이고

반대로 코드 안에 다시 넣어버리는 게 인라인in line 이다.


추출은 보통 중복을 제거하기 위해서 많이 쓰인다. 복사 붙여넣기를 남발하면 중복이 많아지는데, 대부분 변수나 함수를 추출해서 해결할 수 있다.


다음 거지 같은 코드를 보자. 내가 과외하는 학생이 친구가 짜줬다면서 들고 온 코드다.


a = "<시간표>19:39"

if int(a.split(">")[1].split(":")[0]) >= 0 and int(a.split(">")[1].split(":")[0]) <= int(24 and a.split(">")[1].split(":")[1] >= 0 and int(a.split(">")[1].split(":")[1]):

    database_save(a.split(">")[1])


노베이스를 위해 설명하자면 split은 문자열을 쪼개주는 함수다.


["<시간표", "19:39"]로 쪼갠 다음에 [1] 즉 2번째 항목을 가져와서 다시 쪼갠다. ["19", "39"]로 쪼개지겠지? 


이건 문자열이니까 int를 써서 숫자로 바꿔준다. 그러면 시간hour은 0부터 24 사이의 값이어야하고, minute은 0과 60사이의 값이어야 하니까 유효성 검사를 해주는 거다.



다시 코드를 보자. 사실 알아먹기가 힘들지? 가독성이 떨어진다. 다른 팀원이 이 코드를 읽기 어려워지니까 협업에 문제가 생긴다.


이걸 실제로 돌리면 에러가 난다. 내가 괄호 하나를 일부러 빼놨거든. 이 코드만 보고 어디서 괄호를 빼먹었는지 찾기 쉬울까? 디버깅도 어렵다. 


게다가 만약에 문자열 양식이 조금이라도 바뀐다면? 예를 들어 이 코드에 "<시간표>19:39(mon)"처럼 요일을 추가하고 싶다고 하자. 그러면 ctrl+f로 모두 찾아서 바꾸기를 쓰더라도 코드 수정하기가 귀찮아지겠지. 그러다 실수로 다른 코드가 날아갈 수도 있고. 유지보수가 어렵다.


그러면 어떻게 해야할까? 중복되는 값을 변수로 추출해주면 된다.

a = "<시간표>19:39"

hour = int(a.split(">")[1].split(":")[0])


if hour >= 0 and hour <= 24 and int(a.split(">")[1].split(":")[1] >= 0 and int(a.split(">")[1].split(":")[1]):

    database_save(a.split(">")[1])


이러니까 훨씬 보기 좋아졌지? 한 눈에 시간이 0부터 24 사이인지 검사하는 코드라는 걸 알 수 있잖아.




물론 아직 고칠 게 많다. 이제 과제 준다. minute 을 추출해보자. 그리고 hour:minute으로 되어 있는 시간 부분이 중복되니까 그 부분을 추출해보라고. 그러면 이만~