5P by GN⁺ | ★ favorite | 댓글 2개
  • 복잡한 Python 애플리케이션은 규모가 커질수록 단순한 구현 방식만으로 테스트와 변경을 감당하기 어려워지며, 이 책은 그 해법으로 아키텍처 패턴을 코드 예제로 다룸
  • MADE.com의 온라인 가구 판매와 글로벌 공급망을 예제로 삼아, 현실의 운영 문제를 소프트웨어 모델로 옮기는 도메인 모델링을 중심에 둠
  • 핵심 축은 TDD, DDD, 이벤트 기반 아키텍처이며, 빠른 단위 테스트와 적은 수의 E2E 테스트, 인프라와 분리된 모델, 메시지 기반 통합을 목표로 함
  • Flask, SQLAlchemy, pytest, Docker, Redis를 사용하지만, 특정 기술 선택이 구현 세부사항으로 밀려나는 구조를 만드는 데 초점을 맞춤
  • 복잡한 Python 애플리케이션을 다뤄본 경험이 있으면 읽을 수 있으며, DDD나 고전적 애플리케이션 아키텍처 패턴을 미리 알 필요는 없음

테스트하기 쉬운 구조에서 출발한 문제의식

  • Harry의 이전 책 Test-Driven Development with Python 이후, 애플리케이션을 어떻게 구조화해야 테스트하기 쉬운지에 대한 질문이 남음
  • 핵심은 비즈니스 로직을 단위 테스트로 충분히 다루면서, 통합 테스트와 E2E 테스트 수를 최소화하는 구조를 만드는 것임
  • "Hexagonal Architecture", "Ports and Adapters", "Functional Core, Imperative Shell" 같은 개념을 언급했지만, 당시에는 실제로 충분히 이해하거나 실천하지 못한 상태였음
  • Bob은 팀에서 소프트웨어 아키텍처를 맡을 사람이 없어 아키텍트가 되었고, Ian Cooper에게 코드 작성과 사고 방식에 대한 새로운 접근을 배움

MADE.com 사례: 공급망을 소프트웨어로 모델링하기

  • 두 저자는 유럽 이커머스 회사 MADE.com에서 일하며, 책의 기법을 실제 비즈니스 문제를 모델링하는 분산 시스템 구축에 적용함
  • 예제 도메인은 Bob이 MADE에서 처음 만든 시스템을 바탕으로 하며, 새 프로그래머가 팀에 합류할 때 가르쳐야 하는 내용을 정리하려는 목적을 가짐
  • MADE.com은 화물 파트너와 제조사로 이루어진 글로벌 공급망을 운영함
    • 비용을 낮추기 위해 재고를 창고에 오래 쌓아두지 않도록 배송을 최적화하려 함
    • 이상적으로는 고객이 소파를 구매하는 바로 그날 항구에 도착해, 보관 없이 고객 집으로 배송되는 흐름을 원함
    • 컨테이너선으로 상품이 도착하는 데 3개월이 걸릴 수 있어 타이밍 조정이 어려움
  • 실제 운영에서는 파손, 침수, 폭풍으로 인한 지연, 물류 파트너의 처리 오류, 서류 누락, 고객의 주문 변경 같은 변수가 계속 발생함
  • 이런 문제를 다루기 위해 현실 세계의 운영을 소프트웨어로 표현하고, 가능한 많은 업무를 자동화하려 함

Python 프로젝트가 커질 때 드러나는 한계

  • Python은 빠르게 성장하고 성숙해졌지만, C#과 Java 진영이 오래 다뤄온 종류의 문제를 이제 본격적으로 맡기 시작한 상태로 봄
  • 스타트업은 실제 비즈니스가 되고, 웹 앱과 스크립트 자동화는 엔터프라이즈 소프트웨어로 커져감
  • Python의 철학에는 “There should be one—and preferably only one—obvious way to do it”가 있지만, 프로젝트 규모가 커지면 가장 obvious한 방식이 복잡성과 요구사항 변화를 관리하는 데 항상 적합하지는 않음
  • 책에서 다루는 기법과 패턴은 새롭지 않지만, 대부분 Python 세계에는 비교적 새로운 것으로 봄
  • Eric Evans의 Domain-Driven Design, Martin Fowler의 Patterns of Enterprise Application Architecture를 대체하려는 책은 아니며, 해당 고전들을 자주 참조하고 읽기를 권장함
  • 기존 문헌의 코드 예제는 Java나 C++/#로 쓰인 경우가 많아, Python 개발자에게는 읽기 부담이 클 수 있음

복잡성 관리를 위한 세 가지 도구

  • 테스트 주도 개발(TDD) 은 올바른 코드를 만들고, 회귀를 두려워하지 않고 리팩터링하거나 기능을 추가하게 해줌
    • 가능한 빠르게 테스트를 실행하는 방법
    • 빠르고 의존성 없는 단위 테스트에서 최대한 많은 커버리지와 피드백을 얻는 방법
    • 느리고 불안정한 E2E 테스트를 최소화하는 방법을 다룸
  • 도메인 주도 설계(DDD) 는 비즈니스 도메인의 좋은 모델을 만드는 데 집중하게 함
    • 모델이 인프라 관심사에 얽매이지 않도록 하는 방법
    • 변경하기 어려운 모델이 되지 않게 하는 방법을 다룸
  • 메시지로 통합되는 느슨하게 결합된 마이크로서비스, 때로는 reactive microservices라고 불리는 방식은 여러 애플리케이션이나 비즈니스 도메인 사이의 복잡성을 관리하는 해법으로 다뤄짐
    • Flask, Django, Celery 같은 Python 생태계의 기존 도구와 어떻게 맞출지는 항상 분명하지 않음
  • 마이크로서비스를 사용하지 않거나 관심이 없어도, 책의 대부분 패턴과 이벤트 기반 아키텍처 내용 상당수는 모놀리식 아키텍처에도 적용 가능함

독자와 전제 지식

  • 이 책은 어느 정도 복잡한 Python 애플리케이션을 가까이에서 다뤄본 독자를 가정함
  • 복잡성 관리에서 오는 고통을 경험한 독자에게 맞춰져 있음
  • DDD나 고전적 애플리케이션 아키텍처 패턴에 대한 사전 지식은 필요하지 않음
  • 설명은 예제 애플리케이션을 중심으로 장별로 쌓아가는 방식임
  • 저자들은 업무에서 TDD를 사용하므로, 테스트 코드를 먼저 보여주고 그다음 구현을 보여주는 흐름을 자주 사용함
  • Flask, SQLAlchemy, pytest, Docker, Redis를 쓰지만, 이미 익숙하면 도움이 될 뿐 필수는 아님
  • 주요 목표 중 하나는 특정 기술 선택이 사소한 구현 세부사항이 되는 아키텍처를 만드는 것임

책의 구성

  • 책은 두 부분으로 나뉨
  • 1부: 도메인 모델링을 지원하는 아키텍처

    • 도메인 모델링과 DDD는 1장, 2장, 7장에서 다룸
    • 복잡한 비즈니스 문제를 코드 안의 도메인 모델로 반영해야 한다는 전제를 둠
    • 외부 의존성이 없고 빠른 단위 테스트가 가능한 모델로 시작하는 방법을 설명함
    • 이후 적절한 aggregate 선택과 데이터 무결성 문제를 다시 다룸
    • Repository, Service Layer, Unit of Work 패턴은 2장, 4장, 5장에서 다룸
    • 이 패턴들은 모델을 불필요한 의존성에서 분리하기 위해 서로를 보완함
    • 영속 저장소 주변에 추상화 계층을 만들고, 시스템 진입점과 주요 유스케이스를 포착하는 서비스 계층을 둠
    • Flask API나 CLI처럼 얇은 진입점을 만들기 쉬운 구조를 보여줌
    • 추상화와 테스트에 대한 논의는 3장과 5장에서 이어짐
    • Repository 패턴을 소개한 뒤 추상화를 선택하는 방법과 결합 방식에서 추상화의 역할을 다룸
    • Service Layer 패턴 이후에는 테스트 피라미드와 가능한 높은 추상화 수준에서 단위 테스트를 작성하는 방법을 다룸
  • 2부: 이벤트 기반 아키텍처

    • 이벤트 기반 아키텍처는 8장부터 11장에서 다룸
    • Domain Events, Message Bus, Handler 패턴을 소개함
    • Domain Events는 시스템의 어떤 상호작용이 다른 동작을 촉발한다는 개념을 담는 수단임
    • Message Bus는 동작이 이벤트를 촉발하고 적절한 handler를 호출하게 함
    • 이벤트를 마이크로서비스 아키텍처에서 서비스 간 통합 패턴으로 사용하는 방법을 다룸
    • commands와 events를 구분하며, 애플리케이션은 본질적으로 메시지 처리 시스템이 됨
    • 12장에서는 CQRS 예제를 이벤트를 사용하는 방식과 사용하지 않는 방식으로 다룸
    • 13장에서는 명시적·암묵적 의존성을 정리하고 간단한 의존성 주입 프레임워크를 구현함
    • 에필로그에서는 새로 시작하는 단순 예제가 아니라 기존 소프트웨어에 이런 원칙을 적용하는 방법과 추가 읽을거리를 제공함

예제 코드와 따라 하기

  • 책은 하나의 예제 프로젝트를 중심으로 구성되며, 장이 진행될수록 프로젝트를 단계적으로 확장함
  • 독자가 실제로 코드를 만져보고 패턴이 어떻게 작동하는지 감각을 얻는 것을 중요하게 봄
  • 모든 코드는 GitHub에 있으며 각 장마다 별도 브랜치가 있음
  • 따라 하는 방식은 세 가지로 제안됨
    • 직접 저장소를 만들고 책의 예제를 따라 앱을 구축하며, 필요할 때 저자들의 저장소를 참고함
    • 각 패턴을 장별로 자신의 작은 프로젝트에 적용해 봄
    • 각 장의 "Exercise for the Reader"와 일부가 비어 있는 GitHub 코드를 사용해 빠르게 실습함
  • 특히 자신의 프로젝트에 패턴을 적용하려는 독자는 단순한 예제를 먼저 다루는 것이 안전한 연습이 됨
  • 최소한 각 장을 읽을 때 저장소에서 git checkout으로 코드를 받아 실제 동작하는 앱 맥락에서 코드를 확인하기를 권장함

라이선스와 형식

  • 코드와 온라인 버전은 Creative Commons CC BY-NC-ND 라이선스임
    • 비상업적 목적
    • 저작자 표시
    • 복사와 공유 가능
  • 인쇄판은 별도 라이선스를 따르며, 재사용 관련 우려가 있으면 O’Reilly에 문의하도록 안내함
  • 책의 표기 관례는 이탤릭, 고정폭, 고정폭 굵게, 고정폭 이탤릭을 구분해 사용함
    • 이탤릭은 새 용어, URL, 이메일 주소, 파일명, 확장자를 나타냄
    • 고정폭은 프로그램 목록과 코드 요소를 나타냄
    • 고정폭 굵게는 사용자가 그대로 입력해야 하는 명령이나 텍스트를 나타냄
    • 고정폭 이탤릭은 사용자가 제공하거나 문맥에 따라 정해지는 값으로 대체될 텍스트를 나타냄

댓글과 토론

Hacker News 의견들
  • 이 책은 아키텍처 패턴을 배우기 좋은 보물창고이고, 주제에 빠르게 들어가 핵심을 잡기 쉬움
    다만 실무 관점에서는 이런 패턴 일부가 Python에서 복잡도와 성능 문제를 크게 키울 수 있고, 특히 이미 ActiveRecord 패턴을 쓰는 Django 같은 프레임워크와 함께 쓰면 더 그렇다
    Python을 쓰는 크고 작은 회사들을 겪어보니, 엄격한 아키텍처 패턴을 쓰던 큰 회사들은 코드가 “깨끗”하긴 했지만, 처음엔 단순해 보이는 작업도 지나치게 복잡하고 불필요하게 느렸음
    반대로 그런 패턴을 신경 쓰지 않던 큰 회사들은 거대한 if-else 파일이나 비즈니스 로직이 다 들어간 Django 모델처럼 정말 못생긴 코드도 있었지만, 읽고 이해하고 1000줄짜리 if-else를 수정할 수 있어서 더 생산적이었다
    깨끗한 코드가 아니던 회사에서 더 생산적이었다는 걸 인정하기 싫지만, 무엇이 깨끗한지 두고 끝없이 벌어질 논쟁도 많이 피한 셈임

    • 프로젝트가 엄격한 아키텍처 패턴을 따른다고 할 때 자주 만나는 가장 큰 문제는, 실제 동작을 숨기는 불투명한 추상화가 너무 많거나 단순한 작업에도 너무 많은 계층을 지나가게 만든다는 점임
      누군가 “X나 Y를 하려면 N개의 다른 것들을 먼저 만들어야 한다”고 정해버려서, 간단한 작업에도 파일·함수·클래스를 여러 개 수정해야 함
      아키텍처 패턴을 신경 쓰지 않는 회사에서는 보기 흉한 코드가 많을 수 있지만, 간접 참조가 적고 작업 대상이 한 영역에 모여 있어 새로 들어온 사람이 이해하기 쉬운 경우가 많다
      여러 파일에 흩어진 작은 함수들보다, 쉽게 이동하며 수정하고 디버깅할 수 있는 100줄짜리 함수가 나을 때도 많음
      추상화가 전부 나쁘다는 뜻은 아니지만, 일을 오래 할수록 추상화가 적을수록 코드의 개별 단위나 기능을 추론하기 쉬워진다고 느끼며, 정말 어려운 것만 추상화하고 단순한 것까지 추상화하지 않는 쪽으로 결론 내림
    • 엄격한 아키텍처 패턴을 쓰려면 도메인 이해와 패턴 이해가 모두 필요함
      둘 다 있으면 코드베이스 탐색이 직관적이고, 둘 중 하나라도 없으면 1000줄짜리 함수가 더 읽기 쉬워 보일 수 있음
    • 책에서 외계 우주선을 조종하는 모델링 예시를 든 건 조금 오해를 부를 수 있음
      우주선은 고도로 설계된 제품이고, 상당 부분 소프트웨어의 제어 장치로 동작하므로 이미 발견해 복사할 수 있는 깔끔한 설계 모델이 들어 있음
      도메인 모델링은 기존 모델을 복사하는 일이 아니라, 새 소프트웨어가 대체하려는 물리적·사회적 기술보다 소프트웨어가 가진 장점을 활용해 더 낫게 만드는 일이어야 함
      기존 도메인 모델에도 훌륭한 추상화가 있어서 새 모델에 들어가야 하는 핵심 요소가 많고, 이해관계자들이 현재 시스템으로 무엇을 달성하려는지 이해하는 것도 중요하다
      하지만 비즈니스와 문화 세계의 모델은 코드에 맞게 최적화되어 있지 않고 오래되었거나 지저분한 경우가 많으며, 경계 사례와 덜 명시된 부분은 사람이 해석해 처리한다
      그런 모델은 최종 목표가 아니라 영감의 원천으로 다뤄야 함
    • 이 책은 좋지만, 이런 패턴을 언제 적용할지와 언제 적용하지 말아야 할지를 정말 이해해야 함
      이런 아키텍처 패턴은 프로젝트 관리와 비슷해서 둘 다 오버헤드를 만들고, 무분별하게 쓰면 얻는 가치보다 비용이 압도적으로 커져 나쁜 평판을 얻는다
      하지만 신중하게 쓰면 프로젝트 성공에 결정적일 수 있음
      예를 들어 단순한 캘린더 REST API를 만든다면 복잡한 아키텍처를 쓰지 않을 것임
      반면 거래 시스템에서는 포트와 어댑터 아키텍처를 지키는 것이 시뮬레이션 모드와 운영 모드를 매끄럽게 전환하는 데 매우 중요했다
      시뮬레이터와 실제 거래 엔진, 과거 이벤트 피드와 실시간 피드를 쉽게 교체해야 하고, 비즈니스 로직을 두 벌로 만들어 동기화할 수는 없기 때문임
    • “엄격한 아키텍처 패턴 사용”의 문제는 사람들이 참고 자료에 나온 특정 구현을 곧 패턴 자체라고 착각한다는 데 있음
      패턴은 구현이 아니라, 무엇을 하고 있는지에 대한 사고 과정, 그것을 다루는 계획, 나머지 코드에 제공하려는 API의 최상위 설계에 가깝다
      Python에서는 함수가 객체이기 때문에 상태 기계도 서로를 반환하는 함수 묶음과 f = f(x) 반복만으로 충분할 때가 많음
      Singleton 대신 Borg 패턴을 쓰자고 하기도 하지만, 실제로는 그냥 모듈을 쓰면 되는 경우가 많고 sys가 이미 싱글턴처럼 만들어줌
      “의존성 주입”도 흔히 함수에 인자, 때로는 다른 함수를 넘기는 일을 멋지게 부르는 말일 뿐임
      Flyweight는 별도 사물이 아니라 인터닝 기법이고, 원문에서 말한 Command 패턴은 Jack Diederich의 유명한 비판 강연(https://www.youtube.com/watch?v=o9pEzgHorH0)의 핵심 중 하나였으며, functools.partial을 잘 쓰면 된다
      깨끗한 코드와 못생긴 코드의 이분법은 더 나은 예를 아직 못 봐서 생긴 착각일 수 있음
      짧은 함수가 복잡한 클래스 계층을 요구하지도 않고, 애초에 클래스가 필요하지 않을 수도 있다
      객체 지향 프로그래밍은 클래스가 아니라 객체에 관한 것이며, 클래스가 핵심이었다면 클래스 지향 프로그래밍이라고 불렸을 것임
  • 이 책에서 Python이나 특정 언어를 넘어서는 개념, 예를 들면 이벤트 기반 아키텍처, 명령, CQRS 같은 부분은 매우 유용함
    다만 다른 부분에는 문제가 있고, 경험이 부족한 개발자가 이를 교리처럼 받아들여 전부 한꺼번에 구현하려 할 때 위험해질 수 있음
    저장소 패턴은 일반적으로 도움이 되지만, 책의 예시를 포함해 많은 경우에는 이득이 거의 없으면서 복잡도만 늘리는 과한 선택이 된다
    특히 SQLAlchemy를 쓰고 있다면 SQLAlchemy 자체가 어느 정도 저장소, 더 정확히는 ORM이 얹힌 관계형 데이터베이스 추상화 계층 역할을 함
    서비스 계층과 작업 단위도 복잡한 사용 사례가 많은 애플리케이션에는 유용하지만, 책임 범위가 좁은 작은 서비스들로 구성된 시스템에서는 금방 부풀어 오른다
    Python에서의 의존성 주입도 마찬가지임
    설계 패턴은 결국 도구이므로 개발자는 언제 쓸지, 더 중요하게는 언제 쓰지 말아야 할지를 이해해야 한다
    이 책에도 그런 조언이 있지만, 각 장 끝보다 앞부분에서 더 두드러지게 다뤘으면 좋았음

    • 저장소 패턴이 왜 “이득은 거의 없고 복잡도만 늘리는 과한 선택”인지 궁금함
      데이터베이스 접근이 필요하면 관심사 분리를 위해 항상 쓰는 편을 추천할 만큼 가벼운 패턴이라고 봄
      결국 특정 엔터티에 대한 모든 데이터베이스 접근이 그 엔터티의 저장소 한 곳을 통하게 만드는 것뿐이고, 저장소 내부에서는 직접 쿼리를 실행하든 ORM을 쓰든 원하는 대로 할 수 있다
      글의 저장소 패턴 섹션에 있는 내용 상당수는 패턴 자체보다 Python, Django, SQLAlchemy 세부 사항에 더 가깝다
    • Python에서 의존성 주입을 비판하는 이유를 더 듣고 싶음
      주로 Python을 쓰고 있고, 의존성 주입을 “함수가 계산에 필요한 모든 입력을 매개변수로 받게 하는 것”이라고 이해하는데, 프로젝트 설계의 중심 원칙으로 삼을 만하다고 느꼈음
    • 책은 경험이 부족한 개발자가 모든 것을 한 번에 구현하지 말라고 명시적으로 말함
      서비스 계층과 의존성 주입은 함수형 프로그램을 작성할 때 꽤 도움이 됐다
      Python으로 만든 복잡한 이미지 처리 스크립트를 Celery 기반 분산 이미지 처리 서비스의 플러그인처럼 쓰는데, 서비스 계층과 의존성 주입은 코드를 dependency.do_thing(params)에서 do_thing(dependency, params)로 바꿔줌
      이렇게 하면 훨씬 테스트하기 쉬워진다
      실제 배포 환경에서 I/O를 모두 가짜로 바꾼 이미지 처리 작업을 돌릴 수도 있고, 가짜 Celery 위에서 실제 이미지 처리 작업을 돌릴 수도 있음
      전체 배포 전에 여러 함수를 끝까지 테스트할 수 있고, 서비스 계층에서 Result 타입을 함께 쓰면 프로그램을 크래시시키지 않으면서 관련 오류 정보를 웹 클라이언트로 전달하기도 쉬웠다
    • 나도 같은 결론을 얻음
      패턴들을 보는 건 흥미롭지만, 초반에 어떤 상황에서 구현하면 가장 유용한지에 대한 가이드가 있으면 더 좋겠다
      패턴이 도구라면 언제 쓰고 언제 피해야 하는지 안내해주는 편이 도움이 됨
      장단점 섹션에서 어느 정도 다루긴 하므로, 순서와 강조의 문제일 수도 있음
      새 비즈니스를 위한 작은 웹 앱을 만들고 Python을 배우면서 보니, 일부 패턴은 단순화에 쓸 아이디어를 줬고 다른 패턴은 피해야겠다고 판단하게 됐다
    • Robert Martin도 그런 예 중 하나라고 봄
      “Clean Code” 같은 것으로 경험이 부족한 개발자들을 세뇌해 엄청난 피해를 만들었다고 생각함
      소프트웨어 공학은 엄밀한 자연과학이 아니라서 은탄환은 거의 없고 모든 것이 트레이드오프
      하나의 참된 길을 안다고 말하는 사람들은 위험하거나 초보에 가깝다
  • TypeScript 개발자지만 이 책은 가장 좋아하는 아키텍처 책 중 하나이고 자주 참고함
    특히 테스트를 위한 가짜 작업 단위와 서비스 패턴을 좋아하며, 모든 프로젝트에서 서드파티 서비스를 가짜로 대체할 때 신봉하듯 쓴다
    여기서 중요한 건 모의 객체가 아니라 가짜 객체라는 점임
    이름짓기 고민에도 도움이 됐는데, 예를 들어 이벤트 이름은 인프라나 패턴 중심이 아니라 도메인에 특화되게 지으라고 권함
    USER_NOTIFICATION보다 CART_ITEM_BECAME_UNAVAILABLE이 낫다는 식임
    이런 내용 중 일부는 당연하지만 팀원에게 설명하기 번거로운데, cosmic python이 온라인에 공개되어 있어 링크를 보내기 쉽다
    전반적으로 훌륭하고 내게 큰 영향을 준 자료였음

    • 이 책은 처음 보지만 저자 중 한 명인 Harry J. W Percival이 TDD “goat” 책의 저자라는 걸 알아봄
      https://www.obeythetestinggoat.com/pages/book.html
      그 책도 비슷하게 애착이 가는 책이고, 실무에서 Python을 거의 쓰지 않았는데도 다른 언어를 쓸 때 자주 다시 찾아보게 된다
      온라인과 종이책으로 모두 제공되는 점도 좋음
      이 책도 꼭 읽어볼 생각임
    • “가짜, 모의 객체가 아니라”라는 구분이 마음에 든다면 이 글도 좋아할 듯함: https://martinfowler.com/bliki/TestDouble.html
    • 언제나 모의 객체보다 가짜 객체가 낫다
  • Python은 좋은 접착 언어라고 봄
    모든 것에 캡슐화와 상속을 강제하고, 비공개 필드만 두고 메서드로 설정하게 만드는 강제 객체 지향 사고방식에 지쳤다
    SOLID, clean coding, clean architecture, GoF 패턴, Uncle Bob에도 지쳤음
    명사의 왕국과 FizzBuzz Enterprise Edition에도 지쳤다
    이제는 객체 지향을 최대한 줄이고 명령형 또는 함수형 흐름을 따른다
    Python을 가끔 쓸 때, 주로 회사에서 .NET을 쓰기 때문이지 싫어서가 아닌데, 그때는 객체와 패턴에서 자유로운 경험을 원함
    이 책에 가치가 없다는 뜻은 아니고, 패턴을 배우는 데 유용하다
    하지만 현실의 모든 프로그래밍을 패턴·객체·SOLID에 끼워 맞추지는 말아야 함

    • 가능한 한 많은 순수 함수를 쓰고, 그다음 외부 세계와 상호작용하는 1~4개 매개변수 함수들을 만들며, 마지막에야 그것들을 감싸는 도메인 객체를 만드는 모델을 가장 좋아함
      이렇게 하면 관련 없는 복잡도가 도메인 밖에 머무르고, 항상 필요하지 않은 전체 객체를 만들지 않아도 그 함수들을 재사용할 수 있다
  • 여기서 하려는 게 대충 이렇다면 상당히 과해 보임
    SQLAlchemy 모델을 다시 구현하면서 “저장소”라고 부르고, SQLAlchemy 세션을 다시 구현하면서 “작업 단위”라고 부르며, 모델도 쓰지 않는 “서비스 계층”을 추가함
    결합도를 낮춘다는 이유로 모델 속성을 전부 별도 함수 매개변수로 풀어내고, 디버깅 가능성을 없애듯 모든 것을 메시지 버스에 흩뿌림
    그런데 이게 쓰기 경로에만 해당됨
    읽기에는 별도의 비정규화 테이블을 두고 원시 SQL로 조회함
    실제로 12장을 보면 그렇다
    MADE.com 트래픽을 보면 지난달 데스크톱과 모바일 합쳐 50만 방문 정도이고, 분당 약 12뷰 수준임
    그런 상황에서 하루 종일 DDD를 논할 수 있는 직장이 부럽다는 냉소가 듦

    • 책의 75%쯤 읽었지만, 저자들이 책에서 논의한 모든 것을 항상 해야 한다고 말한다고 느낀 적은 없음
      각 패턴마다 장단점 요약이 있고, 부족한 부분은 있어도 패턴이 애플리케이션 요구에 맞는지 생각해야 한다는 점은 분명히 말함
      책의 모든 것이 필요한 애플리케이션은 많지 않겠지만, 하나 이상의 패턴을 적용할 수 있는 애플리케이션은 분명 많다
    • 그렇다면 복잡한 비즈니스용 소프트웨어를 제대로 작성하는 방법을 보여주면 됨
      하지만 일회용 계정이라면, 가치 없는 지나가던 부정적 반응에 가깝다
  • 몇 년 전부터 Python을 직업적으로 쓰기 시작함
    Kotlin과 TypeScript에서 넘어왔고 언어 자체는 접근하기 쉬웠지만, 익숙했던 느슨한 결합과 테스트 용이성을 달성하면서도 Python다운 방식으로 만드는 데 어려움을 겪었다
    동료 추천으로 이 책을 사서 처음부터 끝까지 읽었고, 사소하지 않은 Python 코드베이스에서 복잡도 관리를 하는 방법을 이해하는 데 큰 도움이 됨
    책이 권하는 모든 패턴을 따르지는 않지만, 무엇이 가능한지와 다른 패러다임에서 쌓은 경험을 Python에 적용하면서도 “Java 개발자가 Python을 하는” 느낌이 되지 않게 하는 방법을 보여줬다
    강력히 추천하며, 돈이 아깝지 않았음

  • 진짜 훌륭한 Python 프로그래밍 책 중 하나임
    아쉬웠던 한 가지는 코드에 정적 타입이 부족하다는 점이지만, 저자들이 의도적으로 그렇게 결정한 것임

    • 책은 읽지 않아서 저자들이 정확히 어떤 입장인지 모르지만, 타입 검사는 어떤 아키텍처 조언보다 내 Python을 더 많이 개선해줌
      코드에 타입 힌트를 달기 어려운 정도는 나중에 그 코드를 이해하기 얼마나 어려울지 보여주는 아주 좋은 척도임
    • 정적 타입이 부족하다는 말은 엄격하지 않다는 뜻인지 궁금함
      여기처럼 타입 힌트는 있음: https://www.cosmicpython.com/book/chapter_08_events_and_mess...
      책 일부에는 타입 힌트가 없는 부분도 있다
    • 일부 예시는 dataclasses를 쓰고, 이는 타입 주석을 강제함
      Python은 정적 타입을 지원하지 않는다
      타입 주석 기반 도구는 컴파일 과정에 영향을 주지 않고, dataclasses처럼 메타프로그래밍을 쓰는 경우가 아니라면 Python이 코드를 거부하게 만들 수도 없음
      그저 진단을 제공할 뿐이다
  • 이 책을 책장에 두고 있음
    K&R처럼 작은 책이고, 자주 넘겨본 탓에 꽤 닳은 흔적이 보인다

  • 아주 좋은 읽을거리이자 요약이었음
    약 3년 전 C#/.NET 기반 DDD 환경에서 일했는데, 지금 Python으로 이 개념들을 다시 보니 핵심이 더 잘 추려져 보인다
    이런 종류의 내용에 관심 있다면 강력히 추천함

  • 2년 반에서 3년 전쯤 이 책의 종이책을 읽었고 꽤 즐겼음
    테스트를 일급 주제로 유지하고, 기능을 추가할 때마다 꾸준히 갱신하는 점을 잘 해냈다
    오래된 아키텍처 책 중에는 테스트를 그만큼 우선순위 높게 다루지 않는 것도 있음
    테스트를 준비하기 쉽고, 작성하기 쉽고, 갱신하기 쉽게 만들어두면 코드를 수동으로 실행해 문제를 확인하는 일이 줄어 개발 과정이 더 즐거워진다
    더 빠른 피드백 루프가 생기는 셈임
    이 책의 이벤트 지향 부분은 매우 흥미로웠지만, 현재 업무에 실제로 구현하기에는 그다지 실용적으로 보이지 않았다