현대의 미친 듯이 빠른 변화 속도를 따라가려면 모든 수단을 동원하여 가능한 한 느슨하고 유연한 코드를 작성해야 한다.
되돌릴 수 있는 의사 결정.
Topic 28. 결합도 줄이기
다리를 설계할 때는 그 형태가 바뀌지 않기를 바랄 것이다. 따라서 구조가 단단해야 한다. 하지만 소프트웨어를 설계할 때는 언젠가 형태를 바꾸려 할 것이다. 바라는 것이 정확히 반대다. 소프트웨어의 구조는 유연해야 한다.
묻지 말고 말하라 Tell, Don't Ask. TDA
객체 메서드를 설계할 때 Getter 를 무분별하게 사용해서 Ask 하지 말고 해당 객체가 역할(일)을 수행하는 메서드를 만들어서 Ask 하도록 하면 좋다. 왜냐하면 Getter 를 통해 사용하면 객체의 상태가 호출자 로직(역할)과 결합이 생긴다. 그러면 한 객체로 엮인 것과 같게 된다.
어느 정도까지 숨길지 고민될 때가 있다. 이때는 다음과 같이 최상위 개념이 무엇인지 잘 정리할 필요가 있다.
모든 애플리케이션에는 보편적은 최상위 개념들이 있기 마련이다. 예시한 애플리케이션에서는 고객과 주문이 최상위 개념이다. 주문을 고객 객체 안에 완전히 숨기는 것은 좀 이상하다. 따라서 주문 객체를 노출하는 API를 만들어도 문제 없다.
Topic 29. 실세계를 갖고 저글링하기
오늘날 우리는 더 많은 것을 기대한다. 사람이 컴퓨터에 맞추기보다는 컴퓨터가 우리 세계 안으로 들어와야 한다.
어디에서 온 것이든 애플리케이션을 이런 이벤트에 반응하도록 그리고 그에 기반해서 하는 일을 조절하도록 만들면, 진짜 세상에서 더 잘 작동하는 애플리케이션이 탄생할 것이다. 사용자들은 애플리케이션의 상호 작용이 더 원활하다고 느낄 것이고 애플리케이션 자체는 리소스를 더 효율적으로 사용할 것이다.
우리는 재사용성이 높고 유지보수를 효율적으로 하기 위해 '객제지향' 개념을 사용한다. 객체지향 개념은 우리가 실세계를 인지하는 방식을 모방한다. 우리는 물체(객체)들로 정의하고 물체(객체)들간의 상호작용으로 세상을 이해한다. 객체지향 프로그래밍도 상태와 역할을 가진 객체들을 정의하고 객체들간의 상호 작용으로 프로그램을 설계한다.
사용자와 프로그램 관계에서 보면 사용자는 프로그램을 사용하며 다양한 이벤트를 일으킨다. 이 이벤트에 맞게 프로그램이 반응하도록 한다면 좀 더 좋은 사용자 경험을 얻을 수 있을 것이다.
이와 같은 이벤트 기반에 설계를 할 수 있는 전략들은 다음과 같다.
- 유한 상태 기계
- 감시자observer 패턴
- 게시-구독
- 반응형 프로그래밍과 스트림
유한 상태 기계(Fininte State Machine, FSM). 기본적으로 이벤트를 어떻게 처리할지 정의한 명세서이다.
state = :look_for_string
result = []
while ch = STDIN.getc
state, action = TRANSITIONS[state][ch] || TRANSITIONS[state][:default]
case action
when: ignore
when: start_new_string
result = []
when: add_current_to_string
result << ch
when: finish_current_string
puts result.json
end
end
FSM 상태기계로 간단하게 이벤트 중심으로 구현할 수 있다. 그리고 이벤트 관련된 문제를 다 해결할 순 없다.
감시자 패턴 Observer Pattern
감시자 패턴은 이벤트를 발생시키는 쪽인 Observable 감시 대상과 이런 이벤트에 관심이 있는 클라이언트인 '감시자'로 이루어진다.
구현상으로 보면, 이벤트를 발생시키는 Observable 에 감시할 이벤트와 이벤트가 발생 시 수행할 로직인 감시자를 등록해둔다. Observable 에 이벤트가 발생하면 Observable 내에 해당 이벤트에 감시로 등록된 감시자들을 하나씩 호출한다.
이 패턴의 단점은 2가지가 있다.
첫째로 이벤트 발생자 Observable과 감시자 Observer 사이에 참조가 생기고 결합이 생긴다. 왜냐하면 이벤트 발생 시 Observable 내에 등록된 Observer 목록을 일일이 조회하고 호출해야하는 책임이 있기 때문이다.
두번째 단점은 실행이 동기적이라 성능 병목이 발생할 수 있다는 점이다. 감시대상이 감시자들을 일일이 호출하고 끝날 때까지 기다려야하기 떄문이다.
게시 구독 Publish-Subscribe 패턴
펍섭이라고도 부른다. 이 모델 주체는 Publisher, Subscribe, Channel 이 있다. Publisher 는 이벤트 발생 시 Channel 로 보내게 되며, Channel 에 관심사를 등록해둔 Subscriber 가 이벤트를 받고 역할을 수행하게 된다.
중간자인 Channel 로 결합도를 낮출 수 있다. 그리고 Channel 에서 비동기 실행을 담당하면 되기 때문에 비동기로 처리하기 좋다. 메시지 전달 시스템이라고도 보면 된다.
반응형 프로그래밍 Reactive Programming 과 스트림 그리고 이벤트
반응형 프로그래밍 예시는 스프레드 시트를 들 수 있다. 스프레드 시트에서 한 개의 셀에 있는 데이터를 변경하면 해당 셀로 수식이 된 다른 셀 데이터도 수정된다. 사용자의 반응에 다른 부분들도 변경되는 것이다.
구현 예시로는 프론트엔드에 리액트와 뷰 프레임워크가 있다.
이 리액티브 프로그래밍 핵심에는 이벤트를 일반적인 자료구조처럼 다룰 수 있는 '스트림'이다. 이러한 스트림 기반한 리액티브 라이브러리를 사용하면 시간을 동기적이나 비동기적 처리를 할지 고민할 적어지고 쉽게 적용할 수 있다.
이러한 이벤트 발생지와 이벤트 처리하는 곳을 분리하면 일직선으로 처리되는 코드보다 더 잘 반응하고 결합도를 낮출 수 있다.
'공부노트 > 개발서적' 카테고리의 다른 글
[실용주의 프로그래머] Topic 27. 헤드라이트를 앞서가지 말라 (0) | 2023.08.02 |
---|---|
[실용주의 프로그래머] Topic 26. 리소스 사용의 균형 (0) | 2023.08.02 |