현직자 멘토링 F-Lab에서 멘티 및 수료생을 대상으로 이펙티브 코틀린 온/오프라인 스터디를 참여하였습니다.
1주마다 각자 1장씩을 맡아서 브리핑하고 아젠다를 제시하면 그에 따라 다같이 토론 형태로 스터디를 진행합니다.
먼저 1장에서 다루는 안정성에 대한 아젠다와 개인적으로 느낀점에 대해서 서술하고자 합니다.
상태를 적절하게 관리하는 것이 힘든 이유
멀티스레드를 활용해서 프로퍼티를 수정할 때, 충돌에 의해 일부 연산이 이루어지지 않는 경우
ps) 코틀린의 코루틴을 활용하면, 더 적은 스레드가 관여되므로 충돌과 관련 된 문제가 줄어듭니다.
가변성은 생각보다 단점이 많아서 이를 완전하게 제한하는 프로그래밍 언어도 있다 => 순수 함수형 언어(하스켈)
하지만 이러한 프로그래밍 언어는 가변성에 너무 많은 제한이 걸려서 프로그램을 작성하기가 굉장히 어렵다.
가변성은 시스템의 상태를 나타내기 위한 중요한 방법이다.
코틀린의 프로퍼티는 기본적으로 캡슐화되어 있고, 추가적으로 사용자 정의 접근자(getter와 setter를 가질 수 있습니다.)
추가적으로 var은 게터와 세터를 모두 제공하지만, val은 변경이 불가능하므로 게터만 제공합니다. 그래서 val을 var로 오버라이드할 수 있습니다.
interface Element {
var active: Boolean
}
class ActualElement: Element {
override var active: Boolean = false
}
정리 : 읽기 전용 프로퍼티 val의 값은 변경될 수 있기는 하지만, 프로퍼티 레퍼런스 자체를 변경할 수는 없으므로 동기화 문제 등을 줄일 수 있습니다. 그래서 일반적으로 var보다 val을 많이 사용한다.
val은 읽기 전용 프로퍼티지만, 변경할 수 없음(불변)을 의미하는 것은 아니다. 또한, 게터 또는 델리게이트로 정의할 수 있다.
만약, 완전히 변경할 필요가 없다면, final 프로퍼티를 사용하는 것이 좋다.
val은 정의 옆에 상태가 바로 적히므로, 코드의 실행을 예측하는 것이 훨씬 간단하다. 또한, 스마트 캐스트 등의 추가적인 기능을 활용할 수 있습니다.
읽기 전용 컬렉션 : Iterable, Collection, Set, List 인터페이스
읽고 쓸 수 있는 컬렉션 : MutableIterable, MutableCollection, MutableSet, MutableList
결론 : immutable 객체는 자신의 일부를 수정한 새로운 객체를 만들어야 한다.
하지만, 모든 프로퍼티를 대상으로 함수를 하나하나 만드는 것은 굉장히 귀찮은 일이기 때문에 data 한정자를 사용해야 한다.
요약 : var 보다는 val을 사용하는 것이 좋다. 람다에서 변수를 캡처한다는 것, 간단한 규칙만 지켜 주면, 발생할 수 있는 여러 문제를 차단 할 수 있다.
요약 : 플랫폼 타입을 사용하는 코드는 해당 부분만 위험할 뿐 아니라, 이를 활용하는 곳까지 영향을 줄 수 있는 위험한 코드이다.
또한, 연결되어 있는 자바 생성자, 메서드, 필드에 nullable 여부를 지정하는 어노테이션을 활용하는 것도 좋다.
요약 : 타입을 확실하게 지정해야 하는 경우 명시적으로 타입을 지정해야 한다는 원칙만 갖고 있으면 된다.
또한, 안전을 위해서 외부 API를 만들 때는 반드시 타입을 지정하고, 이렇게 지정한 타입을 특별한 이유와 확실한 확인 없이는 제거하지 말아야 한다.
요약
require 블록 : 아규먼트와 관련된 예측을 정의할 때 사용하는 범용적인 방법
check 블록 : 상태와 관련된 예측을 정의할 때 사용하는 범용적인 방법
assert 블록 : 테스트 모드에서 테스트를 할 때 사용하는 범용적인 방법
return과 throw와 함께 Elvis 연산자 사용하기
두 오류를 사용하게 되는 상황은 어떤 때인가?
엔지니어링이 강한 회사(또는 스타트업, 신규 사업)은 공격적 코딩이 주가 되어 표준 오류를 사용하게 된다. 서비스 회사의 경우 방어적 코딩을 중시해 사용자 정의 오류를 사용하게 된다.
예외 처리의 경우 되도록 처리가 되지 않는 상황을 만드는 게 좋다. 이유는 top down 구조에서 C언어의 goto 예외 처리와 관련이 있다.
단위 테스트를 어떻게 사용해야 할까?
단위 테스트는 너무 광범위한 내용을 다루므로 현재는 넘어가는 걸로 결정함 대신 단위 테스트를 작성할 때는 "무엇"을 테스트 해야 하는지 명확하게 인식하고 작성해야 한다. 안 그러면 작성 코드량만 불어나며 비효율적인 작업이 된다.
불변 객체에 값을 더할 때 새로 객체를 생성하며 성능 상 불이익이 발생하는가?
copy 대신 플러스로 값을 더해 새로운 객체를 만들 면 불이익은 발생하지 않는다.
객체지향적인 언어는 상태와 행위를 포함한다. 그런데 불변 객체는 상태가 없다. 그렇다면 이 상황에서 불변 객체는 과연 객체지향적인 것인가?
해당 논점은 각자 좀 더 생각해보기로 했음.
개발자마다 null의 의미 부여가 달라 생기는 문제점?
null을 아예 안 쓰는 방법 또는 null을 잘 활용하는 방법을 고려할 수 있다. null을 사용하지 않으면 안전하지만 그만큼 코드가 불어나 가독성과 작성 시간이 길어질 수 있다. null을 활용하면 편하긴 하지만 그만큼 남용될 가능성이 있다.
F-Lab 멘토링을 받으면서 immutable, mutable에 대해서 인지는 하고 있었지만 실제로 개발할 때 크게 신경쓰지 못한 포인트였었다. 하지만 1장에서부터 Immutable 객체를 사용하면 좋은 점들이 대해서 안내하여 확실하게 인지하는 계기가 되었다. 그 밖에도 코틀린에 한정된 것이 아니라 전체적인 프로그래밍 언어 베이스로 개발을 진행할 때 기본적으로 지키면 좋은 것들에 대한 안내가 나와있다. 잠깐 코루틴에 대한 언급이 있어서 중요한 것 같아 찾아봤더니 동시성 관련 내용이였고 관련해서 추후 더 상세하게 학습할 예정이다.