본문 바로가기

Python

Architecture Patterns with Python(13장) 의존성 주입(그리고 부트스트래핑) 의존성 주입(dependency injection; DI) 을 위해 bootstrap.py 라는 새로운 컴포넌트를 추가한다. 아래는 부트스트랩이 없는 경우를 보여준다. 엔드포인트에서 수많은 초기화를 수행하고 주 의존성인 UoW를 여기저기 전달해야 한다. 아래는 부트스트래퍼가 이러한 책임을 맡은 모습을 보여준다. (src/allocation/bootstrap.py) import inspect from typing import Callable from allocation.adapters import orm, redis_eventpublisher from allocation.adapters.notifications import ( AbstractNotifications, Em.. 더보기
Architecture Patterns with Python(12장) 명령-질의 책임 분리(CQRS) 읽기와 쓰기는 다르고, 또 다르게 취급해야 한다는 의견은 논란의 여지가 없다. 12.1 쓰기 위해 존재하는 도메인 모델 지금까지 비즈니스 상황에 부합하는 도메인 규칙을 만족시키는 소프트웨어를 만드는 방법들에 대한 설명을 이어왔다. '현재 사용 가능한 재고보다 더 많은 재고를 할당할 수 없다' 와 같은 명시적인 제약과 '각 주문 라인은 한 배치에만 할당된다' 와 같은 암시적인 제약을 설정하였다. 위의 규칙을 일관성 있게 지키기 위해 작은 작업 덩이리로 쪼개고 이를 커밋할 때 도움이 되는 작업 단위(UoW)나 애그리게이트 패턴을 도입했다. 이런 작은 작업 덩어리 사이에서 변경된 내용을 통신하기 위해 도메인 이벤트 패턴을 도입하여 '재고가 손상되거나 분실될 경우 배치의 사용 가.. 더보기
Architecture Patterns with Python(11장) 이벤트 기반 아키텍처 : 이벤트를 사용한 마이크로서비스 통합 앞선 장에서 커맨드와 이벤트를 분리하여 시스템 내부적으로 어떻게 이벤트를 구분하고 이를 처리할 것인지를 정의하였다. 이번 장에서는 레디스와 같은 외부 메시지 버스(혹으 메시지 브로커) 를 통해 이벤트를 주고 받는 구조에 대해 알아본다. 11.1 분산된 진흙 공, 명사로 생각하기 보통 시스템의 이벤트를 명사로 나눈다. 재고 배치, 주문, 상품, 고객 등이다. 행위가 아닌 말그대로 명사 기준이다. 할당보다는 배치로 표현한 것이 이에 해당한다. 정상 경로를 예시로 들어보면 아래와 같이 진행된다. 사용자가 웹 사이트에 방문해 재고가 있는 상품을 선택한다.(주문) 상품을 장바구니에 담고 재고를 예약한다.(배치) 주문이 완료되면 예약을 확정하고 창고에 출.. 더보기
Architecture Patterns with Python(10장) 커맨드와 커맨드 핸들러 지난 9장에서 모든 유스 케이스 함수를 이벤트 핸들러로 변경했다. API 는 새 배치를 만드는 POST 를 받으면 새로운 BatchCreated 이벤트를 만들어서 내부 이벤트처럼 처리한다. 위의 workflow 는 직관적으로 봤을 때 조금 어색함이 느껴진다. 배치가 생성되지 않은 상태에서 먼저 BatchCreated 라는 이벤트가 생성되고, 그 후에 배치가 진짜로 생성된다. 그렇다면 이름을 단순히 CreateBatch 로 바꾸면 될까? 여기서 사용되는 개념이 바로 커맨드(command) 라는 개념이다. 이번 챕터에서는 메시지를 다루는 방법 중, 커맨드와 이벤트를 활용하여 기존 코드를 리팩토링 해본다. 10.1 커맨드와 이벤트 이벤트와 마찬가지로 커맨드도 메시지의 일종이다. 시스템의.. 더보기
Architecture Patterns with Python(9장) 메시지 버스를 타고 시내로 나가기 8장에서 만든 메시지 버스를 보다 근본적인 요소로 만들어본다. 메시지 버스가 서비스 계층의 주 진입 지점으로 만든다. 9.1 새로운 아키텍처가 필요한 새로운 요구 사항 다음의 예기치 못한 상황이 발생했다고 가정해본다. 재고 조사를 하는 동안 지붕에 물이 새서 SPRINGY-MATTRESS 3개가 손상된 것을 발견했다. RELIABLE-FORK 배송에서 필요한 문서가 빠져서 몇 주 동안 세관에 머물러야 했다. 이후 RELIABLE-FORK 3개가 안전 검사에서 실패해 폐기했다. 세계적으로 반짝이는 금속이 부족해져서 다음 SPARKLY-BOOKCASE 배치를 생산할 수 없게 됐다. 이런 유형의 상황을 통해 시스템에 있는 배치 수량을 변경해야 한다는 사실을 알게 됐다. 시스.. 더보기
Fluent Python (챕터 9) - 파이썬스러운 객체 9.1 객체 표현 repr() : 객체를 개발자가 보고자 하는 형태로 표현한 문자열로 반환한다. str() : 객체를 사용자가 보고자 하는 형태로 표현한 문자열로 반환한다. repr(), str() 메서드를 지원하려면 각각 __repr__(), __str__() 매직 메서드를 구현해야 한다. 객체를 표현하는 다른 방법을 지원하는 __bytes__(), __format__() 매직 메서드도 있다. __bytes__() 는 __str__() 과 비슷하지만 bytes() 메서드에 의해 호출되어 객체를 바이트 시퀀스로 표현한다. __format__() 은 내장 함수 format() 과 str.format() 메서드 둘 다 사용하며, 특별 포맷 코드를 이용해서 객체를 표현하는 문자열을 반환한다. 9.2 벡터 클.. 더보기
Architecture Patterns with Python(8장) 이벤트와 메시지 버스 비즈니스 로직을 만족하는 요소가 구현된 이후에, 무언가를 끼워 넣어야 하는 경우에는 아키텍처를 어떻게 유지할 수 있을까 도메인 이벤트 패턴과 이벤트에 대한 메시지 버스 패턴을 활용하는 방법을 예시로 알아본다. 앞서 계속해서 예제로 사용했던 주문과 배치 코드에서 재고가 없는 경우, 구매팀에 이메일로 통지하는 로직을 추가하려고 한다. 일반적으로 이러한 요구 사항이 생기면, 별 생각 없이 웹 컨트롤러에 넣기 쉽다. 8.1 지저분해지는 일 막기 8.1.1 웹 컨트롤러가 지저분해지는 일을 막자 @app.route("/allocate", methods=["POST"]) def allocate_endpoint(): line = model.OrderLine( request.json["orderid.. 더보기
Fluent Python (챕터 8) - 객체 참조, 가변성, 재활용 8.1 변수는 상자가 아니다. 흔히들 변수를 상자로 비유한다. 어떠한 값을 변수에 할당하면 변수라는 상자에 그 값이 들어간다고 표현한다. 하지만 이는 잘못된 비유다. 상자보다는 포스트잇에 빗대는 것이 더 명확한 비유라고 볼 수 있다. 단지 어떠한 값(객체) 에 이 값의 별명이 무엇이라고 포스트잇을 붙여 놓는 것과 같다. a = [1, 2, 3] b = a a.append(4) print(b) > [1, 2, 3, 4] 변수를 어떤 값을 담고 있는 상자라고 생각하면 위의 코드를 설명할 수 없다. a와 b는 서로 다른 상자임에도 a 에 추가한 값이 b 에도 들어가 있기 때문이다. 비슷한 맥락에서 할당에 관하여 어떠한 객체에 대해서 얘기할 때, '변수 s 가 객체에 할당되었다' 라고 하는 것이 '객체가 변수 .. 더보기