개발 공부 기록하기/01. JAVA & Kotlin 38

[코틀린 탐구생활] when, 그리고 클린 코드

when 사실 when expression을 처음 보았을때 들었던 생각은 switch case문과 무척 유사하다는 점이었다. Java에서는 else 사용을 지양해야 한다는 일반적인 clean code 원칙에 따라 switch case 사용도 지양하고 있었는데, Kotlin의 when은 Java의 switch case보다 훨씬 단순하고 강력했다. 비교를 해보자. Kotlin 숫자가 들어오면 숫자를 3으로 나눈 나머지에 따라 적절한 로직을 수행하고 원하지 않는 형태 이면 exception을 뱉어야 한다고 하자. 이를 Early Return 스타일로 표현하면 다음과 같다. (println에 로직이 들어간다고 생각할 수 있다) private fun validateNumber(num: Int) { if (num ..

[코틀린] data class란?

Kotlin data class에 대해서 알아보려고 한다. Java의 data class Car 이라는 객체를 예시로 Step By Step 접근을 해보자 Plain Java Object로 Car를 작성하면 다음과 같다. public class Car { private String name; private int price; } 여기서 Car 인스턴스 필드에 접근하기 위한 getter / setter 를 추가하면 아래와 같다. public class Car { private String name; private int price; public String getName() { return name; } public int price() { return price; } public void setName(..

[코틀린] ?. 연산자, ?: 연산자

코틀린에는 ?. 연산자가 존재한다. 일반적으로 객체지향적인 언어에서 . 연산자는 객체 인스턴스의 필드나 메소드에 접근하는 역할을 수행한다. 코틀린에서는 객체가 null 일 수도 있는 경우를 코드 상 명확히 하기 위해 . 대신 ?. 를 사용해야 한다. Java와 Kotlin으로 몇 가지 예시를 살펴보자 Java 에서의 . 연산자 다음과 같은 코드가 있다고 해보자. public void main() { System.out.println(getCarOrNull().getName()); } public Car getCarOrNull() { if (...) { return null; } return new Car(); } getCarOrNull 코드를 호출하면 조건에 따라 null이 올 수도 Car 인스턴스가 반..

[코틀린] val과 var 차이

Java에서는 새로운 변수를 만들 때 int number = 3; 처럼 [타입] [변수이름] = [할당될 값 또는 인스턴스]가 문법이었다. 하지만 Kotlin에서는 val number1 = 3 var number2 = 3 처럼 Java 문법상 [타입] 자리에 val 또는 var이 들어가게 된다. 둘의 차이는 간단하다. val : 한 번 선언하면 값이 바뀌지 않는다 (JS의 const) var : 한 번 선언한 이후 값을 바꿀 수 있다 (JS의 let) 예를 들어 number1과 number2를 수정했을때 아래와 같이 되는 것이다. number1 = 4 // 에러 number2 = 4 // 통과 Kotlin은 타입을 가고 있어 number1, numbere2에 대한 타입을 자동으로 추론한다 (즉 Int 타..

짧은 코멘트와 함께하는 이펙티브 자바) #20 추상 클래스보다는 인터페이스를 우선하라

짧은코멘트 요약을 잘해서 생략. 추상 클래스보다는 인터페이스를 왜 우선해야 하는지 어떤 경우에는 추상 클래스가 효과적일 수 있는지 잘 제시되어 있다. 추상 클래스보다는 인터페이스를 우선하라 자바가 제공하는 다중 구현 메커니즘은 인터페이스와 추상 클래스 두 가지이다. 둘의 가장 큰 차이는 추상 클래스가 정의한 타입을 구현하는 클래스는 반드시 추상 클래스의 하위 클래스가 되어야 한다는 점이다. 자바는 단일 상속만 지원하니, 추상 클래스 방식은 새로운 타입을 정의하는 데 제약을 안게 되는 셈이다. 인터페이스를 사용하면 장점이 몇 가지 있다. 기존 클래스에도 손쉽게 새로운 인터페이스를 구현해 넣을 수 있다. 인터페이스는 믹스인 정의에 안성맞춤이다. 인터페이스로는 계층구조가 없는 타입 프레임워크를 만들 수 있다...

짧은 코멘트와 함께하는 이펙티브 자바) #19 상속을 고려해 설계하고 문서화하라. 그러지 않았다면 상속을 금지하라

짧은코멘트 Spring 애플리케이션 개발자가 상속을 할 일은 생각보다 많지 않다. 중복되는 필드가 있는 경우 데이터 구조를 표현하기 위한 정도...? 요즘에는 IDE가 원낙 잘 되어 있어 프로젝트에서 사용하는 모든 클래스에 final을 붙일 필요까지는 없는 것 같다. 같은 팀끼리는 의사소통이 잘 되는 측면도 있고... 몇몇 유틸성 클래스에 private constructor를 잘 달아주는 정도면 충분할 것 같다. 상속을 고려한 설계와 문서화 상속용 클래스를 설계하기란 결코 만만치 않다. 상속용 클래스를 만들려면 클래스 내부에서 스스로를 어떻게 사용하는지 (자기 사용 패턴) 모두 문서로 남겨야 한다. 이때 @implSpec 태그를 사용할 수 있다. 상속과 관련되어 문서화한 것은 그 클래스가 사용되는한 반드..

자바 동시성 자료 조사

문득 자바 Thread에 대하여 깊이 있게 알고 싶다는 생각이 들었다. Thread와 관련하여, 가지고 있는 Java 관련 책들이나 JDK docs를 읽으며 간단히 정리해보았다. 혼자 공부하는 자바 스레드가 사용중인 다른 객체를 다른 스레드가 변경할 수 없게 하려면 스레드 작업이 끝날 때까지 객체에 잠금을 걸어서 다른 스레드가 사용할 수 없도록 해야 한다. 임계 영역 : 멀티 스레드 프로그램에서 단 하나의 스레드만 실행할 수 있는 코드 영역 자바는 임계 영역을 지정하기 위해 동기화 메소드를 제공한다. public synchronized void method() { // 임계 영역 : 단 하나의 스레드만 실행 } 동기화 메소드는 메소드 전체 내용이 임계 영역이므로 스레드가 동기화 메소드를 실행하는 즉시 객..

짧은 코멘트와 함께하는 이펙티브 자바) #18 상속보다는 컴포지션을 사용하라

짧은코멘트 회사 블로그에 기고한 글에서도 살짝 이야기 했지만 상속보다는 합성을 사용하는 것이 훨씬 수월하다. 합성에 익숙해지면 어느덧 extends 보다 implements를 선호하게 될 것이다. 상속보다는 합성을 사용하라 일반적인 구체 클래스를 패키지 경계를 넘어 상속하는 일은 위험하다. 메소드 호출과 달리 상속은 캡슐화를 깨뜨린다. 상위 메소드를 부를때 자기 사용 여부에 따라 의도와 다르게 동작할 수 있다. (자기 사용 : 한 클래스의 퍼블릭 인터페이스에서 같은 클래스 내 다른 퍼블릭 인터페이스를 사용하여 기능을 완성한 것) 또한, 상위 클래스의 한 메소드가 상위 클래스의 다른 메소드를 사용하는 자기 사용 여부는 내부 구현 방식에 해당되기 때문에 다음 릴리스에서 유지될지 알 수 없다. 다음 릴리스에서..

짧은 코멘트와 함께하는 이펙티브 자바) #17 변경 가능성을 최소화하라 (불변객체)

짧은코멘트 아래에 언급된 장점들로 인해 불변 객체는 정말 자주 사용되며 final 키워드에 대해서는 잘 알아두면 좋다. class나 method에서도 간혹 사용할 일이 있기 때문이다. 불변 객체의 연산을 예측하는 것 뿐만 아니라 객체 생성이 제한적이라면 내부에 캐싱해두는 것도 성능상 괜찮은 방법이다. 특히 Enum은 자연스럽게 불변 객체가 되는데 name이나 특정 key를 사용해 Enum 찾을 일이 많다면 캐싱이 권장된다. 변경 가능성을 최소화하라 불변 클래스란 그 인스턴스의 내부 값을 수정할 수 없는 클래스이다. 불변 클래스는 가변 클래스보다 설계하고 구현하고 사용하기 쉬우며, 오류가 생길 여지도 적고 훨씬 안전하다. 불변 클래스는 다섯 가지 규칙을 따라야 한다. 객체의 상태를 변경하는 메소드를 제공하..

짧은 코멘트와 함께하는 이펙티브 자바) #16 public 클래스에서는 public 필드가 아닌 접근자 메소드를 사용하라

짧은 코멘트 Effective JAVA에서 가장 짧은 파트가 아닌가 싶다 ㅎㅎ public 클래스에서는 public 필드가 아닌 접근자 메소드를 사용하라 패키지 바깥에서 접근할 수 있는 클래스라면 접근자를 제공해라 package-private 클래스 혹은 private 중첩 클래스라면 데이터 필드를 노출한다 해도 하등의 문제가 없다.