knowledge를 반복해서 사용하지 말라
- 프로젝트에세 이미 있던 코드를 복사해서 붙여넣고 있다면, 무언가가 잘못된 것이다.
knowledge
- knowledge: 의도적인 정보
- 프로젝트를 진행할 때 정의한 모든 것
- 알고리즘의 작동 방식, UI의 형태, 우리가 원하는 결과 등
- knowledge는 코드, 설정, 템플릿 등으로 표현할 수 있다.
- 프로그램에서 중요한 knowledge 두 가지
- 로직: 프로그램이 어떤 식으로 동작하는지와 프로그램이 어떻게 보이는지
- 공통 알고리즘: 원하는 동작을 하기 위한 알고리즘
- 비즈니스 로직은 시간이 지나면서 계속해서 변하지만, 공통 알고리즘은 한 번 정의된 이후에는 크게 변하지 않는다.
모든 것은 변화한다
- 변화하는 이유
- 회사가 사용자의 요구 또는 습관을 더 많이 알게 되었다.
- 디자인 표준이 변화했다.
- 플랫폼, 라이브러리, 도구 등이 변화해서 이에 대응해야 한다.
- 오늘날 대부분의 프로젝트는 몇 달마다 요구 사항과 내부적인 구조를 계속해서 변경한다.
- 변화할 때 가장 큰 적은 knowledge가 반복되어 있는 부분이다.
- 여러 부분에 반복되 어있는 코드를 변경하려면 검색 중 실수가 발생할 수도 있고, 무엇보다 귀찮다.
- 또한 일부가 과거에 약간 다른 반식으로 이미 변경되어 있을 수 있다.
- knowledge 반복은 피로젝트의 확장성을 막고, 쉽게 깨지게 만든다.
언제 코드를 반복해도 될까?
- 얼핏보면 knowledge 반복처럼 보이지만 ,실질적으로 다른 knowledge를 나타내므로 추출하면 안되는 부분은 반복을 줄이면 안된다.
- 다른 knowledge를 나타내는지는 “함께 변경될 가능서이 높은가? 따로 변경될 가능성이 높은가?“라는 질문으로 결졍할 수 있다.
- 비즈니스 규칙이 다른 곳(source)에서 왔다면, 독립적으로 변경될 가능성이 높다.
단일 책임 원칙
- 잘못된 코드 추출로부터 우리를 보호할 수 있는 규칙
- 두 액터가 같은 클래스를 변경하는 일은 없어야 한다.
- 개발자는 수정해야할 함수가 자신이 해야 하는 일 이외의 책임을 갖고 있을 거라는 것은 예측하지 못할 수 있다.
- 책임에 따라 클래스를 구분해서 만들어야한다.
- 또는, 확장 함수를 활용하여 서로 다른 모듈에 배치할 수 있다.
- 단일 책임 원칙은 두 가지 사실을 알려준다.
- 서로 다른 곳에서 사용하는 knowledge는 독립적으로 변경할 가능성이 많다. 따라서 비슷한 처리를 하더라도, 완전히 다른 knowledge로 취급하는 것이 좋다.
- 다른 knowledge는 분리해 두는 것이 좋다. 그렇지 않으면, 재사용해서는 안 되는 부분을 재사용하려는 유혹이 발생할 수 있다.
일반적인 알고리즘을 반복해서 구현하지 말라
- 이미 있는 것을 활용하면, 단순하게 코드가 짧아진다는 것이외에도 다양한 장점이 있다.
- 코드 작성 속도가 빨라진다.
- 구현을 따로 읽지 않아도, 함수의 이름 등만 보고도 무엇을 하는지 확실하게 알 수 있다.
- 직접 구현할 때 발생할 수 있는 실수를 줄일 수 있다.
- 제작자들이 한 번만 최적화하면, 이러한 함수를 활용하는 모든 곳이 최적화의 혜택을 받을 수 있다.
표준 라이브러리 살펴보기
- 가장 대표적인 라이브러리는 표준 라이브러리인 stdlib이다.
map
함수- 자바빈 패턴을 사용하는 것보다는 팩토리 메서드를 활용하거나, 기본 생성자를 활용하는 것이 좋다.
자바빈 패턴: 인자 없는 생성자를 호출하여 기본 객체를 만든 다음, 세터를 이용하여 필드 값을 채워나가는 패턴 단점1: 1회의 함수 호출로 객체 생성을 끝낼 수 없으므로, 객체 일관성이 일시적으로 깨질 수 있다. 단점2: 불변 객체로 만들 수 없다. 자바빈 패턴을 대신 빌더 패턴이나, kotlin의 기본 값이 있는 생성자를 이용하는 것이 좋다.
나만의 유틸리티 구현하기
- 표준 라이브러리에 없는 알고리즘이 필요할 수도 있다.
- 이는 널리 알려진 추상화이므로 범용 유틸리티 함수로 정의하는 것이 좋다.
- 많이 사용되는 알고리즘을 추출하는 방법
- 확장 함수
- 톱레벨 함수
- 프로퍼티 위임
- 클래스
- 확장 함수가 다른 방법들과 비교해서 갖는 장점
- 함수는 상태를 유지하지 않으므로, 행위를 나타내기 좋다.
- 톱레벨 함수와 비교해서, 확장 함수는 구체적인 타입이 있는 객체에만 사용을 제한할 수 있다.
- 수정할 객체를 아규먼트로 전달받아 사용하는 것보다는 확장 리시버로 사용하는 것이 가독성 측면에서 좋다.
- 확장 함수는 객체에 정의한 함수보다 객체를 사용할 때, 자동 완성 기능 등으로 제안이 이루어지므로 쉽게 찾을 수 있다.
일반적인 프로퍼티 패턴은 프로퍼티 위임으로 만들어라
- 프로퍼티 위임을 사용하면 일반적인 프로퍼티의 행위를 추출해서 재사용할 수 있다.
- 대표적인 프로퍼티 위임
lazy
델리게이터observable
델리게이터
- 프로퍼티 델리게이트는 프로퍼티와 관련된 다양한 조작을 할 수있으며, 컨텍스트와 관련된 대부분의 정보를 갖는다.
일반적인 알고리즘을 구현할 때 제네릭을 사용하라
- 타입 파라미터는 컴파일러에 타입과 관련된 정보를 제공하여 컴파일러가 타입을 조금이라도 더 정확하게 추측할 수 있게 해준다.
- 제네릭 제한: 타입 파라미터의 중요한 기능 중 하나는 구체적인 타입의 서브타입만 사용하게 타입을 제한하는 것이다.
타입 파라미터의 섀도잉을 피하라
- 섀도잉: 지역 파라미터가 외부 스코프에 있는 프로퍼티를 가리는 경우
- 클래스 타입 파라미터와 함수 타입 파라미터 사이에서도 발생한다.
- 섀도잉이 발생한 코드는 이해하기 어려울 수 있다.
제네릭 타입과 variance 한정자를 활용하라
함수 타입
- 함수 타입은 파라미터 유형과 리턴 타입에 따라서 관계를 갖는다.
- 코틀린 함수 타입의 모든 파라미터 타입은 contravariant이다.
- 코틀린 함수 타입의 모든 리턴 타입은 covariant이다.
variance 한정자의 안정성
- 자바의 배열은 covariant다.
- covariant라서 아래의 상황에 문제가 발생한다.
- covariant 타입은 out 위치에 사용할 수 있다.
- contravariant 타입은 in 위치에 사용할 수 있다.
variance 한정자의 위치
- variance 한정자 위치
- 선언 부분
- 클래스와 인터페이스를 활용하는 위치: 특정한 변수에만 variance 한정자가 적용된다.
- variance 한정자를 사용하면, 위치가 제한될 수 있다.
MutableList<out T>
가 있다면,get
으로 요소를 추출할 때 T 타입이 나올 것이지만,set
은Nothing
타입의 아규먼트가 전달될 수 있으므로 사용할 수 없다.MutableList<in T>
를 사용할 경우,get
과set
을 모두 사용할 수 있다. 하지만,get
을 사용할 경우, 전달되는 자료형은Any?
가 된다. 모든 타입의 슈퍼타입을 가진 리스트가 존재할 가능성이 있기 때문이다.
공통 모듈을 추출해서 여러 플랫폼에서 재사용하라
- 기업이 한 플랫폼만을 대상으로 애플리케이션을 만드는 경우는 없다.
- 다른 플랫폼에 동일한 제품을 구현한다면, 재사용할 수 있는 부분이 더 많을 것이다.
- 특히 비즈니스 로직 부분들은 거의 동일하다.
- 소르 코드를 공유할 수 있다면, 큰 이득이 발생할 것이다.
풀스택 개발
- 웹사이트 개발은 주로 자바스크립트고, 백엔드 개발은 주로 자바다.
- 두 언어는 굉장히 다르므로, 일반적으로 백엔드와 웹은 분리해서 개발한다.
- 코틀린은 자바의 인기있는 대안이 되고 있으며, 자바스크립트로 컴파일될 수도 있다.
- 이미 많은 코틀린/JS 라이브러리가 있으며, 코틀린을 활용해 다양한 웹 애플리케이션을 만들 수 있다.
- 따라서 공통 코드, API 엔드포인트 정의, 추상화 등을 재사용할 수 있다.
모바일 개발
- 코틀린의 멀티 플랫폼 기능을 확용하면, 로직을 한 번만 구현하고, 안드로이드와 아이폰 플랫폼에서 재사용할 수 있다.
- 공통 모듈을 만들고, 여기에 다양한 비즈니스 로직을 구현하면 된다.
- 비즈니스 로직은 플랫폼과 프레임워크에 종속되지 않고, 독립적이어야 한다.
라이브러리
- 공통 모듈을 정의할 수 있다는 것은 라이브러리에 있어서 강력한 도구다.
- 플랫폼에 크게 의존하지 않는다는 점은 공통 모듈을 JVM, 자바스크립트, 네이티브 환경에서 작동하는 모든 언어에서 활용할 수 있다는 의미다.
함께 사용하기
- 코틀린으로 작성할 수 있는 것들
- 코틀린/JVM을 사용한 백엔드 개발 - 스프링, Ktor 등
- 코틀린/JS를 사용한 웹사이트 개발 - 리액트 등
- 코틀린/JVM을 사용한 안드로이드 개발 - 안드로이드 SDK 등
- 코틀린/네이티브를 통해 Objective-C/스위프트로 iOS 프레임워크 개발
- 코틀린/JVM을 사용한 데스크톱 개발 - TornadoFX 등
- 코틀린/네이티브를 사용한 라즈베리파이, 리눅스, macOS 프로그램 개발