티스토리 뷰

experiences/refactoring

3. 적용 사례

lingi04 2021. 12. 22. 22:37

800줄 짜리 메서드가 있었다. 그래서 앞선 글에서 적은 내용들을 적용하기 딱 좋은 케이스라고 생각했다. 깨끗한 코드를 짜기 위한 연습이라 생각하며 리팩토링을 해보았다.

사전 설명

코드를 공개할 수가 없어서 말로 설명을 최대한 이해하기 쉽게 해봐야겠다.

회사에서 사용하는 개념인데 GroupA, ItemB, ItemC가 있고 GroupA는 ItemB, ItemC를 포함한다. 각 GroupAService, ItemBService, ItemCService엔 GroupA, ItemB, ItemC에 관한 동작들이 구현되어 있다.

deployGroupA라는 메서드가 있다. 이 메서드에는 세부 기능 a, itemB, itemC, e를 위한 로직이 있었고 이 로직들은 if문과 for문 그리고 이유를 설명해주는 주석들이 잘 버무러져 있었다. 또한 itemBitemC는 ItemBService, ItemCService엔 deployBdeployC를 위한 로직과 비슷하다.

코드를 간단하게 설명하면 아래와 같다.

package com.example.a;

public class GroupAService{
    ...
    public void deoloyGroupA(){
        // deploy a
        ...

        // deploy item B
        ...

        // deploy item C
        ...

        // deploy e
        ...
    }
    ...
}
package com.example.b;

public class ItemBService{
    ...
    public void deoloyItemB(){
        // deoloy item B
        ...
    }
    ...
}
package com.example.c;

public class ItemCService{
    ...
    public void deoloyItemC(){
        // deoloy item C
        ...
    }
    ...
}

이 코드들 중 deoloyGroupA메서드를 리펙토링 해보기로 했다.

리팩토링 원칙

앞선 글에서 처럼

  1. 한 메서드는 인덴트를 하나만
  2. else 예약어 사용을 자제하자
  3. 한 가지 메소드는 한 가지 일만
  4. 지역변수를 없애보자

네 가지를 원칙을 지켜 읽기 쉽고 재사용 가능한 코드를 만드는 것이 목표 이다.

적용 방식

일단 세부 기능별로 나눈 후 작은 메서드로 분리하는 작업을 반복해서 했다. 하지만 너무 세분화해서 코드의 깊이가 깊어지면 오히려 이해하기가 어려울 것 같아 너무 세분화 하진 않았다.
정리하면 아래와 같다.

원칙 적용방식
1. 한 메서드는 인덴트를 하나만 if/for 가 중첩되는 경우 메서드를 분리하였다.
2. else 예약어 사용을 자제하자 메서드를 분리하니 조건에 안맞는 경우는 미리 return 할 수 있어서 어느 정도 해결 되었다. 또한 코드를 읽어보고 없앨 수 있는건 없애도록 노력했다.
3. 한 가지 메소드는 한 가지 일만 최대한 지키려 노력했으나 코드의 깊이가 너무 깊어지지 않도록 적당한 선 까지만 메서드를 분리 했다.
4. 지역변수를 없애보자 null이 return 될 수 있는 경우를 제외하고 코드를 읽는데 큰 무리가 없을 정도 선에서 지역변수를 제거하였다. 특히 한번만 쓰이는 지역변수는 거의 다 없앴다.

결과

우선 (전체 코드는 늘어났지만) 한개의 길이가 800라인이던 메서드를 19개의 메서드로 분리를 했다. 길었던 메서드는 분리되어 메서드 안에 세부 메서드가 나열되어 있는 형태로 완성되었다. 메서드명도 최대한 의미있는 이름으로 만드려 노력했다. 덕분에 주석도 어느 정도 줄일 수 있었다. 하지만 몇가지 이유 때문에 배포 소스에 적용할 순 없었다.

아쉬운점

  1. 코드 재사용 부분에서 기대했던 것 만큼 효과를 보기 어려웠다.
    • 특히 deoloyGroupA 메서드의 deoloy item Bdeoloy item C 로직은 ItemBService, ItemCService 클래스의 deoloyItemBdeoloyItemC 메서드와 로직이 거의 유사했기 때문에 재사용할 수 있을 것이라 생각했는데 막상 보니 재사용 하기 어려웠다.
  2. 리팩토링한 코드를 신뢰할 수가 없었다.
    • 테스트 코드가 있는건 아니지만 기존 코드는 qa에서 검증도 많이 했고 서비스를 하며 많이 검증된 상태였다.
    • 하지만 리팩토링한 코드는 직접 테스트를 해보며 어느정도 검증을 했지만 배포 소스에 적용할 순 없었다.
    • 여기서 단위테스트의 중요성에 대해 느낄 수 있었다.

잘 된점??

그래도 잘된점을 꼽아보자면 일단 주관적 판단일지도 모르나 코드 읽기가 조금 더 수월해 졌다.

결국 이번 시도는...

결국 이번 시도는 몇가지 장점을 느끼긴 했지만 부족한 점 역시 느끼며 연습해 보는 것으로 끝났다.

'experiences > refactoring' 카테고리의 다른 글

4. 적용 사례2  (0) 2021.12.22
2. 목표 설명  (0) 2021.12.22
1. intro  (0) 2021.12.22
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday