목록개발 (44)
넘치게 채우기
int INT_MAX = (unsigned int) -1 >> 1; 본론부터 말하자면, 위와 같다. 1을 4비트 + 부호비트로 표현하면, 00001이다.-1은? 2의 보수를 취하여 11111이다. unsigned로 형변환하면서, MSB인 부호 비트도 수 표현 비트로 바뀌면서, -1은 1이 32개 나열된 비트로 바뀐다.이 값에서 다시 오른쪽 시프트 연산을 하여 최하위 비트를 자르면? 1이 31개 나열된 채로, 2^31-1로 된다. 즉, INT_MAX의 값이 된다.
테스트는 시스템의 일부이며, 아키텍처에도 관여한다. 시스템 컴포넌트인 테스트 테스트는 시스템의 일부인가? 아니면 별개인가? 어떤 종류의 테스트가 있는가? 단위 테스트와 통합 테스트는 서로 다른가? 인수 테스트, 기능 테스트, Cucumber 테스트, TDD 테스트, BDD 테스트, 컴포넌트 테스트 등은 어떻지? 아키텍처 관점에서는 모든 테스트가 동일하다. TDD로 생성한 아주 작은 테스트이든, 아니면 대규모의 테스트이든, 이들 테스트는 아키텍처적으로 모두 동일하다. 테스트는 태생적으로 의존성 규칙을 따른다. 테스트는 세부적이며 구체적인 것으로, 의존성은 항상 테스트 대상이 되는 코드를 향한다. 실제로 테스트는 아키텍처에서 가장 바깥쪽 원으로 생각할 수 있다. 시스템 내부의 어떤 것도 테스트에는 의존하지 ..
서비스 지향 ‘아키텍처’와 마이크로서비스 ‘아키텍처’는 최근에 큰 인기를 끌고있다. 서비스를 사용하면 상호 결합이 철저하게 분리되는 것처럼 보인다. 나중에 보겠지만, 이는 일부만 맞는 말이다. 서비스를 사용하면 개발과 배포 독립성을 지원하는 것처럼 보인다. 나중에 보겠지만, 이 역시도 일부만 맞는 말이다. 서비스 아키텍처? 먼저 서비스를 사용한다는 것이 본질적으로 아키텍처에 해당하는지에 대해 생각해 보자. 이 개념은 명백히 사실이 아니다. 시스템의 아키텍처는 의존성 규칙을 준수하며 고수준의 정책을 저수준의 세부사항으로부터 분리하는 경계에 의해 정의된다. 단순히 애플리케이션의 행위를 분리할 뿐인 서비스라면 값비싼 함수 호출에 불과하며, 아키텍처 관점에서 꼭 중요하다고 볼 수는 없다. 모든 서비스가 반드시 ..
모든 시스템에는 최소한 하나의 컴포넌트가 존재하고, 이 컴포넌트가 나머지 컴포넌트를 생성하고, 조정하며, 관리한다. 이 컴포넌트를 밥 아저씨는 메인(Main)이라고 부른다. 궁극적인 세부사항 메인 컴포넌트는 궁극적인 세부사항으로, 가장 낮은 수준의 정책이다. 메인은 시스템의 초기 진입점이다. 운영체제를 제외하면 어떤 것도 메인에 의존하지 않는다. 메인은 모든 팩토리와 전략, 그리고 시스템 전반을 담당하는 부분으로, 제어권을 넘기는 역할을 맡는다. 의존성 주입 프레임워크를 이용해 의존성을 주입하는 일은 바로 이 메인 컴포넌트에서 이뤄져야 한다. 메인에 의존성이 일단 주입되고 나면, 메인은 의존성 주입 프레임워크를 사용하지 않고도 일반적인 방식으로 의존성을 분배할 수 있어야 한다. 메인을 지저분한 컴포넌트 ..
시스템이 세 가지 컴포넌트(UI, 업무 규칙, 데이터베이스)로만 구성된다고 생각하기 쉽다. 몇몇 단순한 시스템에서는 이 정도로 충분하다. 하지만 대다수는 이보다 훨씬 많다. 움퍼스 사냥 게임 1972년 발매된 움퍼스 사냥을 생각해보자. 텍스트를 기반으로 하는 이 게임은 Go East 와 Shoot West와 같은 매우 단순한 명령어를 입력한다. 플레이어는 명령어를 입력하며, 컴퓨터는 플레이어가 보고, 냄새 맡고, 듣고, 경험할 것들로 응답한다. 텍스트 기반 UI는 그대로 유지하되, 게임 규칙과 UI를 분리해서 우리 제품을 여러 시장에서 다양한 언어로 발매할 수 있게 만든다고 해보자. 게임 규칙은 언어 독립적인 API를 사용해서 UI 컴포넌트와 통신할 것이고, UI는 API를 사람이 이해할 수 있는 언어로..
마지막 단계를 건너뛰기 부분적 경계를 생성하는 방법 하나는 독립적으로 컴파일하고 배포할 수 있는 컴포넌트를 만들기 위한 작업은 모두 수행한 후, 단일 컴포넌트에 그대로 모아만 두는 것이다. 쌍방향 인터페이스도 그 컴포넌트에 있고, 입출력 데이터 구조도 거기에 있으며, 모든 것이 완전히 준비되어 있다. 하지만 이 모두를 단일 컴포넌트로 컴파일해서 배포한다. 아무리 보아도 이처럼 부분적 경계를 만들려면 완벽한 경계를 만들 때 만큼의 코드량과 사전 설계가 필요하다. 하지만 다수의 컴포넌트를 관리하는 작업은 하지 않아도 된다. 추적을 위한 버전 번호도 없으며, 배포 관리 부담도 없다. 이 차이는 가볍지 않다. 일차원 경계 완벽한 형태의 아키텍처 경계는 양방향으로 격리된 상태를 유지해야 하므로 쌍방향 Bounda..
프레젠터는 험블 객체 패턴을 따른 형태로, 아키텍처 경계를 식별하고 보호하는 데 도움이 된다. 험블 객체 패턴 험블 객체 패턴은 디자인 패턴으로, 테스트하기 어려운 행위와 테스트하기 쉬운 행위를 단위 테스트 작성자가 분리하기 쉽게 하는 방법으로 고안되었다. 아이디어는 매우 단순하다. 행위들을 두 개의 모듈 또는 클래스로 나누다. 이들 모듈 중 하나가 험블(humble)이다. 가장 기본적인 본질은 남기고, 테스트하기 어려운 행위를 모두 험블 객체로 옮긴다. 나머지 모듈에는 험블 객체에 속하지 않은, 테스트하기 쉬운 행위를 모두 옮긴다. 예를 들어 GUI의 경우 단위 테스트가 어려운데, 화면을 보면서 각 요소가 필요한 위치에 적절히 표시되었는지 검사하는 테스트는 작성하기 매우 어렵기 때문이다. 하지만 GUI..
육각형 아키텍처(Hexagonal Architecture): 포트와 어댑터라고도 알려졌으며, 앨리스터 코오번이 개발했다. 그리고 스티브 프리먼과 냇 프라이스가 그들의 훌륭한 저서인 에서 차용했다. DCI(Data, Context and Interaction): 제임스 코플리언과 트리그배 린스쿠주가 만들었다. BCE(Boundary-Contorl Entity): 이바 야콥슨이 자신의 저서인 이들 아키텍처는 모두 세부적인 면에서는 다소 차이가 있더라도 그 내용은 상당히 비슷하다. 이들의 목표는 모두 같은데, 바로 관심사의 분리(seperation of concerns)다. 이들은 모두 소프트웨어를 계층으로 분리함으로써 관심사의 분리라는 목표를 달성할 수 있었다. 각 아키텍처는 최소한 업무 규칙을 위한 계층 ..
건물의 청사진을 살펴보고 있다고 상상해 보자. 이 문서는 아키텍트가 작성했고 건물에 대한 일련의 계획을 보여주고 있다.이 계획서는 무슨 이야기를 해 주는가? 그 계획서가 한 가족이 거주할 주택을 그리고 있다면, 정문, 거실로 연결되는 현관, 그리고 식당 역시 볼 수 있을 것이다. 식당 가까이에 주방이 있을 것이고, 아마 주방 근처에는 간이 식탁이 있고, 바로 붙어서 가족 방이 있을 가능성이 높다. 이러한 계획서를 본다면 한 가족이 사는 주택을 보고 있다는 사실에 의심의 여지가 없을 것이다. 다시 말해, 이 아키텍처는 “집이야”라고 소리칠 것이다. 이제 도서관의 아키텍처를 보고 있다고 가정해 보자. 커다란 정문, 체크인과 체크아웃을 담당할 사서를 위한 공간, 독서 공간, 작은 회의실, 도서관의 장서를 모두..
애플리케이션을 업무 규칙과 플러그인으로 구분하려면 업무 규칙이 실제로 무엇인지를 잘 이해해야만 한다. 업무 규칙에는 여러 가지가 있다. 엄밀하게 말하면 업무 규칙은 사업적으로 수입을 얻거나 비용을 줄일 수 있는 규칙 또는 절차다. 더 엄밀하게 말하면 컴퓨터상으로 구현했는지와 상관없이, 업무 규칙은 사업적으로 수입을 얻거나 비용을 줄일 수 있어야 한다. 심지어 사람이 수동으로 직접 수행하더라도 마찬가지다. 이러한 규칙을 핵심 업무 규칙(Critical Business Rule)이라고 부를 것이다. 왜냐하면 이들 규칙은 사업 자체에 핵심적이며, 규칙을 자동화하는 시스템이 없더라도 업무 규칙은 그대로 존재하기 때문이다. 핵심 업무 규칙은 보통 데이터를 요구한다. 예를 들어 대출에는 대출 잔액. 이자율, 지급 ..