개발놀이터

코딩 스탠다드 4 : 강타입 언어라면 강타입 언어의 장점을 적극 활용하자 (String 을 지양해야 하는 이유) 본문

리팩토링/코딩 스탠다드

코딩 스탠다드 4 : 강타입 언어라면 강타입 언어의 장점을 적극 활용하자 (String 을 지양해야 하는 이유)

마늘냄새폴폴 2024. 4. 30. 21:55

이번엔 방법론에 대해서 포스팅해볼 생각입니다. 

 

프로그래밍 언어는 크게 두가지로 나눌 수 있습니다. 바로 강타입 언어와 약타입 언어. 흔히 알려지기론 로우레벨, 하이레벨로 나누는 것과 일맥상통합니다. 

 

강타입 언어는 타입이 딱딱 정해져있는 언어입니다. 자바나 C계열을 사용하신다면 int, String, long, boolean 이런 타입들이 익숙하실겁니다. 이렇게 딱딱 정해져있는 것이 바로 강타입 언어입니다. 강타입 언어에는 C, C++, C#, Java 정도가 있습니다. 물론 더 있지만 제가 아는 선에선 이거밖에...

 

약타입 언어는 타입이 런타임에 정해지는 언어입니다. 자바스크립트나 파이썬을 사용하신다면  익숙한 var 같은 타입이 바로 약타입입니다. 약타입 언어에는 자바스크립트, 파이썬, 코틀린 등이 있죠. 

 

 

이번 포스팅에선 메서드로 변수를 넘길 때 강타입을 활용하는 방법이고 이어지는 다음 포스팅에선 HTTP Request를 받을 때 강타입을 활용하는 방법입니다. 

 

자바는 강타입?

자바 몇인지 기억은 안나는데 자바도 약타입을 지원합니다. 하지만 전 강타입 언어는 강타입 언어만의 장점이 있어 약타입을 굳이 사용해야하나싶은 생각이 들긴 합니다. 

 

 

이제 본격적으로 시작하기에 앞서 늘 하듯이 상황을 먼저 가정하고 들어가겠습니다. 

 

상황)

사업을 관리해야하는데 기획자가 사업은 코드로 관리하자고하네요. 우리는 3개의 분과별로 사업 코드를 다르게 가져가야하고 각 분과가 구별되게끔 코드를 만드는 것이 목표입니다. 

 

우리는 아래와 같은 흐름도로 진행할겁니다. 

 

  1. 먼저 분과를 받습니다. 
  2. 분과에 맞는 코드를 생성합니다. 

 

굉장히 간단하죠? 이번 예제는 이전과 다르게 코드의 복잡성을 줄인다기보다도 설계하는 과정을 보여드려야해서 일부러 쉬운 예제로 가져왔습니다. 

 

    public String createCode(String group) {
        return makeCodeByGroup(group);	// 이부분! 주목해주세요. 
    }

    private String makeCodeByGroup(String group) {
        String year = LocalDateTime.now().getYear().toString();

        return year + "-" + group + "-" + UUID.randomUUID().toString();
    }

 

 

메서드로 group이라는 변수를 던지는 부분을 집중해주세요. 

 

저 부분에 문제는 세가지입니다. 

 

  1. group이 뭐지?
  2. group에 뭐가 들어오는지 체크해야되나?
  3. 최종적으로 어떤 코드가 만들어질까?

 

여러분은 이 코드가 굉장히 복잡하고 로직이 복잡하게 꼬여있는 상황을 생각하셔야합니다. 이런 상황에서 그냥 넘어간다면 문제가 생길 수도 있습니다. 

 

그리고 내가 이 코드를 처음 본다고 생각하면 저 두가지 문제에 대해 진지하게 고민하게됩니다. 

 

리팩토링

우선 첫번째부터, group이 뭔지 어떻게 알려줄 수 있을까요? 자바에는 강력한 타입이 있습니다. 바로 enum 클래스죠. 

 

@ToString
public enum Group {
    
    NORMAL("일반"), MEDICAL("의료"), AI("AI");

    Group(String description) {
        
    }
}

 

 

그리고 리턴해줄 DTO를 만들어줍니다. 

 

@Data
public class CreateCodeByGroupDto {

    private String year;

    private Group group;

    private String uuid;

    public CreateCodeByGroupDto(String year, Group group, String uuid) {
        this.year = year;
        this.group = group;
        this.uuid = uuid;
    }

    public String makeCode() {
        return this.year + "-" + this.group.toString() + "-" + this.uuid;
    }
}

 

 

그리고 다시 코드로 가보죠. 

 

    public String createCode(Group group) {
        return makeCodeByGroup(group);	// 이부분! 주목해주세요. 
    }

    private String makeCodeByGroup(Group group) {
        String year = LocalDateTime.now().getYear().toString();
        String uuid = UUID.randomUUID().toString();
        
        CreateCodeByGroup code = new CreateCodeByGroup(year, group, uuid);

        return code.makeCode();
    }

 

이렇게 만들면 어떤가요? 클래스를 두개나 만드는 수고가 있지만 확실히 두가지 문제를 모두 해결했습니다. 

 

이제 group에 뭐가 들어오는지 궁금하면 Group 클래스에 들어가보겠죠. 그리고 우리가 친절하게 설명까지 써놓은 세가지 분과를 볼겁니다. 그리고 makeCode() 로직도 궁금하면 들어가보겠죠. 

 

이렇게 1번 group에 뭐가 들어오는지 알게되었고, 2번 group에 뭐가 들어오는지 체크할 필요도 없죠. 

 

근데 왜 굳이 이렇게 해야할까요? 조금 번거롭긴하죠? 

 

왜냐하면 String 타입은 사실 엄청나게 자유분방한 녀석이라 이걸 하나하나 명시하고 체크해주려면 여간 골치아픈게 아니기 때문입니다. 

 

단순히 혼자 만드는 사이드 프로젝트에선 String으로 받아도 상관없겠지만 여럿이서 같이 협업하는 상황이라면 코드가 직관적이어야하고, 클라이언트쪽에서 어떤 정신나간 데이터가 넘어올지 모르기 때문에 String을 지양해야합니다. 

 

 

마치며

자바는, 특히 스프링은, 정말 오밀조밀하게 잘 짜여진 프레임워크이긴하지만 그 포맷을 일일히 따라가다보면 사실 1만큼 만들어도 되는데 10만큼 만들어야하는 상황이 오더군요... 

 

하지만 10만큼 다 했을 때 애플리케이션이 점점 더 단단해지는 것을 느끼실 수 있을겁니다. 

 

다음 포스팅에선 코딩 스탠다드 4와 이어지는 HTTP Request 를 강타입을 활용해 안정성을 높여보겠습니다.