핀수로그
  • [아무튼 필사] 내 코드가 그렇게 이상한가요? 2일차
    2023년 12월 19일 23시 11분 33초에 업로드 된 글입니다.
    작성자: 핀수
    728x90
    반응형

    본문

    1.3 수많은 악마를 만들어 내는 데이터 클래스

    업무 계약을 다루는 서비스에서 계약 금액을 처리하는 요구 사항을 클래스로 구현해야 한다고 합시다. 아무 생각 없이 구현하면, 코드 1.5와 같은 클래스 구조가 만들어집니다.

    // 계약 금액
    public class ContractAmount {
        public int amountIncludingTax; // 세금 포함 금액
        public BigDecimal salesTaxRate; // 소비세율
    }

     

    세금이 포함된 금액과 소비세율을 public 인스턴스 변수로 갖고 있으므로, 클래스 밖에서도 데이터를 자유롭게 변경할 수 있는 구조입니다. 이처럼 데이터를 갖고 있기만 하는 클래스를 데이터 클래스라고 부릅니다.

    그런데 데이터 클래스에는 데이터 뿐만 아니라, 세금이 포함된 금액을 계산하는 로직도 필요한데, 이러한 계산 로직을 데이터 클래스가 아닌 다른 클래스에 구현하는 일이 벌어지곤 합니다. 설계를 따로 고려하지 않아 생기는 일입니다.

    ...

    작은 규모의 애플리케이션이라면 이러한 구조가 특별히 문제되지 않습니다. 하지만 애플리케이션의 규모가 커진다면, 수많은 악마를 불러들입니다.

    ...

    1.3.1 사양을 변경할 때 송곳니를 드러내는 악마

    업무 계약 서비스에서 소비세와 관련된 사양이 변경되었다고 합시다. 구현 담당자는 소비세율과 관련된 로직을 변경했습니다. 그런데 며칠이 지나 '소비세율이 변경되지 않았다.'라는 장애 보고가 올라왔습니다. 원인을 조사해 보니, 다른 곳에도 세금 포함 금액을 계산하는 로직이 있었던 것입니다. 마찬가지로 구현 담당자는 이곳의 로직도 수정했습니다.

    그런데 얼마 지나지 않아서, 또다시 '소비세율이 변경되지 않았다.'라는 장애 보고가 올라왔습니다.

    ...

    그리고 놀랍게도 세금 포함 금액을 계산하는 로직이 수십 곳에 있음을 확인했습니다.

    ...

    계산 로직을 어느 한곳에 만들어 두면, 사람들이 모두 그것만 사용하고 따로 구현하지는 않겠지 하고 생각할 수도 있습니다. 하지만 설계에 관심이 없다면, 필요한 로직이 이미 구현되어 있다는 사실을 모르고 따로 구현해 버릴 수도 있습니다.

    ...

    이처럼 데이터와 로직 등이 분산되어 있는 것을 응집도가 낮은 구조라고 합니다. 그럼 응집도가 낮아 생길 수 있는 여러 가지 문제를 살펴봅시다.

    ...

    1.3.5 초기화되지 않은 상태 (쓰레기 객체)

    ContractAmount amount = new ContractAmount();
    System.out.println(amount.salesTaxRate.toString());

     

    코드를 실행하면 NullPointerException이 발생합니다. 소비세율 salesTaxRate는 BigDecimal로 정의되어 있으므로, 따로 초기화하지 않으면 null이 들어갑니다. ContractAmount가 추가로 초기화해야 하는 클래스라는 것을 모르면, 버그가 발생하기 쉬운 불완전한 클래스입니다.

    이처럼 '초기화하지 않으면 쓸모 없는 클래스' 또는 '초기화하지 않은 상태가 발생할 수 있는 클래스'를 안티 패턴 쓰레기 객체라고 부릅니다.

     

    1.3.6 잘못된 값 할당

    값이 잘못되었다는 것은 요구 사항에 맞지 않음을 의미합니다. 

    ...

    현재 데이터 클래스는 코드 1.8처럼 소비세율을 음수로 대입해도 값이 들어갑니다. 따라서 잘못된 값이 쉽게 들어갈 수 있는 구조입니다.

    잘못된 값이 들어가지 않게, 데이터 클래스를 사용하는 쪽의 로직을 살짝 변경해서 유효성을 검사하게 만들 수 있습니다. 하지만 사용하는 곳마다 검사 로직을 추가해야 하니 마치 세금 포함 금액을 계산하는 로직처럼 여러 곳에 코드가 중복될 수 있습니다.

    ...

    데이터 클래스가 일으키는 폐해를 정리해 보면, 일단 다음과 같습니다.

    • 코드 중복
    • 수정 누락
    • 가독성 저하
    • 초기화되지 않은 상태(쓰레기 객체)
    • 잘못된 값 할당

    데이터 클래스라는 악마 한 마리가 수많은 악마를 불러들여, 버그를 발생시키고 가독성을 해치는 것입니다. 결과적으로 이와 같은 문제들은 개발 생산성을 떨어뜨립니다.

     

    참고 : 일부러 데이터 클래스로 설계하는 경우도 있습니다. 이는 앞서 언급한 데이터 클래스의 리스크를 충분히 해소할 수 있는 경우에 한정됩니다. 이 책에서는 DTO에서 데이터 클래스를 사용하는 예를 소개합니다.

     


     

    오늘 내용의 핵심은 응집도가 낮은 경우 발생하는 문제점이다.

    응집도는 정보처리기사 자격증을 공부할 때 만난 적이 있는데 이렇게 예시를 통해 만나게 되니 이해가 더욱 잘된다.

    이미 개발 되어 있는 것에 대한 수정을 진행해야 했을 때

    구현되어 있는 것을 모르고 따로 구현한 적이 (정말로) 있었다. 

    코드를 제대로 살펴보지 않은 내 불찰이겠지만, 설계가 잘 되어 있었다면 피해갈 수 있었을지도 모르는 일이다.

     

    공부를 할 때는 항상 좋은 것을 먼저 배워서, '왜 이렇게 해야하지?'하며 의문을 품곤하는데

    이 책은 사례와 함께 좋지 않은 것을 사용했을 때의 폐해를 알려주어서 납득이 잘 되고 그 중요성을 더 깨닫게 된다.

    내일은 어떤 것을 알게 될까?

    우리 존재 화이팅


    출처

     

    내 코드가 그렇게 이상한가요?

    공감 100% 나쁜 코드 사례로 배우는 지속 가능한 코드 설계 입문서. 객체 지향 설계를 통해 코드 품질을 높이는 방법을 설명한다. 설계를 고민하지 않고 작성한 코드는 오로지 한 치 앞만 바라본

    www.aladin.co.kr

     

    728x90
    반응형
    댓글