전체 글 175

[Kotlin] 애노테이션 - 1 (적용과 사용 지점 대상)

오랜만에 Kotlin in Action 책을 다시 부수기로 했다. 우테코 첫 방학이기 때문! 이제 kotlin in action 의 10장 애노테이션과 리플렉션, 11장 DSL 만들기를 보면, Kotlin in Action 의 1, 2부를 모두 보게 된다. 애노테이션을 사용하면 라이브러리가 요구하는 의미를 클래스에게 부여할 수 있다. 코틀린에서 애노테이션을 사용하는 문법은 자바와 똑같지만, 애노테이션을 선언할 때 사용하는 문법은 자바와 약간 다르다. 애노테이션 선언 & 적용 메타데이터를 선언에 추가하면 애노테이션 프로세서가 컴파일 타임/ 런타임에 적절한 처리를 해준다. 메타데이터가 뭔데? 메타데이터(metadata)는 데이터에 대한 데이터라는 의미를 가지며, 특정 정보의 구조, 내용, 관계 등을 설명하는..

Kotlin 2024.04.10

[Kotlin] SAM 을 익명 객체 VS 람다로 구현 & fun interface (feat. 우테코)

블랙잭 미션을 진행하면서, 크루원 중 한명이 SAM 인터페이스와 코틀린 fun interface 를 잘 모르겠다고 했다. 나도 코드에 이것을 잘 사용하는 것이 항상 어려웠다. 그래서 다시 공부해서 스터디 시간에 발표하려고 한다. 먼저 익명 객체와 람다부터 알아보자. 익명 객체(Anonymous Object) 코틀린에서 익명 객체(anonymous objects)는 객체 지향 프로그래밍에서 유용한 개념 중 하나이다. 익명 객체는 이름이 없는 클래스 인스턴스를 만들어내는 방법으로, 주로 인터페이스나 추상 클래스의 인스턴스를 만들 때 사용된다. 코틀린에서는 익명 객체를 선언하고 초기화하는 방법이 간단하고 직관적이다. 코틀린 vs 자바 에서 익명 객체 구현 코틀린에서 익명 객체 구현 val thread = Th..

Kotlin 2024.03.22

의인화 & 정보 전문가 패턴 & 리팩터링 _feat(우테코 - 로또)

우테코 2단계 level 2 로또 미션 중에 나는 매우 재미있는 경험을 했다. 이전에는 책에서 봤던 이론적인 내용을 말로는 표현할 수 있었지만, 나의 코드로는 적용하기가 어려웠다. 나는 무언가를 안다는 것은 아래 세가지 단계로 나뉜다고 생각한다. (내 생각이 아니라, 어디서 봤던 것 같기도 하고...) 개념을 알고 설명한다. 그 개념을 똑같이 사용할 수 있다. 그 개념을 다르게 활용할 수 있다. 나는 책에서 보았던 내용을 1단계 정도밖에 알지 못하는 것 같았다. 내가 읽었던 책은 조영호 저자의 객사오('객체지향의 사실과 오해') 와, '오브젝트 - 코드로 이해하는 객체지향 설계', 그리고 마틴 파울러 저자의 '리팩터링 2판' 이다. 의인화 - 객사오 이 책의 66, 67 페이지에서는 아래와 같은 내용이 ..

[Kotlin] 방어적 복사와 깊은 복사, 얕은 복사 (feat. 우테코)

Mutablility(가변성)과 방어적 복사, 혹은 방어적 프로그래밍은 공부할 때 봤던 코틀린 인 액션 책에 "6.3.2 읽기 전용과 변경 가능한 컬렉션"에서 잠깐 다룬다.(이 글에서도) 하지만 뭔가 부족한 느낌이 있었는데, 마침 우테코 수업에서 이 내용을 다루었다!! 모든 코드는 Kotlin 으로 작성된다. 얕은 복사(Shallow copy)와 깊은 복사(Deep Copy), 그리고 방어적 복사(Defensive Copy) 순서로 공부해보자. 얕은 복사(Shallow copy) & 깊은 복사(Deep copy) 먼저 방어적 복사 이전에 얕은 복사와 깊은 복사를 알아야 한다. 얕은 복사(Shallow copy) 얕은 복사: 객체의 주솟값을 복사한다. 복사된 객체의 인스턴스는 원본 객체의 인스턴스와 같은 ..

Kotlin 2024.03.08

디자인 패턴 - 전략 패턴(Strategy pattern)과 디자인 패턴에 대한 고찰_feat(우테코 - 자동차 경주)

우테코 1단계 level 1 의 자동차 경주 미션 리팩토링을 진행하고, 미션 리뷰어에게 전략 패턴에 대한 이야기를 들었다. 나는 사실 전략 패턴에 대해 잘 알지 못했다. 그런데 전략 패턴을 이미 구현했다는 피드백을 보고 신기함을 느꼈다. 어떻게 제대로 모르는 것을 구현할 수 있지? 이 궁금증을 시작으로 전략 패턴을 더 자세히 공부하기로 했다. 전략 패턴(Strategy Pattern)? '알렉산더 슈베츠' 저자의 '디자인 패턴에 뛰어들기' 라는 책에서는 이렇게 설명하고 있다. (이 글은 위 링크 글을 보고 공부하여 정리한 내용으로 원문을 참조하시는 것을 추천한다.) 전략 패턴은 알고리즘들의 패밀리를 정의하고, 각 패밀리를 별도의 클래스에 넣은 후 그들의 객체들을 상호교환할 수 있도록 하는 행동 디자인 패..

코드의 네이밍과 코딩 컨벤션은 왜 중요한가?

우테코 수업을 듣다가 코드에서 효과적인 네이밍이 왜 중요한가? 라는 질문을 들었다. 효과적인 네이밍은 왜 중요한가? 모두들 흔히 좋은 네이밍으로써 코드의 가독성과 이해도를 향상시키고 유지보수성을 높이는데 도움이 된다고 말한다. 하지만 이것에 대해 다시 왜? 냐고 물으면 쉽게 입이 떼어지지 않았다. 좋은 네이밍이 중요한 이유 Eddy 님의 글에서는 아래처럼 말한다. 프로그래밍은 문제 해결이 전부가 아니다. 프로그래밍은 다른 사람과의 커뮤니케이션이고 협업이다. 내가 만든 코드를 읽는 것은 컴퓨터 뿐만이 아니라 '다른 프로그래머들'이, 그들과 다를 바 없는 '미래의 나' 이다. 그래서 코드는 그 사람들에게 이 프로그램이 어떤 동작을 하는지(어떤 책임을 갖는지)를 명료하게 전달해야 한다. 또 우테코 코치 제이슨..

[Kotlin] variance(변성), in, out, covariant, contravariant, invariant

Kotlin in Action 을 공부하고 Effective kotlin 의 내용을 조금 참조하여 정리한 글입니다. variance(변성) 개념은 `List` 와 `List` 와 같이 Base 타입이 같고, 타입 인자가 다른 타입들이 서로 어떤 관계가 있는지 설명하는 개념이다. 변성: 인자를 함수에 넘기기 `List` 타입의 파라미터를 받는 함수에 `List` 을 넘기면 안전할까? fun printContents(list: List) { println(list.joinToString()) } printContents(listOf("abc", "bac")) /* abc, bac */ 이 경우에는 `List` 을 사용해도 잘 작동한다. 위 함수는 각 원소를 `Any` 로 취급하며 모든 `String` 은 `..

Kotlin 2024.02.06

[Kotlin] 런타임 시 제네릭의 동작: 타입 소거(Type erasure), reified 타입 파라미터

Kotlin in Action 을 공부하고 Effective kotlin 의 내용을 조금 참조하여 정리한 글입니다. 런타임의 제네릭: 타입 소거(type erasure) 자바와 마찬가지로 코틀린 제네릭 타입 인자 정보는 런타임에 지워진다. 제네릭 인스턴스가 생성될 때 쓰인 타입 인자에 대한 정보를 유지하지 않는다. 예를 들어 `List` 객체를 만들더라도, 런타임에는 그 객체를 오직 `List` 로만 볼 수 있다. 즉, 그 `List` 객체가 어떤 타입의 원소를 저장하는지 런타임에는 알 수 없다. 이를 타입 소거 (type erasure) 라고 한다. 런타임에 둘은 완전히 같은 타입의 객체이다. 하지만 컴파일러가 타입 인자를 알고 올바른 타입의 값만 각 리스트에 넣도록 보장해주기 때문에 `List` 에..

Kotlin 2024.01.31

[Kotlin] 제네릭 타입 파라미터(Generic Type Parameter)

Kotlin in Action 을 공부하고 Effective kotlin 의 내용을 조금 참조하여 정리한 글입니다. 제네릭 타입 파라미터 제네릭스를 사용하면 타입 파라미터(type parameter)를 받는 타입을 정의할 수 있다. 제네릭 타입의 인스턴스를 만드려면 타입 파라미터를 구체적인 타입 인자(type argument)로 치환해야 한다. 예를 들어 코틀린의 `List` 는 `List` 로 되어 있다. 이에 대한 인스턴스를 만들 때는 `List` 의 모습으로 구체적인 타입 인자를 지정하여 사용한다. 타입 파라미터는 여러 개가 될 수도 있다. 예를 들어 코틀린의 `Map` 은 `Map` 이다. 이런 제네릭 클래스는 `Map` 처럼 구체적인 타입 인자를 지정하여 인스턴스화한다. 코틀린 컴파일러는 보통 ..

Kotlin 2024.01.31

[Kotlin] 고차 함수 안에서 흐름 제어

Kotlin in Action 을 공부하고 Effective kotlin 의 내용을 조금 참조하여 정리한 글입니다. filter 와 함께 람다 안에서 return 을 사용하는 등의 예제를 살펴보자. 람다 안의 return 문: 람다를 둘러싼 함수로부터 리턴(non-local return) 일반 루프 안에서 `return` 사용하기 data class Person(val name: String, val age: Int) fun lookForAlice(people: List) { for (person in people) { if (person.name == "Alice") { println("Found!") return } } println("Alice is not found") } val people = ..

Kotlin 2024.01.30