프로그래밍 노트/Effective 시리즈

[Effective Kotlin. 49] 하나 이상의 처리 단계를 가진 경우에는 시퀀스를 사용하라 Iterable vs Sequence Sequence 지연(lazy) 연산 따라서 시퀀스 처리함수들은 데코레이터 패턴으로 꾸며진 새로운 시퀀스가 리턴 됨 최종 계산은 toList 또는 count 등의 최종 연산이 이루어질 때 수행됨 Iterable 즉시(eagerly) 연산 처리 함수를 사용할 때마다 연산이 이루어져 List가 만들어짐 public inline fun Sequence.filter( predicate: (T) -> Boolean ): Sequence { return FilteringSequence(ths, true, predicate) } public inline fun Iterable.fil..
객체를 생성하는 방법에 어떤 것들이 있는지, 각각의 방법에는 어떤 장점과 단점이 있는지 살펴보자. [Effective Kotlin. 33] 생성자 대신 팩토리 함수를 사용하라. 객체 생성 방법 생성자 별도의 함수를 통해 생성 생성자의 역할을 대신 해주는 함수를 팩토리 함수라 부르며, 아래와 같은 장점들이 생김 생성자와 다르게 함수에 이름을 붙일 수 있음 (가독성이 좋아짐) ArrayList(3) : ArrayList.withSize(3) 함수가 원하는 형태의 타입을 리턴할 수 있음 호출될 때마다 새 객체를 만들 필요가 없음 싱글턴 패턴처럼 객체를 하나만 생성하게 강제하거나, 최적화를 위해 캐싱 메커니즘을 사용할 수 있음 아직 존재하지 않는 객체를 리턴할 수 있음 가시성을 원하는 대로 제어할 수 있음 인라..
재사용(reusability)성은 프로그래밍 언어의 핵심이라고 할 수 있음 System.out.println, 각종 정렬 함수, http client 구현이 안되어 있다면? T_T 재사용성은 힘이 있는 만큼 굉장히 위험하기도 함 A, B의 공통 부분을 추출한다면, 이후 공통 부분을 수정할 일이 있을 경우 한꺼번에 수정 가능 그러나, 세상일은 우리가 원하는대로 일어나지 않음 A를 대상으로 수정한 것이 B에서 문제가될 수 있고, B를 대상으로 수정한 것이 A에서 문제가될 수 있음 따라서 재사용성을 고려하는 일은 생각보다 어렵고, 다양한 오류를 발생시킬 수 있음 [Effective Kotlin. 19] knowledge를 반복하여 사용하지 말라 프로젝트에서 이미 있던 코드를 복사해서 붙여넣고 있다면, 무언가가..
코틀린의 프로퍼티는 자바의 필드와 비슷해보이지만 완전히 다른 개념 // kotlin val name: String? = null // java String name = null; 공통점 : 데이터를 저장 프로퍼티는 더 많은 기능이 존재 기본적으로 프로퍼티는 사용자 정의 세터/게터를 가질 수 있음 var name: String? = null get() = field?.toUpperCase() set(value) { if (!value.isNullOrBlank()) { field = value } } field 식별자 : 프로퍼티의 데이터를 저장해 두는 백킹 필드(backing field)에 대한 레퍼런스 백킹 필드는 세터와 게터의 디폴트 구현에 사용되며 따로 만들지 않아도 디폴트로 생성 됨 val을 사용해..
개발자가 코드를 작성하는 데는 1분 걸리지만, 이를 읽는 데는 10분이 걸린다 - 로버트 마틴 프로그래밍은 쓰기보다 읽기가 중요 항상 가독성을 생각하며 코드릴 작성할 필요가 있음 인식 부하 감소 kotlin을 처음 접하게 되면 코드가 간결해지는 몇 가지 마법들을 만나게 된다. 이 몇가지 마법들을 알게되면 활용을 하고 싶어지고, 코드를 계속 간결하게 만들고 싶은 욕망에 사로잡히게 되는데 가독성 측면에서 생각해볼 필요가 있음 무엇이 더 좋을까? // 구현 A if (person != null && person.isAdult) { view.showPerson(person) } else { view.showError() } // 구현 B person?.takeIf { it.isAdult } ?.let(view:..
계층이 잘 분리되면 좋은점? 어떤 계층에서 작업할 때 해당 계층만 생각하면 된다는 점. 즉, 전체를 이해할 필요가 없어지는 것 어셈블리 언어, JVM 바이트 코드가 무엇인지 몰라도 프로그래밍할 수 있음 추상화 레벨 높은 레벨로 갈수록 프로세서(물리 장치)로부터 멀어짐 높은 레벨일수록 걱정해야 하는 세부적인 내용들이 적어지지만(단순함을 얻는다.), 제어력을 읽어버림 c언어는 메모리 관리를 직접 할 수 있으나, 자바는 가비지 컬렉터가 자동으로 관리 해줌 메모리 사용을 최적화하는 것이 힘듬 높은 레벨(고수준)일 수록 비즈니스 핵심 로직에 가까움 추상화 레벨 통일 코드도 추상화를 계층처럼 만들어 사용할 수 있는데, 이를 위한 기본적인 도구가 함수 class CoffeeMachine { fun makeCoffee..
상속은 굉장히 강력한 기능인 만큼 여러 가지 문제를 발생시킬 수 있다. 따라서 단순하게 코드 추출 또는 재사용을 위해 상속을 한다면 신중하게 생각해봐야 한다. 간단한 행위 재사용 슈퍼 클래스를 만들어서 공통 행위를 추출한 경우 abstract class LoaderWithProgess { fun load() { // 프로그레스 바 보여줌 innerLoad() // 프로그레스 바 숨김 } abstract fun innerLoad() } class ProfileLoader: LoaderWithProgress() { override fun innerLoad() { // 프로파일 읽어 들임 } } class ImageLoader: LoaderWithProgress() { override fun innerLoad..
클라이언트가 클래스의 인스턴스를 얻는 방법 중 한가지로 생성자와 별도로 정적 팩터리 메서드(static factory method)를 제공하는 방법이 있다. (그 클래스를 반환하는 단순한 정적 메서드) boolean 값을 받아 Boolean 객체 참조로 변환해 준다. public static Boolean valueOf(boolean b){ return b ? Boolean.TRUE : Boolean.FALSE; } 정적 팩터리를 사용했을 때 생성자 보다 좋은점과 나쁜점을 알아보자. 장점 첫 번째, 이름을 가질 수 있다. 정적 팩터리는 이름만 잘 지으면 반환될 객체의 특성을 쉽게 묘사할 수 있다. BigInteger (int bitLength, int certainty, Random rnd) - 생성자 ..
많은 클래스가 하나 이상의 자원에 의존한다. 가령 맞춤법 검사기는 사전(dictionary)에 의존하는데, 이런 클래스를 정적 유틸리티 클래스로 구현한 모습을 드물지 않게 볼 수 있다. 정적 유틸리티를 잘못 사용한 예 - 유연하지 않고 테스트하기 어렵다. public class SpellChecker { private static final Lexicon dictionary = ...; private SpellChecker() {} // 객체 생성 방지 public static boolean isValid(String word){ ... } public static List suggestions(String type) { ... } } 싱글턴을 잘못 사용한 예 - 유연하지 않고 테스트하기 어렵다. pub..
자바 8전에는 메서드가 특정 조건에서 값을 반환할 수 없을 때 취할 수 있는 선택지는 두가지가 존재했다. 예외를 던진다. null을 반환한다. 하지만 두가지 모두 허점이 존재하게 되는데, 예외는 진짜 예외적인 상황에서만 사용해야 하며, 예외를 생성할 때 스택 추적 전체를 캡처하므로 비용도 만만치 않다. null을 반환하면 이런 문제가 생기지는 않지만, 메서드를 호출 하는 쪽에서 별도의 null 처리 코드를 추가해야하는 문제가 발생한다. 자바가 8버전으로 올라가면서 또 하나의 선택지가 생겼는데 바로 Optional를 사용하는 것이다. Optional은 null이 아닌 T 타입 참조를 하나 담거나, 혹은 아무것도 담지 않을 수 있다. 보통 T를 반환해야 하지만 특정 조건에서는 아무것도 반환하지 않아야 할 때..
깡냉쓰
'프로그래밍 노트/Effective 시리즈' 카테고리의 글 목록