목록전체 글 (152)
시배's Android
아이템26. 함수 내부의 추상화 레벨을 통일하라 계층이 잘 분리되면 무엇이 좋을까요? 어떤 계층에서 작업할 때 그 아래의 계층은 이미 완성되어 있으므로, 해당 계층만 생각하면 된다는 것입니다. 즉, 전체를 이해할 필요가 없어지는 것입니다. 추상화 레벨 높은 레벨로 갈수록 물리 장치로부터 점점 멀어집니다. 프로그래밍에서는 일반적으로 높은 레벨일수록 프로세서로부터 멀어진다고 표현합니다. 높은 레벨일수록 걱정해야 하는 세부적인 내용들이 적습니다. 높은 레벨일수록 단순함을 얻지만, 제어력을 잃습니다. 예를 들어 C언어는 메모리 관리를 직접 할 수 있습니다. 반면, 자바는 가비지 컬렉터가 자동으로 메모리를 관리해 줍니다. 추상화 레벨 통일 함수도 높은 레벨과 낮은 레벨을 구분해서 사용해야 한다는 원칙이 있습니다...
import kotlin.reflect.KProperty fun main(){ val test : Int by LoggingProperty(100) println(test) } class LoggingProperty (var value : T) { operator fun getValue( thisRef : Any?, prop : KProperty ) : T { println("${prop.name} returned value $value") return value } operator fun setValue( thisRef : Any?, prop : KProperty, newValue : T ) { val name = prop.name println("$name changed from $value to $..
플로우는 비동기적으로 계산해야 할 값의 스트림을 나타냅니다. Flow 인터페이스 자체는 떠다니는 원소들을 모으는 역할을 하며, 플로우의 끝에 도달할 때까지 각 값을 처리하는 걸 의미합니다. 플로우를 사용하면 코루틴이 연산을 수행하는 데 필요한 기능을 전부 사용할 수 있습니다. 플로우의 빌더와 연산은 중단 함수이며 구조화된 동시성과 적절한 예외 처리를 지원합니다. 플로우는 어딘가에서 시작되어야 합니다. 플로우 빌더, 다른 객체에서의 변환, 또는 헬퍼 함수로부터 시작됩니다. 플로우의 마지막 연산은 최종 연산이라 불리며, 중단 가능하거나 스코프를 필요로 하는 유일한 연산이라는 점에서 아주 중요합니다. 시작 연산과 최종 연산 사이에 플로우를 변경하는 중간 연산을 가질 수 있습니다. 웹소켓이나 RSocket 알림..
핫 데이터 스트림은 열정적이라 데이터를 소비하는 것과 무관하게 원소를 생성하지만, 콜드 데이터 스트림은 게을러서 요청이 있을때만 작업을 수행하며 아무것도 저장하지 않습니다. 핫인 리스트와 콜드인 시퀀스를 사용할 때 그 차이가 드러납니다. 핫 데이터 스트림의 빌더와 연산은 즉각 실행됩니다. 콜드 데이터 스트림에서는 원소가 필요할 때까지 실행되지 않습니다. 콜드 데이터 스트림 무한할 수 있습니다. 최소한의 연산만 수행합니다. 메모리를 적게 사용합니다. 핫 데이터 스트림 항상 사용 가능한 상태입니다. 여러 번 사용되었을 때 매번 결과를 다시 계산할 필요가 없습니다. 채널은 핫이라 값을 곧바로 계산합니다. 별도의 코루틴에서 계산을 수행합니다. 채널은 소비되는 것과 상관없이 값을 생성한 뒤에 가지게 됩니다. 채널..
아이템19. knowledge를 반복하여 사용하지 말라 knowledge는 넓은 의미로 의도적인 정보를 뜻합니다. 프로젝트를 진행할 때 정의한 모든 것이 knowledge입니다. 알고리즘의 작동 방식, UI의 형태, 우리가 원하는 결과 등이 모두 의도적인 정보이며, knowledge입니다. 로직 : 프로그램이 어떠한 식으로 동작하는지와 프로그램이 어떻게 보이는지 공통 알고리즘 : 원하는 동작을 하기 위한 알고리즘 둘의 가장 큰 차이점은 시간에 따른 변화입니다. 비즈니스 로직은 시간이 지나면서 계속해서 변하지만 콩통 알고리즘은 한 번 정의된 이후에는 크게 변하지 않습니다. knowledge도 계속해서 변한다. 회사가 사용자의 요구 또는 습관을 더 많이 알게 되었다. 디자인 표준이 변화했다. 플랫폼, 라이브..
코루틴은 가장 먼저 완료되는 코루틴의 결과를 기다리는 select 함수를 제공합니다. 또한 여러 개의 채널 중 버퍼에 남은 공간이 있는 채널을 먼저 확인하여 데이터를 보내거나, 이용 가능한 원소가 있는 채널로부터 데이터를 받을 수 있는지 여부도 확인할 수 있습니다. 코루틴 사이에 경합을 일으키거나, 여러 개의 데이터 소스로부터 나오는 결과값을 합칠 수도 있습니다. 지연되는 값 선택하기 여러 개의 소스에 데이터를 요청한 뒤, 가장 빠른 응답만 얻는 경우를 생각해봅시다. 요청을 여러 개의 비동기 프로세스로 시작한 뒤, select 함수를 표현식으로 사용하고 표현식 내부에서 값을 기다리는 것입니다. select 내부에서는 셀렉트 표현식에서 나올 수 있는 결괏값을 명시하는 Deferred 값의 onAwait 함..
채널은 송신자와 수신자의 수에 제한이 없으며, 채널을 통해 전송된 모든 값은 단 한 번만 받을 수 있습니다. Channel은 두 개의 서로 다른 인터페이스를 구현한 하나의 인터페이스입니다. SendChannel은 원소를 보내거나 채널을 닫는 용도로 사용됩니다. ReceiveChannel은 원소를 받을 때 사용됩니다. 채널의 진입점을 제한하기 위해 ReceiveChannel이나 SendChannel 중 하나만 노출시키는 것도 가능합니다. receive를 호출했는데 채널에 원소가 없다면 코루틴은 원소가 들어올 때 까지 중단됩니다. 반면 send는 채널의 용량이 다 찼을 때 중단됩니다. 용량이 제한적인 채널에서만 trySend tryReceive를 사용해야 합니다. produce 함수는 빌도로 시작된 코루틴이..
아이템11. 가독성을 목표로 설계하라 // 구현 A if (person != null && person.isAdult) { view.showPerson(person) } else { view.showError() } // 구현 B person?.takeIf { it.isAdult } ?.let(view::showPerson) ?. view.showError() 가독성이란 코드를 읽고 얼마나 빠르게 이해할 수 있는지를 의미합니다. 구현 A는 수정하기 쉽습니다. 구현 A는 디버깅도 더 간단합니다. 기본적으로 인지부하를 줄이는 방향으로 코드를 작성해야한다. 극단적이지 않기 let으로 인해서 예상하지 못한 결과가 나올 수 있다. (view.showPerson 에서 nullable을 리턴하는 경우) let은 절대..