diff --git "a/3. \355\225\250\354\210\230/README.md" "b/3. \355\225\250\354\210\230/README.md"
new file mode 100644
index 0000000..2154b33
--- /dev/null
+++ "b/3. \355\225\250\354\210\230/README.md"
@@ -0,0 +1,405 @@
+# 3장. 함수
+
+함수를 잘 만드는 방법을 소개한다.
+
+## 목차
+
+* [작게 만들어라](#-------)
+* [한 가지만 해라! ← 🌟 함수 당 추상화 수준은 하나로 🌟](#----------------------------------)
+* [Switch 문](#switch--)
+* [서술적인 이름을 사용하라!](#--------------)
+* [함수 인수](#-----)
+ + [인수 1개를 넘기는 경우 3가지](#---1----------3--)
+ + [플래그 인수](#------)
+ + [이항 함수](#-----)
+* [부수 효과를 일으키지 마라!](#---------------)
+ + [출력 인수](#-----)
+* [명령과 조회를 분리하라!](#-------------)
+* [오류 코드보다 예외를 사용하라!](#-----------------)
+ + [오류 코드 의존성](#---------)
+* [반복하지 마라! `DRY: Don’t Repeat Yourself`](#----------dry--don-t-repeat-yourself-)
+ + [DRY를 지키지 않는 예시? 소스코드 복붙?](#dry---------------------)
+ + [중복일까?](#-----)
+ + [중복이 아닐까?](#--------)
+* [함수를 어떻게 짜죠?](#-----------)
+* [결론](#--)
+
+## 작게 만들어라
+
+- 각 함수가 한 가지 일만 하도록 최대한 작게 만들 것.
+ - **줄 수에 집착하기보다 정말로 ‘한 가지’ 일만 하는지**를 생각하는 게 좋을 것 같다.
+- 함수에서 들여쓰기 수준은 1단이나 2단을 넘어서면 안된다. 넘어서야 한다면 함수 이름을 적절하게 짓고 함수를 호출해라.
+
+## 한 가지만 해라! ← 🌟 함수 당 추상화 수준은 하나로 🌟
+
+그래서 그 ‘**한 가지**’의 기준이 뭘까?
+
+추상화 수준이 하나여야 한다는 것.
+
+- 추상화 수준을 섞으면 근본 개념인지 세부사항인지 구분하기 어려워 뒤섞인다. → 최악은 점점 **세부사항이 더 추가**된다는 것!
+
+- 추상화 수준을 유지하기 어렵다면… 위에서 아래로 이야기를 읽어 내려가듯이 코드를 작성하자. 한 함수 다음에는 추상화 수준이 한 단계 낮은 함수가 오는 것. 그리고 각 함수는 한 가지만 한다.
+
+ ```java
+ public class Human {
+ public void spendADay() {
+ spendMorning()
+ spendAfternoon()
+ spendEvening()
+ }
+
+ private void spendMorning() {
+ getUp()
+ takeAShower()
+ eatBreakFast()
+ goToWork()
+ }
+
+ private void getUp() {
+ turnOffAlarm()
+ makingABed()
+ }
+
+ private void takeAShower() {
+ goToBathroom()
+ brushTeeth()
+ turnOnShower()
+ //...
+ }
+
+ //...
+
+ private void spendAfternoon() {
+ //...
+ }
+
+ //...
+ }
+ ```
+
+- 내 함수가 한가지 작업을 하는 지 모르겠다면 생각해보자
+
+ - 함수에서 의미 있는 이름으로 다른 함수를 추출할 수 있다면 여러 작업을 하는 셈
+
+ - 함수를 여러 섹션으로 나눌 수 있다면 여러 작업을 하는 셈
+
+## Switch 문
+
+switch 문은 N가지를 처리하기 때문에 **한가지를 처리하지 않는다**.
+
+하지만 꼭 switch 문을 써야할 때가 있다. 그럴 땐 각 switch 문으로 구분되는 것들을 클래스로 만들고, 각 클래스의 객체를 생성하는 저차원클래스를 만들어 그 부분에만 switch 문을 숨겨라.
+
+함수에 switch 문을 사용했을 때 큰 문제는 해당 함수와 구조가 동일한 함수가 무한정 존재할 수 있다는 것.
+
+- 책 예제 - 추상 팩토리? 추상 팩토리 패턴이라기 보다는 그냥 팩토리 메서드 패턴 같음
+
+switch문 객체 생성 예제
+ [참고](https://yeah.tistory.com/4)
+ - 기본 객체
+
+ ```java
+ abstract class Instrument {
+ String name;
+ Instrument(String name) {
+ this.name = name;
+ }
+ void play();
+ void tune();
+ }
+ ---
+ public class BassGuitar implements Instrument {/*..*/}
+ public class Piano implements Instrument {/*..*/}
+ public class Drum implements Instrument {/*..*/}
+ ```
+
+ - 팩토리 패턴
+
+ ```java
+ public class InstrumentFactory {
+ public Instrument create(InstrumentType type, String name) throws InvalidInstrumentType {
+ switch(type) {
+ case BASS_GUITAR:
+ return new BaseGuitar(name);
+ case PIANO:
+ return new Piano(name);
+ case DRUM:
+ return new Drum(name);
+ default:
+ throw new InvalidInstrumentType(type);
+ }
+ }
+ ```
+
+ - 생성 코드와의 강력한 결합
+
+ - 팩토리 메서드 패턴
+
+ ```java
+ abstract class InstrumentFactory {
+ public final Instrument create(InstrumentType type, String name) {
+ // 하위 클래스로 위임
+ return this.createInstrument(type, name);
+ }
+
+ abstract public Instrument createInstrument(InstrumentType type, String name);
+ }
+ ---
+ public class InstrumentFactoryImpl extends Factory {
+ @Override
+ public Instrument createInstrument(InstrumentType type, String name) {
+ switch(type) {
+ case BASS_GUITAR:
+ return new BaseGuitar(name);
+ case PIANO:
+ return new Piano(name);
+ case DRUM:
+ return new Drum(name);
+ default:
+ throw new InvalidInstrumentType(type);
+ }
+ }
+ }
+ ```
+
+ - 기존 Factory 클래스를 추상 클래스로 적용하여 객체 생산 분리, 구현부 숨겨짐
+
+ - 추상 팩토리 패턴: 생성해야 될 각각의 객체마다 팩토리 생성
+
+ ```java
+ public class BaseGuitarFactory extends InstrumentFactory {
+ @Override
+ public Instrument createInstrument(InstrumentType type, String name) {
+ return new BaseGuitar(name);
+ }
+ }
+ ----
+ public class DrumFactory extends InstrumentFactory {
+ @Override
+ public Instrument createInstrument(InstrumentType type, String name) {
+ return new Drum(name);
+ }
+ }
+ ```
+
+
+## 서술적인 이름을 사용하라!
+
+- 즉 함수가 하는 일을 그대로 표현할 수 있는 이름을 사용해라.
+
+- 함수가 작고 단순할수록 서술적인 이름을 고르기도 쉬워진다.
+ - 이름이 긴 건 상관없지만, 이름이 너무 길고 짓기 어렵다면 **함수가 한가지 일만 하는 게 맞는 지 한 번 생각**해보고, 아니라면 함수를 나눠보자.
+
+- 이름을 붙일 때는 일관성이 있어야 한다. 이름을 보고 나머지 함수도 이렇겠지? 라고 생각하는 대로 동작해야 한다.
+
+## 함수 인수
+
+- 함수의 인수는 적을 수록 이상적이다.
+- 함수의 추상화 수준을 따질 땐 **함수 이름과 인수 사이에 추상화 수준**도 따져봐야 한다. 함수 이름과 인수는 동사/명사 쌍을 이루어서 바로 이해할 수 있어야 한다.
+- 인수가 많으면 테스트할 때도 부담스러워 진다.
+
+### 인수 1개를 넘기는 경우 3가지
+
+1. 질문을 던지는 경우 - 예) 인수로 넘기는 게 존재하니?
+
+2. 인수로 뭔가를 변환해 결과를 반환하는 경우
+
+3. 이벤트 함수
+
+ - 출력 인수는 없지만 입력 인수로 시스템 상태를 바꿈
+
+ - 예)
+
+ ```java
+ passwordAttemptFailedNtimes(int attempts)
+ ```
+
+ - 이벤트라는 사실이 코드에 명확히 드러나야 함. 그러므로 이름과 문맥을 주의해서 선택하자.
+
+ - 🧐 이벤트 함수가 정확히 뭐를 말하는 건지 모르겠는데 위의 예시를 들어보면
+
+ ```java
+ public void passwordAttemptFailedNtime(int attempts) {
+ if (attempts < MAX_PASSWORD_ATTEMPT) {
+ return;
+ }
+ throw new PasswordAttemptFailedException(attempts);
+ }
+ ```
+
+ 이런 식의 함수?
+
+위 세 가지 경우가 아니라면 단항 함수는 피하자.
+
+예를 들어 인수로 뭔가를 변환하고 결과를 반환하지 않는 경우, 즉 인수를 출력 인수로 쓰는 경우 같을 땐 인수를 그대로 돌려주더라고 결과를 반환하자.
+
+또 위 세 가지 경우가 아니라면 피하라는 의미는, **각각의 경우를 한꺼번에 하지 말라는 것**도 포함이다. 즉 한 가지만 할 것.
+
+### 플래그 인수
+
+- 함수로 bool 값을 넘긴다는 것의 의미 == 이 함수는 bool 값에 따라 **여러 가지 일**을 한다고 선포하는 것과 같음.
+- 이럴 땐 bool값에 따른 함수를 여러 개로 나누는 것이 좋다.
+
+### 이항 함수
+
+- 인수가 2개가 오기 위해선 그 인수들 간에 자연스러운 순서가 있어야 한다.
+
+- 만약 그렇지 않은 경우 함수의 이름에 인수를 순서대로 넣어 기억할 필요가 없게 하자.
+
+ ```java
+ assertEquals(expected, actual)
+ // better
+ assertExpectedEqualsActual(expected, actual)
+ ```
+
+- 만약 꼭 이항 함수를 사용해야 할 경우 - 소개된 방법
+
+ - 함수를 한 인수의 클래스의 메서드로 넣어 보자
+ - 한 인수를 현재 클래스의 멤버 변수로 넣어보자
+ - 새 클래스를 만들어 생성자에서 한 인수를 받고 메서드에서 나머지 인수를 받는 식으로 해보자..
+ - 혹은 인수들을 독자적인 클래스 변수로 선언해보자.
+
+- 즉 **맥락을 부여**하자.
+
+ - 2장 의미 있는 이름: 의미 있는 맥락을 추가하라
+
+## 부수 효과를 일으키지 마라!
+
+> side effect: 함수에 의해 함수 외부의 값이 변하는 것
+
+부수 효과를 일으키는 함수의 경우 시간적 결합이나 순서 종속성을 일으킨다.
+
+- 시간적 결합: 특정 상황에서만 호출할 수 있는 함수가 됨
+- 순서 종속성: 반드시 메서드 A가 호출된 다음에야 메서드 B가 호출될 수 있음
+
+만약 꼭 시간적 결합이 필요하다면 함수 이름에 분명히 명시할 것.
+
+### 출력 인수
+
+- 출력 인수는 독자가 코드를 재차 확인하게 만드므로 좋지 않다.
+
+- 객체 지향 언어에서는 출력 인수를 사용할 필요가 거의 없다.
+
+ 출력 인수로 사용하라고 설계한 변수가 `this` 이기 때문
+
+ - 즉 출력 인수를 사용할 상황에 있다면 그 인수 클래스의 메서드로 만들어야 하는 건 아닐 지 생각해보자.
+
+## 명령과 조회를 분리하라!
+
+함수는 뭔가를 수행하거나 답하거나 둘 중 하나만.
+
+**객체 상태를 변경하거나 반환하거나 둘 중 하나만.**
+
+## 오류 코드보다 예외를 사용하라!
+
+오류 코드를 사용할 경우 여러 단계로 중첩될 수 있고 곧바로 오류를 처리해야 한다.
+
+반면 오류 코드 대신 예외를 사용하면 오류 처리 코드를 분리할 수 있다.
+
+- 이 때도 ‘한 가지’만 해야 한다는 걸 기억하자.
+
+ ```java
+ void action() { // 이 함수는 try - catch 블록만 있다.
+ try {
+ 정상_동작();
+ }
+ catch (Exception e) {
+ 오류_처리();
+ }
+ }
+ ```
+
+### 오류 코드 의존성
+
+- 오류 코드를 반환한다는 얘기는 어디선가 오류 코드를 정의한다는 것. **Error Enum으로 정의한다면 해당 enum이 변한다면 enum을 사용하는 클래스 전부를 다시 컴파일하고 배치해야되기 때문에 변경이 어려워진다**.
+
+- 오류 코드 대신 예외를 사용하면 새 예외는 Exception 클래스에서 파생되므로 재컴파일/재배치 없이도 새 예외 클래스를 추가할 수 있다.
+
+- 🧐 여기서 해당 enum이 변한다면 클래스 전부가 모두 변한다는 것의 의미?
+
+ ```java
+ public enum Error {
+ OK,
+ INVALID,
+ NO_SUCH,
+ ...
+ }
+ ```
+
+ - **이펙티브 자바: 자바 enum은 클라이언트 코드를 재컴파일 하지 않고도 상수를 더하거나 순서를 바꿀 수 있음**.
+
+ - int 상수값과 비교한 enum 장점: 공개되는 것이 오직 필드의 이름뿐이라, 정수 열거 패턴과 달리 상수 값이 클라이언트로 컴파일되어 각인되지 않기 때문에 새로운 상수나 순서를 바꾸더라도 클라이언트는 다시 컴파일 필요가 없음
+ - 그럼 어떤 경우에서 재컴파일을 얘기하는 걸까?
+
+ - 하고 찾아봤더니 같은 질문이 있었음: https://stackoverflow.com/questions/38150393/enum-change-vs-adding-new-exception-need-for-recompilation
+
+ > adding another value to the enum requires another compilation for that change to be picked up.
+
+ - 결론
+
+ - 단순히 새로운 값을 추가하거나 순서를 바꾸는 건 재컴파일을 하지 않아도 되는 게 맞음 :o: (하지만 만약 클라이언트 코드에 스위치 문으로 enum을 구분하는 게 있다면 switch문도 수정해야할 것)
+ - 만약 enum의 행동이 바뀌면 재컴파일해야되는 게 맞음. enum에 method가 추가되면 재컴파일 해야한다는 뜻
+ - ∴ 따라서 만약 enum이 정말 '에러 코드들 모음집'으로만 쓰인다면 재컴파일 측면에서 오류 코드와 비교해서 큰 효율성 차이는 없는 것으로 보임. 근데 만약 에러 코드에 따른 추가 메서드(원인 저장하거나, 에러에 따른 다른 행동 제공하거나)가 필요하다면 재컴파일이 필요하니 효율성 차이가 있음
+
+## 반복하지 마라! `DRY: Don’t Repeat Yourself`
+
+같은 알고리즘을 여러 곳에 쓰지 말자.
+
+### DRY를 지키지 않는 예시? 소스코드 복붙?
+
+단순히 소스코드 복붙만이 DRY를 지키지 않는 예시가 아니다. DRY는 **‘지식의 중복, 의도의 중복’**이다. 똑같이 생긴 소스코드라도 지식, 의도가 다르다면 중복이 아니다. 다르게 생긴 코드라도 지식, 의도의 중복이면 중복이다.
+
+### 중복일까?
+
+주문 프로그램에서 연령과 주문 수량을 기록하고 검증하는 기능이 필요하다고 해보자.
+
+연령과 주문수량은 모두 숫자이고, 0보다 커야 한다. 이걸 검증 코드로 작성하면 아래와 같다.
+
+```java
+public void validateAge(String value):
+ validateType(value, Integer.class)
+ validateMinInteger(value, 1)
+
+public void validate_quantity(String value):
+ validateType(value, Integer.class)
+ validateMinInteger(value, 1)
+```
+
+두 함수의 내용이 동일하다. 그럼 DRY 위반일까?
+
+아니다. 코드는 동일하지만 두 함수가 필요하는 지식은 다르다. 두 함수는 각각 서로 다른 것을 검증하고 있지만, 우연히 규칙이 같은 것 뿐이다.
+
+### 중복이 아닐까?
+
+예를 들어 선을 표현하는 클래스가 아래와 같이 있다.
+
+```java
+class Line {
+ Point start;
+ Point end;
+ double length;
+}
+```
+
+이 때 시작점과 끝점이 정해지면 길이도 정해진다. 근데 길이가 또 있다! 그래서 중복이다. 따라서 길이는 계산되는 필드로 만드는 것이 낫다.
+
+```java
+class Line {
+ Point start;
+ Point end;
+ double length() { return start.distanceTo(end); }
+}
+```
+
+> 하지만 개발을 진행하다 보면 성능 상의 이유로 DRY 원칙을 위배할 수도 있다. 비용이 많이 드는 연산을 여러 번 수행하지 않기 위해 데이터를 캐싱할 때 종종 일어난다.
+
+## 함수를 어떻게 짜죠?
+
+글짓기를 하는 것처럼 짜자. 처음엔 함수가 복잡하더라도 일단 그 코드를 테스트하는 단위 테스트 케이스를 만들자. 그리고 계속해서 리팩터링하면서 단위 테스트를 통과하는 걸 확인하자.
+
+처음부터 탁 짜내지 않는다. 그게 가능한 사람은 없다.
+
+## 결론
+
+시스템을 구현할 프로그램이 아니라 풀어갈 이야기로 여기자. 진짜 목표는 시스템이라는 이야기를 풀어나가는 것이다.
+
+함수는 한 가지만 한다. 한 함수 내에서 추상화 수준을 유지하고 높은 것부터 써내려가자. 인수가 많아진다면 해당 인수와 함수간의 관계를 생각해보고 클래스를 생성하거나 멤버 변수로 추가할 지 생각해보자.