예전에는 자바에서 함수 타입을 표현할 때 추상 메서드를 하나만 담은 인터페이스(드물게는 추상 클래스)를 사용했습니다. 이런 인터페이스의 인스턴스를 함수 객체라고 하여, 특정 함수나 동작을 나타내는데 썼습니다. 1997년 JDK 1.1이 등장하면서 함수 객체를 만드는 주요 수단은 익명 클래스(아이템 24)가 되었습니다. 다음 코드를 예로 살펴봅시다. 문자열을 길이순으로 정렬하는데, 정렬을 위한 비교 함수로 익명 클래스를 사용합니다. Collections.sort(words, new Comparator() { public int compare(String s1, String s2) { return Integer.compare(s1.length(), s2.length()); } }); 전략(Strategy) ..
아무 메서드도 담고 있지 않고, 단지 자신을 구현하는 클래스가 특정 속성을 가짐을 표시해주는 인터페이스를 마커 인터페이스(marker interface)라고 합니다. Serializable 인터페이스가 좋은 예입니다. Serializable은 자신을 구현한 클래스의 인스턴스는 ObjectOutputStream을 통해 쓸(write) 수 있다고, 즉 직렬화할 수 있다고 알려줍니다. 마커 애너테이션(아이템 39)이 등장하면서 마커 인터페이스는 구식이 되었다는 이야기가 있습니다. 하지만 이것은 사실이 아니며 마커 인터페이스는 두 가지 면에서 마커 애너테이션보다 낫습니다. [1]. 마커 인터페이스는 이를 구현한 클래스의 인스턴스들을 구분하는 타입으로 쓸 수 있다. 마커 인터페이스는 어엿한 타입이기 때문에, 마커..
자바가 기본으로 제공하는 애너테이션 중 보통의 프로그래머에게 가장 중요한 것은 @Override일 것입니다. @Override는 메서드 선언에만 달 수 있으며, 이 애너테이션이 달렸다는 것은 상위 타입의 메서드를 재정의했음을 뜻합니다. 이 애너테이션을 일관되게 사용하면 여러 가지 악명 높은 버그들을 예방해줍니다. 다음의 Bigram 프로그램을 살펴봅시다. 이 클래스는 바이그램, 즉 여기서는 영어 알파벳 2개로 구성된 문자열을 표현합니다. public class Bigram { private final char first; private final char second; public Bigram(char first, char second) { this.first = first; this.second = s..
전통적으로 도구나 프레임워크가 특별히 다뤄야 할 프로그램 요소에는 딱 구분되는 명명 패턴을 적용해왔습니다. 예컨대 테스트 프레임워크인 JUnit은 버전 3까지 테스트 메서드 이름을 test로 시작하게끔 했습니다. 효과적인 방법이지만 단점도 큽니다. [1]. 오타가 나면 안 된다. 실수로 이름을 tsetSafetyOverride로 지으면 JUnit 3은 이 메서드를 무시하고 지나치기 때문에 개발자는 이 테스트가 통과했다고 오해할 수 있습니다. [2]. 올바른 프로그램 요소에서만 사용되리라 보증할 방법이 없다는 것이다. 예컨대 (메서드가 아닌) 클래스 이름을 TestSafetyMechanisms로 지어 JUnit에 던져줬다고 해봅시다. 개발자는 이 클래스에 정의된 테스트 메서드들을 수행해주길 기대하겠지만 J..
열거 타입은 거의 모든 상황에서 타입 안전 열거 패턴보다 우수합니다. 단, 예외가 하나 있으니, 타입 안전 열거 패턴은 확장할 수 있으나 열거 타입은 그럴 수 없다는 점입니다. 달리 말하면, 타입 안전 열거 패턴은 열거한 값들을 그대로 가져온 다음 값을 더 추 가하여 다른 목적으로 쓸 수 있는 반면, 열거 타입은 그렇게 할 수 없다는 뜻입니다. 실수로 이렇게 설계한 것은 아닙니다. 사실 대부분 상황에서 열거 타입을 확장하는 건 좋지 않은 생각입니다. 기반 타입과 확장된 타입들의 원소 모두를 순회할 방법도 마땅치 않습니다. 마지막으로, 확장성을 높이려면 고려할 요소가 늘어나 설계와 구현이 더 복잡해집니다. 그런데 확장할 수 있는 열거 타입이 어울리는 쓰임이 최소한 하는 있습니다. 바로 연산 코드(opera..
이따금 배열이나 리스트에서 원소를 꺼낼 때 ordinal 메서드(아이템 35)로 인덱스를 얻는 코드가 있습니다. 식물을 간단히 나타낸 다음 클래스를 예로 살펴봅시다. class Plant { enum LifeCycle { ANNUAL, PERENNIAL, BIENNIAL } final String name; final LifeCycle lifeCycle; Plant(String name, LifeCycle lifeCycle) { this.name = name; this.lifeCycle = lifeCycle; } @Oveeride public String toString() { return name; } } 이제 정원에 심은 식물들을 배열 하나로 관리하고, 이들을 생애주기별로 묶어봅시다. 생애주기별로 총..
대부분의 열거 타입 상수는 자연스럽게 하나의 정숫값에 대응됩니다. 그리고 모든 열거 타입은 해당 상수가 그 열거 타입에서 몇 번째 위치인지를 반환하는 ordinal이라는 메서드를 제공합니다. 이런 이유로 열거 타입 상수와 연결된 정숫값이 필요하면 ordinal 메서드를 이용하고 싶은 욕구에 빠집니다. 다음 코드는 합주단의 종류를 연주자가 1명인 솔로부터 10명까지 정의한 열거 타입입니다. public enum Ensemble { SOLO, DUET, TRIO, QUARTET, QUINTET, SEXTET, SEPTET, OCTET, NONET, DECTET; public int numberOfMusicians() { return oridnal() + 1; } } 동작은 하지만 유지보수하기가 끔찍한 코드입..
- Total
- Today
- Yesterday
- Algorithm
- 테라폼
- JPA
- 백준
- C++
- AWS
- Olympiad
- 코테
- 이펙티브 자바
- 이팩티브 자바
- BAEKJOON
- Kotlin
- BOJ
- kkoon9
- 정규표현식
- 클린 코드
- programmers
- MSA
- 디자인패턴
- 클린 아키텍처
- Java
- Effective Java
- node.js
- kotest
- 디자인 패턴
- Spring Boot
- Spring
- 프로그래머스
- 객체지향
- 알고리즘
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |