-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
docs : 최준 이펙티브 자바 item 51 정리본 추가 (#108)
- Loading branch information
Showing
2 changed files
with
284 additions
and
0 deletions.
There are no files selected for viewing
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,284 @@ | ||
# 5️⃣1️⃣ Item 51 : 메서드 시그니처를 신중히 설계하라 | ||
|
||
<br> | ||
|
||
## 📌 목차 | ||
1. API 설계 요령 | ||
2. 1.메서드 이름을 신중히 짓자. | ||
3. 2.편의 메서드를 너무 많이 만들지 말자. | ||
4. 3.매개변수 목록은 짧게 유지하자. | ||
5. 매개변수 목록 줄이는 기술 | ||
6. 4.매개변수 타입으로는 클래스보다는 인터페이스가 더 낫다. | ||
7. 5.boolean보다는 원소 2개짜리 열거 타입이 낫다. | ||
8. 결론 | ||
|
||
<br> | ||
|
||
## 🏗 API 설계 요령 | ||
|
||
`API 설계 요령`들을 보자. | ||
|
||
이 요령들을 잘 활용하면 아래와 같은 `장점`들을 얻을 수 있다. | ||
|
||
- `배우기 쉬운` API 만들 수 있다. | ||
- `쓰기 쉬운` API 만들 수 있다. | ||
- `오류 가능성이 적은` API 만들 수 있다. | ||
|
||
<br> | ||
|
||
## 1️⃣ 1. 메서드 이름을 신중히 짓자. | ||
|
||
첫번째 API 설계 요령은 `‘메서드 이름을 신중히 짓자’`이다. | ||
|
||
<br> | ||
|
||
메서드 이름을 지을 때에는 아래를 참고해서 해야 한다. | ||
|
||
1. 항상 `표준 명명 규칙`을 따라야 한다. | ||
2. `이해할 수 있는` 메서드 이름을 지어야 한다. | ||
3. 같은 패키지에 속한 다른 이름들과 `일관되게` 지어야 한다. | ||
4. `개발자 커뮤니티`에서 널리 받아들여지는 이름 사용해야 한다. | ||
5. `긴 메서드 이름`은 피해야 한다. | ||
6. 애매하면 `자바 라이브러리의 API 가이드` 참조해 지어야 한다. | ||
|
||
<br> | ||
|
||
## 2️⃣ 2. 편의 메서드를 너무 많이 만들지 말자. | ||
|
||
두번째 API 설계 요령은 `‘편의 메서드를 너무 많이 만들지 말자’`이다. | ||
|
||
<br> | ||
|
||
편의 메서드는 `자주 사용되는 기능 or 반복되는 코드 블록 모듈화 해 재사용 가능하게 만든 메서드`다. | ||
|
||
편의 메서드는 다음과 같은 `장점`이 있다. | ||
|
||
1. 코드의 `재사용성`을 높인다. | ||
2. 코드의 `가독성을 향상`시킨다. | ||
3. `버그 발생 확률을 줄이는 데` 도움이 된다. | ||
|
||
<br> | ||
|
||
하지만 `메서드가 너무 많은` 클래스, 인터페이스는 다음과 같은 문제점이 있다. | ||
|
||
1. `익히기` 어렵다. | ||
2. `사용하기` 어렵다. | ||
3. `문서화하기` 어렵다. | ||
4. `테스트하기` 어렵다. | ||
5. `유지보수하기` 어렵다. | ||
6. 구현하는 사람, 사용하는 사람 `모두 어렵게 한다`. | ||
|
||
<br> | ||
|
||
따라서 클래스나 인터페이스는 자신의 `각 기능을 완벽히 수행`하는 메서드로 제공해야 한다. | ||
|
||
아주 `자주 쓰이는 메서드의 경우`에만 별도의 약칭 메서드로 두자. | ||
|
||
<br> | ||
|
||
## 3️⃣ 3. 매개변수 목록은 짧게 유지하자. | ||
|
||
세번쨰 API 설계 요령은 `‘매개변수 목록은 짧게 유지하자’`이다. | ||
|
||
<br> | ||
|
||
매개변수는 `4개 이하가 좋다`고 한다. | ||
|
||
5개부터는 매개변수를 `전부 기억하기 쉽지 않다`. | ||
|
||
<br> | ||
|
||
매개변수가 많은 메서드가 많으면 아래와 같은 `문제`가 생긴다. | ||
|
||
1. `API 문서를 가지고 보면서` 개발해야 한다. | ||
2. `IDE를 사용하면 수고를 덜 수 있지만` 여전히 쉽지 않다. | ||
|
||
<br> | ||
|
||
`같은 타입의 매개변수 여러 개` 연달아 나오는 경우 더 문제가 많아진다. | ||
|
||
1. 사용자가 매개변수 `순서를 기억하기 어렵다`. | ||
2. 실수로 순서 바꿔 입력해도 그대로 컴파일되고 `실행되어 의도와 다르게 동작`한다. | ||
|
||
<br> | ||
|
||
### 🔨 매개변수 목록 줄이는 기술 | ||
|
||
긴 매개변수 목록을 짧게 줄여주는 기술 `3가지`를 보자. | ||
|
||
<br> | ||
|
||
**첫번째 기술** | ||
|
||
첫번째 기술은 `여러 메서드로 쪼개는 것`이다. | ||
|
||
하나의 매개변수 목록을 여러 메서드로 나누는 것이다. | ||
|
||
이렇게 하면 메서드가 너무 많아질 것 같다. | ||
|
||
<br> | ||
|
||
그러나 이렇게 메서드를 나누면 `직교성이 높아진다`. | ||
|
||
직교성이 높아진다 = `공통점 없는 기능들이 잘 분리`되어 오히려 메서드 수를 줄여주는 효과가 있다. | ||
|
||
API는 기본 기능만 잘 갖춰 놓으면 아무리 `복잡한 기능도 조합`할 수 있다. | ||
|
||
그래서 공통점 없이 기능들을 잘 분리해 놓으면 `자연스럽게 중복이 줄고 결합성이 낮아진다`. | ||
|
||
이렇게 하면 코드를 수정하거나 테스트하기 쉬워진다. | ||
|
||
그래서 직교성이 높은 설계는 가볍고 구현하기 쉽고 유연하고 강력하다고 한다. | ||
|
||
<br> | ||
|
||
**두번째 기술** | ||
|
||
두번째 기술은 `매개변수 여러 개를 묶어주는 도우미 클래스`를 만드는 것이다. | ||
|
||
이런 도우미 클래스는 일반적으로 `정적 멤버 클래스`로 둔다. | ||
|
||
`매개변수 몇 개를 독립된 하나의 개념`으로 볼 수 있을 때 추천하는 기법이다. | ||
|
||
<br> | ||
|
||
아래와 같은 순서로 진행하는 것이다. | ||
|
||
1. 매개변수를 묶는 도우미 클래스를 만든다. | ||
2. 메서드의 매개변수를 이 하나의 도우미 클래스로 주고 받는다. | ||
3. API, 클래스 내부 구현이 깔끔해진다. | ||
|
||
<br> | ||
|
||
```java | ||
public class CardGame{ | ||
public void game(int rank, String suit){ | ||
~~ | ||
} | ||
} | ||
|
||
-> | ||
|
||
public class CardGame{ | ||
public static class CardType{ | ||
private int rank; | ||
private String suit; | ||
... | ||
} | ||
|
||
public void game(CardGame cardGame){ | ||
~~ | ||
} | ||
} | ||
``` | ||
|
||
<br> | ||
|
||
**세번째 기술** | ||
|
||
세번째 기술은 객체 생성에 사용한 `빌더 패턴을 메서드 호출에 응용`하는 것이다. | ||
|
||
앞의 두 기술을 혼합한 것이다. | ||
|
||
이 기술은 매개변수가 많은데 `그중 일부는 생략해도 괜찮을 때` 도움이 된다. | ||
|
||
<br> | ||
|
||
이것은 다음과 같은 순서를 따라 진행하면 된다. | ||
|
||
1. 모든 매개변수를 하나로 `추상화한 객체를 정의`한다. | ||
2. 이 객체에 각 매개변수 하나 or 연관된 몇 개에 관한 `setter 메서드를 정의`한다. | ||
3. 클라이언트는 객체의 setter 메서드로 필요한 `매개변수를 설정`한다. | ||
4. execute 메서드를 호출해 설정한 `매개변수들의 유효성을 검사`한다. | ||
5. `객체를 메서드로` 넘긴다. | ||
|
||
<br> | ||
|
||
따라서 매개변수 목록 줄이는 기술을 정리하면 아래와 같다. | ||
|
||
1. 여러 메서드로 쪼개자. | ||
2. 매개변수 여러 개를 묶어주는 도우미 클래스를 만들자. | ||
3. 객체 생성에 사용한 빌더 패턴을 메서드 호출에 응용하자. | ||
|
||
<br> | ||
|
||
## 4️⃣ 4. 매개변수 타입으로는 클래스보다는 인터페이스가 더 낫다. | ||
|
||
네번째 API 설계 요령은 `‘매개변수 타입으로는 클래스보다는 인터페이스가 더 낫다’` 이다. | ||
|
||
<br> | ||
|
||
매개변수 타입을 인터페이스로 하는 이유는 아래와 같다. | ||
|
||
1. `어떤 인터페이스의 구현체도` 파라미터로 건넬 수 있다. | ||
2. `아직 존재하지 않는 구현체도` 파라미터로 건넬 수 있다. | ||
|
||
<br> | ||
|
||
인터페이스 대신 클래스를 사용하면 아래와 같은 `단점`이 있다. | ||
|
||
1. 클라이언트에게 `특정 구현체만 사용하도록 제한`하게 된다. | ||
2. 입력 데이터가 다른 형태로 존재하면 특정 구현체 객체로 옮겨 담느라 `비싼 복사 비용 생긴다`. | ||
|
||
<br> | ||
|
||
## 5️⃣ 5. boolean보다는 원소 2개짜리 열거 타입이 낫다. | ||
|
||
다섯번째 API 설계 요령은 `‘boolean보다는 원소 2개짜리 열거 타입이 낫다’` 이다. | ||
|
||
<br> | ||
|
||
열거 타입을 사용하면 `장점`은 아래와 같다. | ||
|
||
1. 코드를 `읽고 쓰기가 더 쉬워진다`. | ||
2. 하는 일을 훨씬 `명확히 알려준다`. | ||
3. 나중에 `선택지를 추가하기도 쉽다`. | ||
4. 새로운 타입을 지원해야 한다면 다른 정적 메서드 추가할 필요 없이 `열거 타입에 추가`하면 된다. | ||
5. 의존성을 개별 `열거 타입 상수의 메서드 안으로 리팩터링해 넣을 수도 있다`. | ||
|
||
<br> | ||
|
||
예시로 Thermometer라는 온도계 클래스를 보자. | ||
|
||
온도계 클래스의 정적 팩터리 메서드가 있는데 `섭씨 온도와 화씨 온도를 구분하기 위해 매개변수로 true, false`를 넘기는 것이다. | ||
|
||
```java | ||
Thermometer.newInstance(true); -> 섭씨 | ||
Thermometer.newInstance(false); -> 화씨 | ||
``` | ||
|
||
<br> | ||
|
||
이렇게 사용하는 것보다는 열거 타입을 만들어 사용하는 것이 좋다는 것이다. | ||
|
||
이렇게 하면 `코드를 읽고 쓰고 더 쉬워지고 하는 일이 더 명확히 보인다`. | ||
|
||
```java | ||
public enum TemperatureScale{ FAHRENHEIT, CELSIUS } | ||
|
||
Thermometer.newInstance(TemperatureSclae.CELSIUS); -> 섭씨 | ||
Thermometer.newInstance(TemperatureSclae.FAHRENHEIT); -> 화씨 | ||
``` | ||
|
||
<br> | ||
|
||
나중에 켈빈 온도를 지원해야 한다면 Thermometer 클래스에 정적 메서드 추가할 필요 없이 `열거 타입에 추가하면 된다`. | ||
|
||
`선택지를 추가하는데 더 쉬워진 것이다`. | ||
|
||
```java | ||
Thermometer.newKelvinInstance(); (X) | ||
public enum TemperatureScale{ FAHRENHEIT, CELSIUS, KELVIN } (O) | ||
``` | ||
|
||
<br> | ||
|
||
## ‼ 결론 | ||
|
||
API 설계 요령 `5가지`를 정리하면 아래와 같다. | ||
|
||
1. 메서드 이름을 신중히 짓자. | ||
2. 편의 메서드를 너무 많이 만들지 말자. | ||
3. 매개변수 목록은 짧게 유지하자. | ||
4. 매개변수 타입으로는 클래스보다는 인터페이스가 더 낫다. | ||
5. boolean보다는 원소 2개짜리 열거 타입이 낫다. |