본문 바로가기

분류 전체보기

(117)
Bulk Insertion과 ORM 최적화 기존에 location과 place를 create_or_get할 때, 인스턴스 하나당 개별적으로 요청을 보내서 확인하는 작업을 진행했다. 시간이 되면 이를 개선하여 한 번의 요청으로 모든 데이터를 확인하고 생성하는 로직으로 변경하려고 생각하고 있었는데 place 와 location 관계를 다시 복구 하면서 같이 리팩토링하게 되었다. location은 비교적 간단히 처리할 수 있었지만, place 모델은 내부에 place_type 모델과의 관계가 있었기 때문에 생각보다 시간이 걸렸다. 솔직히 시간좀 잡아 먹었다. 그래서 처음에는 하다가 그냥 또 빠르게 바꿀까 해서 add_all을 생각했지만, 이건 사실상 기존에 하던 로직이랑 다를바가 없어서 스스로를 다독여 유혹에 빠지지 않고 작업을 계속 진행 했다. 처음..
애그리게이트와 일관성 경계 여기서는 도메인 모델을 다시 살펴보면서 불변조건과 제약에 대해 살펴보고, 도메인 모델 객체가 개념적으로나 영속적 저장소 안에서나 내부적인 일관성을 유지하는 방법을 살펴본다. 그리고 일관성 경계를 설명하고, 일관성 경계가 어떻게 유지보수 편의를 해치지 않으면서 고성능 소프트웨어를 만들 수 있게 해 주는지 살펴본다 스프레드 시트로 처리하면 안돼? 스프레드 시트 사용하면 여러 조건들을 즉 시스템의 복잡한 제약을 유지하기 어려워 규모 확장이 힘듦. 제약, 불변조건 그래서 도메인 로직의 일부는 이런 제약을 강제로 지키게 해서 시스템의 불변조건을 유지하려는 목적으로 작성됨. 불변조건을 보니까 실용주의 프로그래머가 떠올랐다. 아무튼. 제약과 불변조건은 비슷해 보이지만 비교해 보자면 제약은 모델이 취할 수 있는 상태의..
작업 단위 패턴 저장소 패턴이 영속적 저장소 개념에 대한 추상화라면 작업 단위 패턴은 원자적 연산이라는 개념에 대한 추상화. 서비스 계층에서 직접 세션과, 저장소를 불러서 작업하지 않게 해 줌으로써, 서비스 계층과 각 계층을 분리시켜줌. 책에서는 컨텐스트 매니저를 통해 구현했다. 근데 이게 뒤에서도 나오는데 기존에 세션이 하는 걸 한번 wrapping 한 느낌이다. 왜 그런지 밑에서 설명하고 그 차이와 트레이드오프를 말해준다. 밑에 예제만 봐도 알겠지만 서비스 로직를 트랜잭션 처리했다. 그 과정에서 uow는 필요한 모든 걸 갖고 있고 외부에서 호출하는 caller는 그냥 얘만 인자로 넘기면서 서비스를 호출하면 된다. 책 예제 class SqlAlchemyUnitOfWork(AbstractUnitOfWork): def _..
서비스 계층과 도메인 서비스 흔히 말하는 서비스 계층은 애플리케이션 서비스 계층인데 외부에서 오는 요청을 처리해 연산을 오케스트레이션한다. 즉 서비스 계층이 다음과 같은 간단한 단계를 수행하여 애플리케이션을 제어한다는 의미. 데이터베이스에서 데이터를 얻는다. 도메인 모델을 업데이트한다 변경된 내용을 영속화 한다. 비즈니스 로직과 분리하면 프로그램을 깔끔하게 유지하는 데 도움이 된다. 두번째는 도메인 서비스. 도메인 모델에 속하지만 근본적으로 상태가 있는 엔티티나 값 객체에 속하지 않는 로직을 부르는 이름임. 여기서 예를 들면 쇼핑카트 어플리케이션에서 세금 관련 규칙을 구현한다면. 이건 쇼핑 카트 업데이트 작업과는 별개다. 중요한 부분이지만 세금만을 위한 영속적인 엔티티를 사용하는 것은 바람직하지 않음. 대신 상태가 없는 TaxCal..
결합과 추상화 파이썬으로 살펴보는 아키텍처 패턴을 보다가 3장 부분에 종종 생각하던 부분이 있어서 정리해 봤다. 테스트에 관련한 부분이다. 추상화에 대한 이야기를 하는데, 설계를 위한 추상화다. 그리고 테스트는 그 설계를 위함이 우선이라고 한다. 그래서 첫 번째는 그냥 돌아가게 구현하고 리팩터링 하는 식으로 이어지는데, 테스트를 위해 다른 방식으로 구현하는 예시도 보여준다. 3.3 선택한 추상화 구현 중요 로직을 명확하게 빼서 추상화하는데 여기 예시의 구현을 간단히 정리하면 외부 상태에 대해 아무 의존성이 없는 코드의 '핵' 을 만들고 외부 세계를 표현하는 입력에 대해 핵이 출력한 걸 처리한다. 그니까 중요 비즈니스 로직을 추상화해서 따로 빼놓는다. 이렇게 예시를 직접 보니까 추상화를 하면 테스트하기가 훨씬 쉬워지는 ..
저장소 패턴 저장소 패턴은 데이터 저장소를 간단히 추상화한 것으로 이 패턴을 사용하면 모델 계층과 데이터 계층을 분리할 수 있다. 내가 기존에 알기로는 레포지토리 패턴은 데이터 액세스의 추상화를 제공하는 반면, ORM은 객체와 데이터베이스 테이블 간의 매핑을 담당한다고 알고 있는데, 이 둘의 구현 자체도 의존성을 역전시키는 형태로 구현하는 방식에 대해 알게 되었다. 예전에 저장소 패턴이랑 ORM에 대해서 알게되었을때는 어차피 ORM이 영속성을 추상화 하는데 뭐하러 저장소 패턴을 또 쓰지? 뭔가 캡슐화를 통해 유연하게 만들기 위해서 계층을 한번더 만드나 보다~ 라고만 생각하고 넘어 갔었다. 근데 이 책에서 구체적으로 왜 구현하는지 그리고 어떻게 구현하는지가 나와서 이해하는데 많은 도움이 되었다. 더군다나 저장소 패턴을..
API 요청 모듈 계층 분리 과정 Meet-up-spot이라는 만남 장소 추천 웹애플리케이션 프로젝트를 혼자 진행한다고 정신이 없었는데, 정신이 없어서 그랬는지 프로젝트하면서 섣부르게 진행한 부분에서 수정할 부분을 발견했다. 원래는 구글 maps api 요청을 직접 보내는 모듈을 작성해서 작업하고 있었는데, 보니까 애초에 라이브러리가 있더라. 아무리 그래도 너무 급하게 진행했던 거 같다. 근데 보면 라이브러리가 최근 api를 반영을 못해서 만약 사용한다고 해도 직접 요청 보내는 부분도 필요할거 같아 보였다. 사실 기능만 같으면 예전 것을 써도 되는데 테스트하는 과정에서 안 되는 게 있어서 일단 최근 api 테스트해보고 확정 지어야겠다. 그리고 이건 계속 사용하면서 불편했던 부분이기도 한데, 카카오 맵이 api가 더 간단해 보여서 바꿀까 ..
MySQL 퍼포먼스 최적화 (1~3장) 1.MySQL의 특징 1.1 MySQL은 전체적으로 어떻게 생겼나 1.1.1 서버엔진 DB가 SQL을 이해할 수 있도록 쿼리를 재구성하는 ‘쿼리 파싱’ 과 디스크나 메모리 같은 물리적인 저장장치와 통신하는 스토리지 엔진에 데이터를 요청하는 업무를 담당 또한 스토리지 엔진에서 받아온 데이터를 사용자 요청에 맞게 처리하거나 접근 제어, 쿼리 캐시, 옵티마이저 등의 역할을 수행한다. 즉, 물리적인 저장장치와 직접적으로 통신하는 역할을 제외하고 사용자와 MySQL 사이에서 발생하는 데이터 처리 프로세스의 대부분을 담당한다 스토리지 엔진이 물리적인 저장장치에서 데이터를 읽어오는 역할을 수행한다면, 서버엔진은 스토리지 엔진에서 가져온 데이터를 처리하는 역할을 담당한다. Table join Group By Order..