Replies: 1 comment
-
의견리비: 안 쓴다.
콜리: 안 쓰는데 쓸 의향이 있다.
에버: 안 쓴다.
제리: 원래 싫어하는 편에 속했는데 이번 미션에서 일부러 final과 var를 쓰는 형태로 코드 개발을 해보니 생각보다 나쁘지 않다. 그래서 괜찮은 것 같다.
var가 가독성을 해친다?리비: 메서드가 뭔가를 반환했는데 그게 var 타입으로 되어 있으면 한눈에 알기 힘들다. 그래서 타입 명시성이 감소하는 것 같은데 어떻게 생각하십니까? 제리: 코드를 읽는 시점에서는 이 코드가 어떤 일을 하는지에 주목하는데 이때 타입이 큰 영향을 미치지는 않는 것 같다. 또한, var 타입이 딱 지역 변수에만 사용할 수 있고 메서드 매개변수나 반환부에서는 쓸 수 없으니 그런 부분에서 명시가 되어 있어 크리티컬한 문제가 아닌 것 같다. 오히려 var로 타입이 감춰져 있으니 코드의 본 행위에 좀 더 집중해서 코드를 읽을 수 있다고 생각한다. 콜리: 그 객체가 받을 수 있는 메시지가 중요하지 그게 어떤 타입인가는 타입 추론으로 충분히 유추가 가능한 것 같다고 개인적으로는 생각한다. 리비: 근데 추가로 얘기하고 싶은 게 어떤 메서드가 반환하는 객체 그리고 그 객체의 API들을 쫙 찍어보면서 개발하는 입장에서는 그 클래스 타입이 굉장히 중요하다고 생각한다. 클래스가 반환하는 타입에 따라 이용할 수 있는 API 명세가 달라진다. 그랬을 때는 클래스가 명시적인 편이 앞으로 어떤 작업을 할 수 있을지에 대한 예측 가능성을 확보하는 게 아닐까 싶은 측면에서 여전히 var 타입을 좀 안 좋게 보긴 한다. 콜리: 타입 자체가 중요하다는 전제는 동의하는데 그게 과연 지역 변수에 중복적으로 선언해줄 필요가 있는가의 관점에서 좀 바라볼 필요가 있을 것 같다. 그 메서드를 사용한다는 거는 기본적으로 반환 타입이 무엇인지 이미 퍼블릭 인터페이스를 인식한 상태에서 코드를 짠다고 생각을 한다. 그렇기 때문에 var를 쓰는 이유는 타입에 대한 중요성을 간과한다는 측면보다 굳이 중복적인 정보를 또 한 번 더 담아야 하는가의 관점에서도 바라봐야 한다고 생각한다. 자바에서 제공하는 다형성이 var 타입을 사용함으로써 의미가 없어진다?에버: 그러면 자바에서 다형성을 제공하는데 그게 var 타입을 사용함으로써 의미가 없어진다고 생각되진 않나? 예로, 어떤 구체 클래스를 추상 클래스로 추상화할 때, 변수 타입에 그 추상 클래스를 명시함으로써 다형성이 제공된다고 생각한다. 근데 var 타입을 쓰면 안 되는 것 아닌가? 리비: 예시를 하나 던지자면 new HashMap에서 그걸 var로 받는 경우가 있을 것 같다. 콜리: 그런 측면에서 오히려 인터페이스에 의존하는 프로그래밍을 가능하게 한다고 생각을 했던 게, 프로그래밍의 이상적인 원칙 중 하나가 인스턴스는 구체 타입으로 하되 변수는 인터페이스로 받아주는 것이다. 그러니까 추상화된 것을 반환하되 그 반환형 자체는 구체 타입인 것. 그래서 오히려 var 타입 자체가 구체적인 구현 요소를 캡슐화하고 조금 더 유연한 안정성을 제공을 한다고 생각한다. 왜냐하면 어떤 변수가 있고 그 뒤에서 반환되는 어떤 값이 다른 구체 타입으로 바뀌더라도 사실 이 코드 내에서는 수정할 타입이 전혀 없어지게 된다. 그런 측면에서는 오히려 OCP 측면에서 var가 좀 더 중요한 역할을 할 수도 있겠다. 그리고 실제로 네오가 레벨 1에서 var 타입을 사용했을 때 리팩터링 내성이 강하다는 느낌을 많이 받기도 했다. 리비: 어쨌든 이 얘기를 통해서 내가 하고 싶은 말은 타입이 어떻게 추론될지를 컴파일러를 돌려봐야 알고 있다는 거잖아. var 타입을 쓰는 것 자체가 굉장히 컴파일러에 의존적이 되는 상황이라고 생각을 한다. 개발자가 충분히 제어할 수 있는 부분을 컴파일러한테까지 넘길 필요는 없다고 생각한다. 그거는 어떻게 생각하시나요? 제리: 컴파일러가 일을 하는데 그걸 왜 말려야 하는지 모르겠어. 왜냐하면 var를 쓰게 되면은 컴파일 시점에 타입 추론을 하게 되잖아. 그럼 오히려 런타임 시점에 타입 추론을 안 한다는 건데 오히려 더 안정적인 거 아닌가? 컴파일러가 해주는 타입 추론을 안 받을 이유가 없다고 생각한다. 리비: 그런데 예를 들어서 진짜 극단적인 예시인데 나중에 새로운 컴파일러가 나왔어. 리비 컴파일러라고 나와가지고. 근데 얘는 타입 추론할 때 뭔가 좀 달라져서 우리가 코드를 수정해야 하는 일이 생길 수도 있을 것 같아. 어쨌든 컴파일러에 의존이 생긴다는 거는 우리가 컴파일러의 구현대로 맞춰야 한다는 얘기니까 아까랑 똑같은 얘기긴 한데 우리가 충분히 제어할 수 있는 부분인데 컴파일러한테 그걸 맡기면 위험 지점이 좀 늘어나지 않나 라는 생각입니다. 제리: 근데 일단 만약에 컴파일러에 뭔가 새로운 변화가 추가된다고 해도 무조건 기존의 코드를 포용할 수 있는 범위로 발전한다고 생각해. 왜냐하면 제네릭 같은 것도 후에 생겼지만 컴파일러가 내부적으로 구 버전의 코드까지 다 컴파일할 수 있게 그 기능을 붙였잖아. 그래서 이 var가 나중에는 타입 추론이 안 되면 어떡하지라는 걱정은 지금까지의 역사로 봤을 때는 안 해도 될 걱정이라고 생각한다. 리비: 아까 얘기했던 거랑 비슷한데 new HashMap한 다음에 그걸 바로 받았다고 쳐보자. 근데 우리의 프로그램이 이거를 Map으로 기대하고 나중에 동적으로 HashMap이 아니라 ConcurrentHashMap을 쓰도록 바꾼다고 한번 생각을 해볼게요. 그럴 때는 바로 추론되는 타입이 Map이어야 하잖아. 근데 Map이 아닐 위험도 있을 것 같아. 똑똑한 컴파일러가 아니라면 지금 우리의 코드에서는 var 타입으로 반응되는 게 굉장히 위험한 행위잖아. 그런 걸 생각해봤을 때 var 타입을 사용하지 않고 명시적으로 다형성을 사용하는 게 낫지 않나. 콜리: 그래서 이게 ArrayList로 선언을 하면 그대로 추론이 되는 게 맞아? 그게 되게 중요할 것 같아. 리비: 한 번 찍어볼까? 한 번 동적으로 바꿔보자. 애초에 에러가 뜨네. 제리: 애초에 var 자체가 선언할 때 타입을 지정하고 그뒤로 타입을 바꿀 수 없는 키워드라서. 리비: 그러면 에 선생의 주장이 훨씬 강력해지는군요. 다형성을 이용하기 힘들지 않나요? 제리: 근데 이미 선언한 변수를 저렇게 바꿀 일이 언제 있어? 콜리: 근데 그리고 나는 var가 로컬 변수에만 선언이 가능하다는 게 가장 큰 의미를 가진다고 생각을 하거든. 그러니까 블록 내에서 자원이 할당되고 코드가 끝나면 자연스럽게 해제가 되잖아. 그러면 결론적으로는 이 로직 내에서만, 그리고 우리가 클린 코드로 작성한다면 일회용으로 사용하고 버릴 코드들이란 말이야. 그런 차원에서 나는 우리가 var가 만들어진 목적 자체를 정확히 인지하고 쓸 필요가 있다고 생각하긴 해요. 리비: 콜리가 완전 제대로 짚었네. 애초에 지역 변수에만 선언할 수 있으니까. 콜리: 그러니까 우리가 명료하게 클린 코드라고 하면 메서드 자체가 10줄이 넘지 않으니까 그 10줄 내에서 일회용으로 선언되고 해제되는 자원에 대해서 명시적으로 타입을 계속 넣어주는 게 과연 의미가 있나. 에버: 그러면 좀 다른 얘기인데 만약 int를 목적으로 var 타입을 선언하고 그게 long의 범위로 넘어갈 수도 있잖아. 콜리: var는 처음에 선언될 때부터 컴파일 타임에 타입이 정해지고 그 후로는 변하지 않는다. 그래서 var 타입에서 주의해야 하는 가장 큰 두 가지가, 첫 번째가 아까 이야기했었던 제네릭 관련해서 추론이 안 되기 때문에 오른쪽에 선언을 해줘야 한다는 거고, 두 번째가 리터럴 타입 사용을 할 때도 처음부터 숫자형을 명확하게 명시해줄 필요가 있다는 것이다. var를 쓰지 않아도 겪는 문제라고 생각하고, var이기 때문에 발생하는 문제가 아닌 것 같다. 그래서 나는 var에 좀 찬성하는 게, 우리가 우려하는 부분들은 지역 변수에 대해서는 주로 발생하지 않는다. 객체 이름이 너무 길어질 때 쓰는 것 괜찮겠다, 그러니까 우리가 명확하게 타입을 인지한 상태로 지역 변수 내에서 중복적인 타입 선언은 필요하지 않은 부분에 한해서, 딱 봐도 알 수 있는 보일러 플레이트 코드에 한해서는 써도 괜찮다. 정리리비: final과 var를 구구가 왜 그렇게 같이 많이 쓸까 생각했었는데 그냥 약간 코틀린의 잔해라고 생각했다. 구구가 코틀린 개발을 했었는진 모르겠는데 코틀린에서는 final과 var 타입 추론이 기본이라고 알고 있다. 그런데 나는 아직 자바 코드가 더 익숙해서 얘네들의 장점이 간결함 외에는 별로 생각나지 않는다. 간결함보다 뭔가 조금 더 느껴지면 그때부터 사용을 좀 고려할 것 같다. 에버: 나는 var를 사용했을 때 오히려 가독성이 떨어진다고 구구 코드를 보면서 느끼게 되어서 사용하지 않을 것 같다. 만약 팀 프로젝트에서 사용한다면 더더욱 나는 안 좋다고 생각한다. 제리: 일단 나는 오늘 리비가 들어준 예시 때문에 왜 final 혹은 var만 쓰는 게 아니라 final var를 같이 쓰는지에 대해 좀 알게 되었던 것 같다. 원래 자바처럼 타입 엄격한 언어에서 var를 쓰는 게 납득이 안 가서 안 좋아했는데, 유지보수 관점에서 var가 압도적으로 좋구나 싶어서 협업하는데 타입을 수정해야 하는 코드량이 많다고 하면 var를 도입해볼 만 하다고 생각한다. 한 번 쓰니까 생각보다 금방 익숙해지는 것 같다. 콜리: var를 보일러 플레이트 코드에는 많이 도입할 것 같다고 생각했다. 나는 자동 완성을 주로 하는 편이라 var로 처리하면 좀 더 빠르게 코드를 작성할 수 있을 것 같다는 생각이 들었다. 두 번째로, var를 사용함으로써 자연스럽게 final도 같이 사용할 것 같다. 코드가 너무 길어져서 final을 붙이는 걸 꺼렸는데 var를 사용하면 그래도 코드가 짧아지니까 같이 습관화할 수 있지 않을까 하는 생각이 든다. 왜 지역변수에만 var를 활용했는지를 의식하면서 쓰면 충분히 그 효용을 누릴 수 있을 것 같다. |
Beta Was this translation helpful? Give feedback.
-
팀 컨벤션으로 var 키워드 도입을 찬성하는지, 반대하는지 논의해보자
Beta Was this translation helpful? Give feedback.
All reactions