generated from muhandojeon/study-template
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* 5장 * Update 변수미.md
- Loading branch information
Showing
1 changed file
with
183 additions
and
0 deletions.
There are no files selected for viewing
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,183 @@ | ||
삶은 멈추지 않는다. 우리가 작성하는 코드도 마찬가지다. | ||
현대의 미친 듯이 빠른 변화 속도를 따라가려면 모든 수단을 동원하여 가능한 한 느슨하고 유연한 코드를 작성해야 한다. | ||
|
||
코드가 불확실한 세상에 서도 유연성과 적응력을 잃지 않을 방법에 대해 이야기한다 | ||
(되돌릴 수 있는 의사 결정을 내리는 구체적인 방법) | ||
|
||
## Topic 28 결합도 줄이기 | ||
|
||
소프트웨어의 구조는 유연해야 한다. 그리고 유연하려면 각각의 부품이 다른 부품에 가능한 한 조금만 연결되어야 한다. | ||
|
||
결합은 두 개의 코드 조각이 무언가를 공유 하면 언제나 일어날 수 있다 | ||
-> 결합도가 낮은코드가 바꾸기 쉽다. | ||
|
||
### 열차 사고 | ||
|
||
열차의 모든 객차가 서로 연결되어 있듯이 메서드나 속성들이 모두 연결되어있는 코드를 `열차 사고`라고 부른다. | ||
|
||
`열차 사고`가 일어난 코드를 고치려면 `묻지 말고 말하라 (TDA)`라는 원칙을 적용해야한다. | ||
|
||
#### **묻지 말고 말하라 (TDA)** | ||
|
||
다른 객체의 내부 상태에 따라 판단을 내리고 그 객체를 갱신해선 안된다. | ||
|
||
- 객체 내부 상태를 물어 캡슐화의 장점이 없어진다. | ||
처리 자체를 해당 객체에 위임해야한다. | ||
|
||
![image](https://github.com/user-attachments/assets/95bbcc43-1169-4e0c-abb9-0130072af386) | ||
|
||
|
||
왼쪽 객체는 단순히 무언가를 해달라고 말만(Tell) 하면 되고, | ||
그 Tell 은 곧 명령이 되어 우측 객체에서 로직과 데이터가 캡슐화 되어 처리한다. | ||
|
||
- 데이터와 행동을 하나의 객체로 엮어 시스템의 기본 동작들을 연결해 동작하게 만드는 것 | ||
- 데이터와 로직은 서로 밀접하게 연관되어 있고 | ||
- 밀접하게 연관된 것들은 같은 구성요소 안에 있어야 한다. | ||
|
||
### 데메테르 법칙 (LoD) | ||
|
||
데메테르라는 프로젝트를 수행하는 도중 개발자들에게 보다 깨끗하고 결합도가 낮은 함수를 작성하는 방법을 알려주기 위해 만들었다. | ||
|
||
#### 메서드 호출을 엮지 말라. | ||
|
||
무언가에 접근할 때 “.”을 딱 하나만 쓰려고 노력해 보라. | ||
|
||
```ts | ||
# 좋지 않은 방식이다. | ||
amount = customer.orders.last().totals().amount; | ||
``` | ||
|
||
#### 전역 데이터를 피해라 | ||
|
||
어디서나 접근할 수 있는 데이터는 교묘하게 애플리케이션 컴포넌트 간의 결합을 만들어 낸다. | ||
전역 데이터 하나하나는 애플리케이션의 모든 메서드에 갑자기 매개 변수가 추가된 것과 같은 효과를 낸다 | ||
|
||
fyi | ||
|
||
- 싱글턴도 전역데이터다 | ||
- 외부 리소스도 전역 데이터이다. | ||
|
||
#### 결국은 모두 ETC | ||
|
||
직접적으로 아는 것만 다루는 부끄럼쟁이 코드를 계속 유지하라. | ||
그러면 애플리케이션의 결합도를 낮게 유지할 수 있을 것이고, 결과적으로 코드를 바꾸기 쉬워질 것이다. | ||
|
||
## Topic 29 실세계를 갖고 저글링하기 | ||
|
||
### 이벤트 | ||
|
||
> 이벤트는 무언가 정보가 있다는 것을 | ||
어디에서 온 것이든 애플리케이션을 이런 이벤트에 반응하도록, 그리고 그에 기반해서 하는 일을 조절하도록 만들면, 진짜 세상에서 더 잘 작동하는 애 플리케이션이 탄생할 것이다. | ||
|
||
그러면 어떻게 이벤트에 잘 반응하는 애플리케이션을 만들 수 있을까? | ||
|
||
1. 유한상태 기계 | ||
2. 감시자observer 패턴 | ||
3. 게시-구독 | ||
4. 반웅형프로그래밍과 스트림 | ||
|
||
### 유한 상태 기계 | ||
|
||
상태 기계는 이벤트를 어떻게 처리할지 정의한 명세일 뿐이다. | ||
|
||
정해진 상태들이 있고 그중 하나가 ‘현재 상태’다. 상태마다 그 상태일 때 의미가 있는 이벤트들을 나열하고, 이벤트별로 시스템의 다음 ‘현재 상태’를 정의한다. | ||
|
||
### 감시자 패턴 (observer pattern) | ||
|
||
- 감시 대상 : 이벤트를 발생시키는 쪽 | ||
- 감시자 : 이벤트에 관심이 있는 클라이언트 | ||
|
||
특히 감시자 패턴은 사용자 인터페이스 시스템에서 널리 쓰이는데, 어떤 상호 작용이 일어났다는 것을 애플리케이션에 콜백으로 알려주는 방식을 사용한다. | ||
|
||
#### 감시자 패턴의 문제 | ||
|
||
모든 감시자가 감시 대상에 등 록을 해야 하기 때문에 결합이 생긴다. | ||
또한, 일반적으로 감시 대상이 콜백을 직접 호출하도록 구현하기 때문에 이 부분이 성능 병목이 될 수 있다. (동기적처리의 특성상 콜백 실행이 끝날 때까지 감시 대상이 계속 기다려야하기 때문) | ||
|
||
### 게시-구독 | ||
|
||
감시자 패턴을 일반화한 것으로, 동시에 감시자 모델의 결합도를 높이 는 문제와 성능 문제도 해결 | ||
|
||
- 게시자 : 채널에 이벤트를 보내는 쪽 | ||
- 구독자 : 관심사를 하나 이상의 채널에 등록 | ||
> 감시자 패턴과는 다르게 게시자와 구 독자 사이의 통신은 여러분의 코드 밖에서 일어난다. | ||
> (비동기적으로 일어난다. ) | ||
#### 장점 | ||
|
||
- 추가적인 결합 없이 비동기 이벤트 처리를 구현하기에 아주 좋은 기술 | ||
- 다른 기존 코드를 수정하지 않고 이벤트 처리 코드를 추 가하거나 교체할 수 있다 | ||
|
||
#### 단점 | ||
|
||
- 현재 어떤 일이 벌어지고 있는지 파악하기가 힘들다는 것 | ||
- 게시자 가 메시지를 보내는 것을 확인했더라도 어떤 구독자가 그 메시지를 처리하는 지 바로 이어서 볼 수 없다 (비동기적의 한계) | ||
|
||
### 반응형 프로그래밍과 스트림 그리고 이벤트 | ||
|
||
#### 반응형 프로그래밍 | ||
|
||
값이 바뀌면 그 값을 사용하는 다른 값이 ‘반응하는’하는 것 | ||
ex) 스프레드시트 | ||
|
||
이벤트를 사용하여 코드가 반응하도록 할 수 있다는 것은 명백하다. | ||
하지만 이벤트를 이리저리 연결하는 것도 쉽지만은 않다. | ||
|
||
그래서 `스트림`이 필요하다. | ||
|
||
#### 스트림 | ||
|
||
이벤트를 일반적인 자료 구조처럼 다룰 수 있게 해 준다. | ||
이벤트의 리스트를 다룬다고 생각하면 된다. | ||
-> 익숙한 방식으로 스트림을 다룰 수 있기 때문에 좋은 방식이다. | ||
|
||
## Topic 30 변환 프로그래밍 | ||
|
||
모든 프로그램은 데이터를 변환한다. 받은 입력을 출력으로 바꾼다. | ||
|
||
프로그램이 란 입력을 출력으로 바꾸는 것이라는 사고방식으로 돌아갈 필요가 있다. | ||
-> 구조는 명확해지고 더 일관적으로 오류를 처리하게 되어 결합도 대폭 줄어들 것이다. | ||
|
||
#### 변환 찾기 | ||
|
||
데이터를 전체 시스템 여기저기의 작은 웅덩이에 홑어 놓는 대신, 데이터를 거대한 강으로, 흐름으 로 생각하라. | ||
파이프라인은 코드 一 데이터 一 코드 一 데이터......의 연속이다. | ||
|
||
데이터는 더 이상 클래스를 정의할 때처럼 특정한 함수들과 묶이지 않는다. | ||
대신 우리 애플리케이션이 입력을 출력으로 바꾸어 나가는 진행 상황을 데이터로 자유롭게 표현할 수 있다. | ||
|
||
어떤 함수던 매개 변수가 다른 함수의 출력 결과를 맞기만 하면 어디서나 사용하고 또 재사용할 수 있다. 이건 결합을 대폭 줄일 수 있다. | ||
|
||
#### 오류 처리는 어떻게 하나? | ||
|
||
**어떻게 오류 검사에 필요한 조건부 논리를 추가할 수 있을까?** | ||
여러 가지 방법이 있지만 공통으로 사용하는 기본적인 관례가 하나 있다. | ||
바로 변환 사이에 값을 절대 날것으로 넘기지 않는 것이다. 대신 wrapper 역할을 하는 자료구조나 타입으로 값을 싸서 넘긴다. | ||
|
||
> (엘릭서 뭔데...) | ||
## Topic 31 상속세 | ||
|
||
우리가 맞닥트린 객체 지향 개발자 세대는 다음 둘 중 하나의 이유로 상속을 사용한다. | ||
타입이 싫어서 아니면 타입이 좋아서. | ||
|
||
타입을 싫어하는 이들은 입력하는 글자 수를 줄이기 위해 상속을 쓴다. | ||
타입을 좋아하는 이들은 상속으로 클래스 간의 관계를 표현한다. | ||
|
||
**두 가지 상속 모두 문제가 있다** | ||
|
||
더는 상속을 쓸 필요가 없게 해 주는 세 가지 기법을 소개하겠다. | ||
|
||
- 인터페이스와 프로토콜 | ||
- 다형성은 인터페이스로 표현하는 것이 좋다. | ||
- 위임 | ||
- 서비스에 위임하라. Has-A가 Is-A보다 낫다. | ||
- 믹스인과트레이트 | ||
|
||
## Topic 32 설정 | ||
|
||
애플리케이션이 출시된 이후 바뀔 수도 있는 값에 코드가 의존하고 있다면 | ||
-> 그 값을 애플리케이션 외부에서 관리해라. | ||
애플리케이션이 여러 환경에서 혹은 여러 고객을 위해 실행된다면 | ||
-> 특정 환경이나 특정 고객에게 한정된 값을 애플리케이션 외부에서 관리해라. |