ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 4장,5장,6장
    클린 코드(Clean Code)/클린 아키텍처요약 2022. 11. 22. 00:01
    728x90

    4,5,6장에 대해서는 인상 깊은 내용에 대해서만 정리하고자 합니다.

     

    4장 - 구조적 프로그래밍

    다익스트라는 "테스트가 버그가 있음을 보여줄 뿐, 버그가 없음을 보여줄 수는 없다"라고 말했습니다.

    다시 말해 프로그래밍이 잘못되었음은 증명할 수 있지만 프로그래밍이 맞다고 증명할 순 없습니다.

     

    5장 - 객체지향 프로그래밍

    캡슐화

    데이터와 함수가 응집력있게 구성된 집단을 서로 구분 지을 수 있습니다.

    하지만 기존의 C언어에 비해서 완벽한 캡슐화가 약화되었습니다.

     

    상속

    이전에도 상속을 구현할 수 있었습니다.

    다만 더 편리해졌을 뿐입니다.

     

    다형성

    다형성을 이용하면 의존성에 대한 절대적인 제어 권한을 획득할 수 있는 능력을 갖게 됩니다. (인터페이스를 활용한 DI)

    이로 인해 저수준의 세부사항은 중요도가 낮은 플러그인 모듈로 만들 수 있으며, 고수준의 정책을 포함하는 모듈과는 독립적으로 개발하고 배포할 수 있습니다.

     

    6장 - 함수형 프로그래밍

    함수형 프로그래밍인 클로저에서는 변수가 한번 초기화되면 절대로 변하지 않습니다.

     

    불변성이 중요한 이유는 무엇일까요?

    race condition, 교착 상태 조건, 동시성 문제가 모두 가변 변수로 인해 발생합니다.

    즉, 변수가 불변성을 가진다면 이런 문제들이 해결됩니다.

     

    가변성의 분리

    불변성과 관련하여 가장 주요한 타협 포인트는 가변 컴포넌트와 불변 컴포넌트를 분리하는 일입니다.

    이를 통해 불변 컴포넌트끼리 작업을 처리하고 가변 컴포넌트를 통해 가변 변수를 다룹니다.

    이때는 동시성 문제를 해결하기 위해 트랜잭션을 사용하는 방식으로 해결합니다.

     

    이벤트 소싱

    저장 공간과 처리 능력의 한계는 점점 줄어들고 있습니다.

    이제 프로세스가 초당 수십억 개의 명령을 수행하고 램 용량은 수십억 바이트인 시대가 되었습니다.

    더 많은 메모리를 확보할수록, 기계가 빨라질수록 필요한 가변 상태를 더 적어집니다.

     

    간단한 예로 고객의 계좌 잔고를 관리하는 은행 애플리케이션을 생각해 보겠습니다.

    계좌 잔고를 변경하는 대신 트랜잭션 자체를 저장한다고 상상하면 누군가 잔고를 조회할 때마다 계좌 개설 시점부터 발생한 모든 트랜잭션을 단순히 더하면 됩니다.

     

    이런 전략을 사용하면 가변변수가 하나도 필요 없습니다.

    하지만 당연하게도 이런 접근법은 시간이 지남에 따라 트랜잭션의 수는 끝없이 증가하고, 잔고 계산에 필요한 컴퓨팅 자원은 걷잡을 수 없이 커집니다.

     

    이 전략이 영원히 실현 가능하려면 무한한 저장 공간과 무한한 처리능력이 필요합니다.

    하지만 영원히 동작하게 할 필요는 없으며 애플리케이션의 생명주기 동안만 문제없이 동작할 정도의 저장 공간과 처리 능력만 있으면 충분합니다.

     

    이벤트 소싱에 깔려있는 발상이 바로 이것입니다.

    이벤트 소싱은 상태가 아닌 트랜잭션을 저장하는 전략이고 상태가 필요 해지면 단순히 상태의 시작점부터 트랜잭션을 처리합니다.

    이렇게 되면 애플리케이션은 CRUD가 아닌 CR만 수행하면 됩니다.

    데이터 저장소에서 변경과 삭제가 발생하지 않으므로 동시 업데이트 문제 또한 일어나지 않습니다.

     

    이 이야기가 터무니 없이 들릴 수 있지만 소스 코드 버전 관리 시스템이 정확히 이 방식으로 동작합니다.

     

     

    개인적인 견해

    이벤트소싱에 대한 개념을 조금 더 확고하게 알아보고자 했습니다.

     

    이벤트 소싱은 데이터 저장 방법에 대한 것입니다.

    평소 우리는 어떤 로직을 처리하고, 그 결과 값만을 저장해왔습니다.

     

    사용자는 온라인 서점에서 책을 주문합니다.

    1번 책을 주문하고 2번 책도 한 번에 주문하려고 추가하였습니다.

    생각해보니 1번책은 사기 싫어져서 취소했습니다.

    이렇게 결과적으로 2번 책만 최종 값으로 저장하게 됩니다.

     

    같은 상황에서 이벤트 소싱은 이벤트 자체를 데이터로 저장합니다.

    "사용자가 1번 책을 추가하여 주문을 생성한다"

    "2번 책을 주문에 추가한다"

    "1번 책을 주문에서 삭제한다"

     

    이런 3가지 이벤트가 저장되는 방식으로 UPDATE 또는 DELETE 개념이 없습니다.

     

    현재 시점의 최종 값 알아내기(스냅숏의 도입 배경)

    순차적으로 저장된 이벤트들을 쭉 연산한다면 최종 값을 얻을 수 있습니다.

    하지만 이벤트가 10억 건 100억 건 쌓이게 되면 어떨까요?

    자연스럽게 최종 값을 얻기 위한 처리시간이 길어집니다.

     

    따라서 스냅숏의 개념을 도입합니다.

    10억 번째 이벤트가 발생할 때 스냅숏으로 저장해 두면 결국 최종 값은 1001번째 이벤트부터 재생해서 얻을 수 있습니다.

     

    CQRS

    이벤트 소싱에서 만약 다음과 같은 요구사항은 어떻게 처리해야 할까요?

     

    2번 책만 주문한 사용자 리스트를 반환해주세요

    이벤트를 모조리 재생해서 2번 책만 주문한 사용자 리스트를 반환하는 일은 너무 오래 걸립니다.

     

    이때 조회 성능을 위해 CQRS(Command and Query Responsibility Segregration)를 사용하여 상태를 변경하는 Command와 조회를 담당하는 Query를 Object 혹은 시스템 단위로 분리시킵니다.

     

     

     

     

     

    출처

    https://mjspring.medium.com/이벤트-소싱-event-sourcing-개념-50029f50f78c

     

    이벤트 소싱(Event Sourcing) 개념

    이벤트 소싱 혹은 CQRS라는 말을 SNS에서 자주 보게 되었어요. 비슷한 시기에 번역을 의뢰받아서 진행하게 되었어요. 아카(Akka) 관련 책인데 약속했던 마감일보다 늦어지고 있습니다. 이유는, 아카

    mjspring.medium.com

     

    댓글

Designed by Tistory.