스터디/이펙티브코틀린

아이템 30 - 요소의 가시성을 최소화화라

WHY? 작은 인터페이스는 배우기 쉽고 유지하기 쉽다. 기능이 많은 클래스보다 기능이 적은 클래스를 이해하는 것이 쉽고 유지보수하기 쉽다. 보이는 요소 자체가 적으면 유지보수하고 테스트할 것이 적다. 변경을 가할 때는 기존의 것을 숨기는 것보다 새로운 것을 노출하는 것이 쉽다. 기존 요소는 이미 사용하고 있는 부분에 많은 영향을 미치고 있을 수 있기 때문이다. 가시성과 관련된 제한을 변경하는 것은 더 어렵다. 따라서 변경할 경우 대체제를 제공해야한다. 클래스의 상태를 나타내는 프로퍼티를 외부에서 변경할 수 있다면 클래스는 특정 조건을 만족해야하는 자신의 상태를 보장할 수 없다. 클래스의 값(var)의 setter의 가시성만 private하게 제한 하도록 하는 것이 좋다. 가시성이 제한 될수록 클래스의 변..

2023.06.12 게시됨

스터디/이펙티브코틀린

아이템 24 - 제네릭 타입과 variance 한정자를 활용하라

제네릭 타입(T)에 한정자 out과 in이 붙은 경우 다음과 같이 생각하자. out : T는 반환 타입으로만 사용할 수 있다. in: T는 타입 매개변수로만 사용할 수 있다. variance: 가변성, 차이 여기서 variance 한정자는 out과 in 키워드를 의미한다. out: 공변성(covariant)으로 만든다. 자바의 extends와 유사하다. 상한을 지정한다. out 한정자를 사용하면서 발생하는 차이는 아래 코드로 설명한다. class Cup fun main() { val anys: Cup = Cup // 컴파일 에러, 서로 관련이 없는것으로 취급 } class Cup fun main() { val anys: Cup = Cup // Any를 기반으로 하는 모든 타입을 허용 } in: 반변성(c..

2023.05.14 게시됨

스터디/이펙티브코틀린

아이템 23 - 타입 파라미터의 섀도잉을 피하라

아래는 프로퍼티와 파라미터가 같은 이름을 가지는 섀도잉을 나타낸다. 이 경우 함수 내에서 섀도잉으로 인해 프로퍼티를 가르키게 된다. class Forest(val tree: Tree) { // (1) fun addTree(tree: Tree) { // (2) println(tree) // (3) -> (1)을 바라본다. } } 제네릭에 대한 이해가 부족할 때 아래와 같이 사용하여 섀도잉이 되면 원치않은 방향으로 파라미터가 사용될 수 있다. class Forest { // (1) fun addTree(tree: T) { // (2) // 여기서 tree의 T(2)는 T(1)와 서로 다른 타입이기 때문이다. // 이름을 바꾸던가 하나만 사용하도록 하자. } } class Forest { // (1) fun ..

2023.05.14 게시됨

스터디/이펙티브코틀린

아이템 21 - 일반적인 프로퍼티 패턴은 프로퍼티 위임으로 만들어라

지연 프로퍼티 lazy 프로퍼티는 이후에 처음 사용하는 요청이 들어올 때 초기화되는 프로퍼티를 의미한다. 지연프로퍼티를 java에서 구현하려면 복합한 과정이 필요한데 코틀린은 프로퍼티 위임을 이용하여 간단하게 구현할 수 있다. val value by lazy { createValue() } Delegates.observable을 이용하면 프로퍼티 위임을 사용하면 변화를 감지하는 옵저버 패턴도 쉽게 만들 수 있다. var catchedChessPeices: List by Delegates.observable(listOf()) { _, old, new -> checkKingDied(new) } 위와 같이 프로퍼티 위임 메커니즘을 사용하면 뷰, 리소스 바인딩, 의존성 주입, 데이터 바인딩 등 다양한 패턴을 만..

2023.05.14 게시됨

스터디/이펙티브코틀린

아이템 19 - knowledge를 반복하여 사용하지 말라

프로젝트에서 이미 있던 코드를 복사해서 붙여넣고 있다면, 무언가가 잘못된 것이다. 이를 “knowledge를 반복하여 사용하지 말라” 라고 표현하기도 하고 Don’t Repeat Yourself인 DRY 규칙으로 표현하기도 한다. 그런데 이를 잘못 이해하는 경우가 있다. Knowledge 프로젝트를 진행할 때 정의한 모든 것이 Knowledge(=의도적인 정보)이다. 알고리즘의 동작 방식, UI 형태, 우리가 원하는 결과등이 모두 의도적인 정보이다. 가장 중요한 두 가지 Knowledge를 뽑으면 다음과 같다. 로직: 프로그램이 어떻게 동작하는지, 어떻게 보이는지 공통 알고리즘: 원하는 동작을 하기 위한 알고리즘 둘의 차이점은 시간에 따른 변화이다. 비즈니스 로직은 시간이 지나면서 같이 변하지만 공통 알..

2023.05.03 게시됨

스터디/이펙티브코틀린

아이템 17 - 이름 있는 아규먼트를 사용하라

코드에서 아규먼트의 의미가 명확하지 않은 경우는 모든 코드를 작성하다 느낄 수 있는 부분이다. val text = (1..10).joinToString("|") // `|`이 무엇을 의미하는지? joinToString에 대해 알고 있다면 구분자라는 것을 알 수 있지만 아니라면 이해하기 힘들 수 있다. 파라미터가 명확하지 않은 경우에는 이름있는 아규먼트(named argument)를 이용하여 명확하게 만들자. val text = (1..10).joinToString(separator = "|") separator를 변수로 선언하여 사용해도 좋지만 아래와 같은 문제가 발생 할 수 있다. 실제로 코드에서 사용되는지 확신 할 수 없다. (사실 이건 IDE가 다 알려주니 큰 문제가 되지 않는다.) 변수를 잘못 만..

2023.04.27 게시됨

스터디/이펙티브코틀린

아이템 16 - 프로퍼티는 동작이 아니라 상태를 나타내야 한다

코틀린의 프로퍼티는 자바의 필드와 비슷해 보이나 다른 개념이다. var: name: String? = null get() = field?.toUpperCase() set(value) = { if(!value.isNullOrBlank()){ field = value } } 위와 같이 파생 프로퍼티라 불리는 var를 사용해서 만든 프로퍼티는 위와같이 게터와 세터를 정의할 수 있다. 이 때 field는 데이터를 저장하는 백킹(backing) 필드에 대한 레퍼런스이다. 백킹 필드는 따로 만들지 않아도 디폴트로 생성된다. 단, val를 이용한 읽기 전용 프로퍼티의 경우 생성되지 않는다. 프로퍼티는 필드가 필요하지 않다. 개념적으로 접근자라고 생각하면 된다. 따라서 val의 경우 getter, var의 경우 get..

2023.04.27 게시됨

스터디/클린코드

Junit에서 테스트 데이터 클리닝 하기

들어가며 책 단위테스트에서 통합테스트를 할 경우 공유 의존성의 초기화에 대해 이야기를 하는 부분이 있다. 공유 의존성은 테스트 컨텍스트를 공유하는 여러 테스트를 같이 실행하면 말 그대로 공유하기 때문에 앞서 실행된 테스트가 뒤에 실행되는 테스트에 영향을 미친다는 것이다. 그렇기 때문에 이 의존성에 대한 초기화 작업이 필요하다. 그렇다면 공유 의존성의 초기화 작업은 언제하는게 좋을까? 이에 대한 대답도 책에서 답해주고 있다. 테스트를 수행하기 전에 초기화를 해주는 것이다. 필자는 예전부터 습관적으로 테스트가 끝나고 마지막에 테스트에 사용된 공유 데이터를 지우는 작업을 했다. 테스트를 수행하면서 필요한 셋업데이터를 만들고 테스트 대상을 검증하며 생긴 데이터가 있으니 이후에 생성된 데이터를 지워야 한다는 생각..

2023.02.28 게시됨

스터디/스프링

Spring Batch 멀티 스레드 프로세싱을 활용하며 겪은 문제 (1)

들어가며 보통의 팀들이 사용하듯 통계성, 일회성 작업을 배치로 많이 작성하여 해결하고 있다. 그런데 필자가 기본적인 배치의 구조를 잘못 이해하면서 문제가 발생했다. 스프링 배치의 멀티 스레드 프로세싱을 활용하며 겪은 문제 중 잡 스코프(job scope)를 가지는 빈(bean)을 사용할 경우 겪은 문제를 기록한다. 문제 회사 코드를 가져올 수 없으니 예제 코드를 작성하고 요구사항에서 문제가 발생한 부분에 집중하기 위해 불 필요한 부분은 생략하였다. 코드는 코틀린으로 작성했다. 요구 사항 다른 시스템에서 전달받은 이벤트 중 특정 이벤트의 값이 잘못되어 올바르지 않은 값이 저장되었다. 다른 시스템을 담당하는 팀에서 파일로 전달받은 값으로 특정 데이터들을 수정해야 한다. 작성한 코드 배치 코드 처리 속도를 올..

2023.01.30 게시됨