불평을 경계하라

우리는 살면서 너무도 많은 ‘불평’을 한다. 미용실에서 자른 머리가 내 마음에 들지 않을때, 직장에서 상사가 내게 터무니 없는 요구를 하는 것 같을때, 우연히 들른 식당이 맛이 없을 때, 원하던 시험에서 떨어졌을 때 처럼 많은 사소하고 큰 일에서 우리는 불평을 늘어 놓는다. 이런 불평의 대상은 대게는 나 스스로 이지만 때로는 내가 아닌 다른 사람이 되기도 한다.

많은 훌륭한 사람들, 좋은 책들에 하나 같이 우리에게 불평을 하지 말라고 가르치지만, 그 말만 듣고 이것을 실천하기에는 너무 사소하고 무턱대고 그 말들에 따르기에는 구체적인 이유도 사실 알지 못한다.

이번 포스트에서는 우리가 불평을 하는 이유, 또 불평이 우리에게 미치는 영향에 대한 나의 주관적인 생각을 담아보고자 한다.

우리는 왜 불평을 하는가?

우리가 불평을 하는 이유는 지금 벌어지고 있는 일에 대한 책임을 나에게로 돌리기 위함이다.
시험에서 떨어지거나 직장에서 질책을 받거나 하던 사업이 안되는 경우 우리는 불평이라는 간편하고 달콤한 해결책을 찾는다. 시험을 준비한 시간이 짧아서 떨어졌다거나 혹은 직장 동료가 내 의도를 정확히 이해하지 못했다거나 시장이 너무 불황이어서 사업이 망했다는 불평처럼 우리는 우리의 실패를 우리가 통제하지 못하는 상황 에 대해 불평함으로써 우리 주변사람들에게 “나를 공격 하지 마시오!” 라는 선전포고를 하는 것이다. 때문에 많은 경우 우리가 하는 불평들은 제 3자가 볼 때 논리적으로 반박하기 어려운 경우가 많고, 스스로도 과거의 많은 일들이 어쩔 수 없는 결과로 귀결되었음에 안도 아닌 안도, 위안 아닌 위안을 얻고는 한다.

때로 많은 사람들은 사실 불평을 하는 그 사실에 대한 정확한 이유와 원인을 마음 속 깊은 곳에 이해하면서도 다른 사람에게 다른 불평을 하곤 하는데, 이를 통해 그들은 주변 사람들로 부터 스스로를 방어할 수 있게 된다.

불평의 마법

짧은 순간이지만 불평은 우리의 마음을 편안하게 해 준다. 답답했던 마음도 불평한마디 툭 던지고 잘못된 상황 탓이거니 하면 마음이 편해지고 잘못된 것은 전부 바깥 세상 탓인것만 같다. 불평의 마법은 이때부터 시작된다. 사실 불평이란 한낱 단어들의 조합이자 생각없이 내뱉는 달콤한 담배 한모금과 같은 것이지만 지속적인 불평은 어느덧 우리 마음을 심각하게 손상시킨다. 우리가 통제하지 못하는 상황 에게 모든 책임을 돌려버린 탓에 우리 스스로 우리가 불평을 한 대상에 우리가 할 수 있는 것은 없다고 선언해 버린 것이다. 이 선언은 마음속 깊은 곳에 잠식하고 우리 스스로 만들어 낸 통제하지 못하는 상황속에 우리를 가두어 버린다. 가령 사법고시에 떨어진 뒤 ‘사법고시는 정말 말도안되. 천재가 아니면 붙을 수 없다니까?’ 라는 한마디의 말은 시간이 지남에 따라 내 머릿속의 확고한 진실로 자리잡는 것이다. 이것이 바로 불평의 마법이다. 한 마디의 불평의 우리의 무한한 가능성을 서서히 잠식해 나간다.

불평의 마법에서 벗어나기

흔히 ‘사람의 그릇’ 이라는 말을 하고는 한다. 필자는 이 단어를 너무도 싫어하고 허세가 가득한 단어임에 분명하다고 생각하지만, 필자가 생각하는 그 ‘사람의 그릇’ 이란 불평의 정도 정도로 해석될 수 있다고 생각한다. 불평의 마법 을 통해 우리 스스로를 통제하지 못하는 상황속에 가두고 책임감을 털어낼 수 있지만, 그만큼 세상을 향한 가능성을 담는 우리의 그릇을 점점 작아지게 함이 그 까닭이다.

그래서, 필자가 생각하는 불평의 마법에서 벗어나는 방법은 조금 답답하게 살아가는 것이다. 때로는 한마디 툭 뱉고 싶은 불평을 참고 침착하게 정말 불평의 원인을 탐색해 나가야 한다.

“왜 나는 지금 불만이 있는 것일까? 어떻게 하면 앞으로는 내가 이런 불만을 가지지 않을 수 있을까?”

라는 생각을 계속 하는 것은 그 순간은 정말 답답한 순간이 아닐 수 없지만, 이렇게 조금 묵직한 어깨를 가지고 불평의 순간들을 마주하게 된다면 멀지 않은 미래에 우리는 세상의 모든 가능성을 담을 넉넉한 그릇을 가지게 될 것임을 믿어 의심치 않는다.

묵직한 어깨를 가진 사람이 되기 위하여

늘 그렇듯이 오늘의 포스팅도 필자 자신에 대한 성찰이 많이 반영된 글이다.
하루 하루 열심히 살아나가고, 하루 하루 부족한 부분을 체워가고 있지만 가끔은 이렇게 불평한마디 툭 던지고 책임감을 내려놓고 홀가분한 마음으로 살아가고 싶을 때가 있고, 또 자주 그래온 것이 사실이다.

하지만, 매번 툭 던져온 이 불평이란 것이 스스로를 좀 먹이고 있음을 느끼고 다시한번 마음을 다잡고자 이렇게 글을 써내려 간다.

이 글을 읽는 독자들도 필자와 같이 불평의 달콤함에 빠져든 기억이 있다면, 불평의 달콤함 보다는 묵직한 책임감의 어깨를 가지고 세상의 모든 가능성을 한껏 받아들여 성장해 나가길 기원한다.


Javscript의 Date Object와 다양한 활용법에 대해 알아보자.

웹사이트를 만들거나 다양한 작업을 함에 있어서 정확한 ‘날짜 표기’ 는 매우 중요하며 이는 js에서 Date Object를 통해 구현된다.
이번 포스트에서는 Date의 내장 함수와 그에 따른 활용법에 대해 알아본다.

Create date object

다음과 같은 방법으로 date object를 생성할 수 있다.

1
var date = new Date("2018-4-30");

이처럼 생성 시점에 날짜를 전달 함으로써 그 날에 해당하는 date object를 반환받을 수 있으며, 다음과 같이 다양한 형태의 날짜를 입력하여도 올바른 반환값이 나온다.

1
var date = new Date()

‘천재’란 누구인가?

천재란 일반적으로 일반적인 인간에 비해 압도적으로 강력한 능력을 타고난 자로 여겨지고, 다르게 말하면 일반적인 사람과는 ‘경쟁’ 자체가 무의미한 특별한 사람이라고 우리에게 여겨지기도 한다. 수영 천재, 피겨 스케이팅 천재, 컴퓨터 천재 등등 우리는 살면서 ‘천재’ 라는 말을 너무도 자주 듣게되고 가끔은 이 세상엔 왜 이렇게 천재들이 많을까 하는 무력감을 느끼며 ‘경쟁 할 수 없는 일반인’ 이라는 굴레 안에 스스로 들어가 버리기도 한다.

하지만, 필자는 모든 사람은 누구나 자신의 분야에서 천재가 될 수 있다고 생각하며 철저히 주관적으로 ‘천재’에 대해 재해석 해 보고자 한다.

필자가 생각하는 ‘천재’란 다음과 같이 요약할 수 있겠다.

1
천재란 자신의 운명을 걸머쥐고 모든 것을 쏟아 부을 지향점을 가지고 실천하며, 그에 따른 결과에 책임을 질 수 있는 용기를 가진 사람이다.

사실 이렇게 천재에 대한 단편적으로 정의는 너무 추상적이고 비현실적이라는 생각이 들 수 있다.

또 어떻게 보면’천재’를 너무 과소평가 하는 것이 아닌가 생각이 들 수도 있다.

가령 예를 들어보자.

상대방에 대한 사랑에 인생을 불사른 로미오와 줄리엣,

필자는 무언가 ‘특별한’ 두뇌 혹은 재능을 가지는 사람들의 존재는 인정하지만 우리가 흔히 말하는 많은 천재들 즉, 영화 속 주인공, 예술가, 기업가 들은 사실상 일반인과 크게 다르지 않은 똑같은 인간이라고 생각하
어쩌면 영화 속의 주인공들, 희대의 로맨티스트, 예술가, 기업가 들은 모두 ‘천재’라는 한가지의 범주로 요약 될는지도 모른다.

사회적 책임, 도덕적 관념, 모든 나를 구속한다고 핑계대는 제약들이 없어진 상태 내게 아무런 의무도 지워지지 않고 금전적 제약도 심지어 법의 제약도 없어진 그런 상태로 내일을 맞이한다면 나에게 무엇을 하고 싶은 지를 묻는 다면 나는 무어라고 대답한단 말인가.

“무언가 큰 일을 하고싶다. 수억 명의 사람들을 기쁘게 하고 내 주변 사람들이 행복해 하고, 어떤 완벽한 이상사회로 이 사회와 세계가 진행중이라면 그 사회의 도래에 공헌 할 수 있는 그런 세계 변화의 흐름을 잡고 흔들 수 있는 그런 위대한 일을 하고싶다.”

이 따위 대답에 내가 부응하기 위해서는 그러기 위해서는 지금 당장 나는 어떤 일을 하고 있다고 말해야 하나. 그저 그 일을 찾는 것? 절박함이 없다. 반드시 대의를 이루겠다는 나는 하루하루 매시간 매초 온 힘을 다해 이를 고민해야 한다.

Installation

윈도우
https://github.com/golang/dep/releases

위 링크를 통해 설치를 진행한 뒤 해당 .exe 파일을 go rootpath의 bin 폴더 안에 넣어준다.

프로젝트 폴더 포팅

dep을 사용하기 위해서는 반드시 다음과 같은 구조로 폴더를 만들고 포팅해야 한다.
GOPATH/src/github.com/directory/projectname

download

1
dep ensure

참조

GRPC란 무엇인이며 어떻게 동작하는가?

GRPC란 google에서 제공하는 rpc 프로토콜 프레임워크이다.
이를 통해 간편하게 클라이언트와 서버 간에 rpc 통신을 할 수 있게 해준다.

grpc의 간략한 동작 순서는 다음과 같다.

  • 서버에서 grpc server가 listen을 하고 있다.
  • 클라이언트에서 gRPC stub을 통해 서비스에 접근한다.
  • 서버에서 gRPC stub 명령을 받아 수행 후 클라이언트에 반환해 준다.

gRPC를 통해 간편하게 server를 만들어 listen을 수행하고, 이를 호출하는 client 프로그램을 만들어 RPC 통신을 한다.

RPC 통신이란?

Remote Procedure Call 의 약어로 다른 컴퓨터에 있는 특정 method를 마치 자신의 컴퓨터에 있는 것처럼 호출하는 것으로 분산 어플리케이션과 서비스를 만드는데 중요한 역할을 한다.

grpc에서는 데이터 전송을 위한 marshal를 위해 protocall buffer를 사용한다.

protocall buffer란?

protocall buffer란 어떤 언어와 플랫폼에서도 사용가능하고 확장성이 좋으며, 통신 프로토콜이나 데이터 저장등에 사용하기 위해 정형화된 데이터를 serializing 할 수 있는 좋은 방법이다.
protocall buffer 에서는 serialize 하고자 하는 구조체가 .proto 파일에 메세지의 형태로써 정의되어야 한다.

이러한 .proto file은 protoc 컴파일러를 통하여 접근 가능한 객체로 변환되고, 각 언어에 맞는 protoc가 존재한다.

.proto 파일의 예

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
message Person {
required string name = 1;
required int32 id = 2;
optional string email = 3;

enum PhoneType {
MOBILE = 0;
HOME = 1;
WORK = 2;
}

message PhoneNumber {
required string number = 1;
optional PhoneType type = 2 [default = HOME];
}

repeated PhoneNumber phone = 4;
}


Event Sourcing

이벤트 소싱이란 기존의 관계형 데이터베이스의 저장 방식과 달리 데이터 저장을 수많은 이벤트들을 묶음으로 저장하는 것을 의미한다.
사실 event sourcing 이란 사실 현실에서는 너무도 흔한 방법이다. 가령 회계장부를 기록한다고 할때 우리는 회사의 보유 자금을 현재 상태만을 기록하는 것이 아니라 과거 매출, 비용 등의 합산으로 계산한다. 그래야 과거의 정보가 투명하게 공개되고 다양한 재무 데이터의 활용이 가능하기 때문이다. 이처럼 실제 행위의 집합들을 저장하는 방식을 event sourcing이라 한다.

하지만, 다음과 같은 경우를 생각해보자
만약 과거의 데이터를 수정해야 할 일이 생긴다면 어떨까?
이 경우도 실제 회계에서 하는 방법과 같은 원칙을 따른다. 바로 과거의 특정 기록으로 돌아가 해당 부분만을 수정하고 뒤를 전부 다시 작성하는 것이다. 이는 매우 비효율 적이어 보이지만 데이터 그 자체가 매우 중요한 회계에서는 너무도 당연한 진리이다.

이는 데이터 혹은 이벤틀의 삭제에도 영향을 주는데, event soucing에서는 원칙적으로 delete가 없다. 이는 회계장부 작성과도 그 흐름을 동일시 하는데, 가령 회계장부를 작성할 때에는 잘못된 정보를 기입하면 그 후에 그를 상쇄시키는 추가적인 기록을 추가한다. 그래야만 누군가가 고의로 데이터를 조작했는데와 같은 정보들을 유추할 수 있기 때문이다. 동일한 논리가 event sourcing에서도 적용된다.

왜 이런 event sourcing이 현대 software에서 중요하게 되었을까?

그것은 바로 현대 사회에서 데이터의 가치가 너무도 중요하기 때문이다. 과거 쇼핑몰에서는 고객이 단순히 구매 혹은 판매 등의 정보만을 기록한 반면 요즘 사회에서는 장바구니에 물건을 넣었다 빼는 빈도와 주기 시기 등에 대한 데이터를 활용하여 각종 비즈니스 정책들이 결정되며 이 모든 사소한 행위 데이터를 기록하는 것은 너무도 중요하고 그것이 event sourcing의 필요성이다.

이처럼 event sourcing을 통한다면, 특정 시기의 정확한 상황을 재현할 수 있는데, 가령 우리가 역사를 기록하는 것과 같은 원리이다. 특정 시기의 단편적 정보가 아닌 그 시기에 일어나는 일련의 사건들을 정확히 재구현 할 수 있을때 즉, 마치 타임머신을 타고 여행하듯이 정치 사회 경제에 대한 총체적인 재구성을 통해서만 그 시기의 명확한 사회적 상황을 알 수 있다. 이처럼 비즈니스 세계에서도 event sourcing을 통해 과거의 특정 상황에 대한 명확한 인사이트를 가질 수 있다.

이러한 event sourcing 은 소프트웨어 테스트 시에도 활용될 수 있다.
가령, 기존의 모든 테스트 행위를 event로 기록해 놓으면, 개발이 완료된 뒤에 정확히 같은 테스트를 수천번이고 반복해서 수행해 볼 수 있다.
가령 보험 서비스의 경우에 A 라는 사람의 주소가 바뀌면 Manager가 해당 주소가 바뀜을 알리고 회계부서, 지급 부서 등 많은 부서에 해당 사실을 알리고 로직을 처리해야 한다. 하지만 event 를 사용하면 그저 Manager는 쿨하게 “A의 주소가 바뀜!” 만을 외치면 기타 여러 부서에서 주의깊게 관찰하고 있다가 이벤트가 발생하면 그에 맞는 로직을 스스로가 처리하여 Manager의 독립성이 높아지게 된다.

그 순서는 다음과 같다.

  1. Command 발생
  2. Command Hander에 발생한 Command를 전달하고 event 발생
  3. aggregation 변형

CQRS 패턴이란?

위와 같은 event sourcing에 있어 데이터의 읽기와 쓰기는 너무도 다른 기능이다. 쓰기의 경우 특정 이벤트를 저장하는 아주 단순한 로직인데 반해 읽기의 경우 읽기의 구간 특정 시기의 스냅샷과 같은 복잡한 로직이 동반되는 경우가 다반사 이다.

CQRS에서는 이렇게 이벤트의 저장과 읽기를 위해 두 종류의 명령을 내리는데 하나는 데이터를 저장하는 Command 와 이벤트를 읽어 오는 query 이다.


나는 벤저민 프랭클린을 참 좋아한다.

철저한 자기관리와 건국의 아버지로 알려진 프랭클린, 나는 그의 자기 관리를 위한 노력이나 훌륭한 일을 하려 하는 긍지보다 다른 부분에 집중하고자 한다.

그것은 바로 그는 변치않는 신념과 스스로에 대한 믿음으로 묵묵히 자신의 길을 걸었다는 것이다.

주변의 시선과 자신이 처한 환경, 미래에 대한 불안에 대해 그는 거의 언급하지 않았다.

그저 자신이 처한 환경에서 조금 더 나아질 수 있는 방법을 찾았고, 끊임없이 내가 필요하고 더 나은 사람이 되기위해 정진해 나갔다.

인생을 살아가는 정도라는 것이 무의미해 지고, 한치앞을 내다 볼 수 없는 오늘의 사회에는 더욱더 가장 본받아야 할 점이 아닌가 생각된다.

흔히 인생을 살아나가는 것은 눈덮힌 산을 오르는 것에 비유된다.

가장 연륜있고, 실력있는 선구자는 우리를 앞서 오르고 대부분의 우리는 선구자가 남긴 발자국을 따라 오르며 끊임없이 내가 올바른 발걸음을 디뎠는지 생각한다.

내 눈앞의 수많은 발자국을 보며 어느 길이 가장 쉽고 효과적인 길인지를 가늠하려 하고, 내가 걸어온 발자국을 보며 산턱 언저리에서 후회와 불안에 이따금 뒤돌아 우두커니 서있는 것이다.

하지만, 정말 산을 잘 오르는 사람들은 오로지 정상만을 바라보고 오를 뿐이다.

우리 앞을 지나간 선구자는 물론 도움이 될 수 있지만, 그 사람이 어떤 상황에 있었는지 그때의 날씨는 어땠는지 우리는 알지 못하며, 가장 올바른 선택은 목적지에 시선을 던져두고 나를 믿고 신중하게 한걸음 한걸음을 옮기는 것인 것을 그들은 잘 아는 것이다.

요즘 세상을 무한 경쟁사회라고 한다.

주변을 달려가는 수많은 주자들을 바라보며 조바심을 느끼게 만드는 사회에서 많은 사람들이 고작 한치 앞에 있는 사람을 꽁무니 만을 쫓게도 되고, 한발작 뒤에 있는 주자들을 보며 가끔은 안도하기도 할 것이다.

이 글을 쓰는 필자도 또 마음을 다잡고자 이런글을 쓰는지 모른다.

오늘 하루도 앞서나가는 자에대한 조바심을 뒤따라 오는 자에 대한 오만함을 내려놓고 정상만을 바라보며 누구의 발자국도 아닌 나의 발자국을 남길 수 있는 하루, 내면의 단단함이 더해지는 하루가 되기를 바란다.


자료형이란 무엇인가요?

자료형이란 데이터를 표현하는 기준이 되며, 정수형 자료형, 혹은 실수형 자료형 인지 등의 데이터의 표현 기준을 정해주고, 명확한 데이터의 크기를 알려줌으로써 메모리에 보다 효과적으로 자료가 저장될 수 있도록 해줍니다.

대표적인 자료형으로는 char, int, float, double 등이 있으며 각각 1바이트, 4바이트, 4바이트, 8바이트의 크기를 가집니다.

이러한 자료형의 크기를 구하는 연산자로는 sizeof() 함수가 있으며 다음과 같이 사용합니다.

1
2
int num = 1
numSize = sizeof(num)

우리가 컴퓨터에서 표현하는 자료는 앞서 말했듯이 정수와 실수의 큰 기준으로 나뉘게 되며, 여기서 실수형을 표현하는 경우 정확도 향상을 위해 float 이 아닌 double을 사용 합니다.

또 어떤 자료형들이 있나요?

C 프로그래밍 시에 자료형 앞에 unsigned와 같은 키워드가 붙은 것을 많이 보았을 겁니다.
이 것은 바로 해당 자료형이 unsigned로 나타내는 것을 의미하며 즉, 음수를 구분하지는 못하지만 2배 더 큰 숫자까지 나타낼 수 있게 해주는 것을 의미합니다.

그밖에, 문자를 표현하기 위한 char 자료형이 있는데 이는 ASCII 코드에 의거하여 문자를 나타내는 것을 의미합니다.
이러한 ASCII 코드는 1바이트 즉 256가지의 문자를 표현하며, 기본적으로 컴퓨터 내에서 정수형 자료형으로 나타내어 지므로, 정수형 표현과 문자형 표현이 모두 가능합니다.

가령 다음의 예제를 살펴봅시다.

1
2
3
char examplChar = "a"

printf("%d", examplChar)

이 경우 문자 a의 정수형 표현을 ASCII 코드표에서 찾아 나타내어 줍니다.

상수란 무엇인가요?

상수는 int, double에 근거한 것으로 메모리 내에 이름이 없는 literal 상수와 이름이 있는 symbolic 상수로 구분됩니다.
이러한 상수는 한번 선언되면 그 값이 바뀔 수 없으며, 만약 이름이 있는 symbolic 상수로 선언되는 경우 이름은 대문자와 아래바 _ 로 구성되는 것이 일반적입니다.

다음의 예는 literal 상수의 예를 보여줍니다.

1
int exampleNum = 5 + 6

이렇게 literal 상수는 별도의 선언이 없이 값을 나타내며, 위의 경우 5와 6은 literal 상수입니다.

다음은 symbolic 상수의 예를 나타냅니다.

1
const int MAGIC_NUMBER = 1

이렇게 기본 자료형 int 앞에 const 키워드를 붙여 줌으로써 symbolic 상수를 선언하며, 선언과 동시에 초기화가 되어야 합니다.

만약 상수에 자료형을 지정해 주고 싶다면 어떻게 할까요?

다음은 상수 자료형에 float 으로 표기를 지정해 주는 예를 나타냅니다.

1
long exampleNum = 5.1235L

이처럼 상수의 뒤에 U, L, UL, LL, F 등을 나타냄으로써 자료형을 알려줄 수 있습니다.

자료형 형 변환

이렇게 한번 선언된 자료형은 프로그래밍 도중에 변경될 수 있으며 이것을 형 변환 이라고 합니다.

형변환 에는 자동으로 형이 변환되는 자동 형 변환 과 사용자가 형을 변환해 주는 강제 형 변환 이 있습니다.

먼저 자동 형 변환은 보통 자료형을 일치시켜 계산해야 하는 경우 또는 대입 시에 강제로 형 변환이 되는 경우, 연산 시 빠른 연산을 위해 CPU 에서 자동으로 변환이 되는 경우가 있습니다.

먼저 자료형 일치를 위한 자동 형 변환의 예를 살펴봅시다.

1
2
3
int num1 = 5
double num2 = 5.6235
double result = num1 + num2

위의 예의 경우 num1 과 num2 는 다른 자료형을 가졌기 때문에, 덧셈연산이 불가능 합니다.
이렇게 되면 컴퓨터는 자동으로 num1 과 num2 중 하나의 자료형에 맞추어 연산을 진행하게 되는데, 그 판단의 근거는 정확도를 높이는 방향 으로 진행된다는 것 입니다.

위 예의 경우 num1 과 num2 가 int 형으로 변환되어 계산이 된다면 큰 오차가 생기므로 적은 오차범위를 가지도록 둘 다 double 형으로 변환이 되어 계산이 되게 됩니다.

다음 예는 대입의 과정에서 자동 형 변환이 일어나는 경우입니다.

1
2
int num1 = 129
char result = num1

num1 은 int 형으로 선언이 되었지만 char 자료형에 할당됨에 따라 4바이트에서 1바이트로 그 크기가 줄어들게 됩니다.
이 경우에는 최상위 바이트의 손실이 일어나게 되며 이 경우 00000000 00000000 00000000 10000001 에서 10000001 로 바뀌게 되어 부호가 바뀌게 되는 문제가 생깁니다.

다음은 강제 형 변환 의 예를 살펴봅시다.

1
2
3
4
5
int num1 = 5
int num2 = 10
double result

result = (double)num1/num2

위 예는 num1과 num2의 연산을 통해 얻은 0.5를 double로 강제 형 변환 시켜주어 result에 할당하는 예를 보여줍니다.
이처럼 (자료형) 키워드를 앞에 붙여줌으로써 강제로 해당 자료형을 바꾸어 줄 수 있습니다.


루소의 [사회계약론]은 밖으로 표출된 정치 현실의 차원에서 문제를 제기하는 대신 정치적 질서의 기반, 다시 말해 그것의 배후의 메커니즘에 대한 원리적 접근을 시도하며, 나아가 정치적 권력 또는 권위의 정당성은 어떻게 획득되는가를 다루고 있다.

루소는 ‘폭력’이 최초의 노예를 만들어 내었고, 그 노예들의 비열함이 노예상태를 영속시킨다고 보았다.
사람은 사실 인간이기 이전에 동물로써 힘에 굴복하는 것은 어떻게 보면 불가피한 행위이기에 강한자가 약한자를 노예로 삼는 것을 막을 방법 따위는 없었다. 그것이 ‘자연의 법칙’ 이었고, 모든 생물학적 생태계의 ‘약육강식’의 법칙을 따르는 자연스러운 일이었다. 또, 약한자가 비열함을 벗어내는 방법은 목숨을 담보로한 도전 밖에 없었으며, 대부분의 경우는 죽음으로 귀결되었기에 노예상태는 영속되었다.

하지만, ‘힘과 권위’ 라는 것은 사실 시간이 지나면 사라지게 되는 것이고, 과거의 강한 힘을 가진 사람들도 늙고 노쇠해짐에 따라 과거의 모든 영광은 뒤로하고 냉혹한 자연의 질서에 굴복되어 버리기에, 대부분의 사람들은 대체로 좋은 결말을 맞이할 수 없는것이 현실이었다. 이렇게 시간이 지남에 따라 사람들은 이렇게 무자비한 ‘동물의 법칙’을 벗어나 상호간의 약속을 통해 삶의 질을 올릴 수 있는 방법을 찾게 되었고, 여기서 최초의 ‘사회 계약’ 이 이루어 지게 되었고, 공동체 라는 개념이 생겨나게 되었다.

공동체를 구성하는 각 구성원의 신체와 재산을 방어하고 ‘인간다운 삶’을 보장받기 위해 서로와 서로 사이에 계약을 하게 되고, 이를 통해 ‘공공의 힘’을 가지게 되어 각 개인은 그러한 ‘공공의 힘’으로 부터 보호 받고 자기 자신의 의지에 따라 한 ‘계약’ 에게만 복종함으로써 각 개인은 타인에게 복종을 하지 않는 자유로운 삶을 보장받을 수 있게 되었다. 즉, 과거처럼 ‘힘’에 의해 누군가의 노예가 되지 않을 수 있고, 자신이 혼자서 생존하기 어려운 많은 제약 속에서도 최소한의 인간적인 삶을 보장받게 되었으며, 이러한 공동체의 구성원들의 집합적인 의미로 국민, 주권에 참여하는 개인이라는 뜻에서 시민, 국가의 법률에 종속된다는 의미로 신민 이라는 용어들이 생겨나게 되었다.

사회의 계약이 강화됨에 따라 개인적인 인격은 사라지고, 이 결합행위는 하나의 집합적인 법인체 즉, 도시국가, 공화국을 만들게 된다.
이렇게 다수가 결합하여 한 단체를 이루면 누구도 그 단체를 공격하기 전에는 한 사람의 구성원도 해칠 수 없기에 각 구성원은 완벽한 동맹을 이루게 되고, 이런 굳건한 동맹관계가 원활히 수행되기 위해서는 각 개인이 지켜야할 많은 것들이 있었으며, 이에 따라 각 개인의 ‘자연적 신분’에서 ‘시민’ 으로 이행되었다. 이 과정에서 과거에는 볼 수 없었던 도덕성 을 부여되었고, 이는 사회적으로 큰 변화의 시작이었다.

오늘날 대부분의 사람들이 인간이라면 태어날 때 부터 당연하게 여겨질 것이라 생각되는 이 도덕성 은 사실 인류가 모두 비극적인 결말을 맞이하지 않기 위한 서로간의 약속이자 비자연적이고 인위적인 단지 하나의 규약 에 불과하였으나, 오늘날에는 사회의 탄탄한 기반으로 거듭났고, 이는 사회 계약 의 기본적인 토대로써 다음과 같은 목적성을 가지게 된다.

자연적 평등을 파괴하는 것이 아니라 반대로 인간들 사이에 자연적으로 생겨날 수 있는 육체적 불평등을 도덕적이고 합법적인 평등으로 대치한다는 것,
그리고 인간은 체력 또는 재능에 있어 불평등할 수 있는 만큼 계약에 의해 그리고 법으로써 모두가 평등하게 된다.

이렇게 사회 계약론은 모두에게 이득이 되는 최고의 계약이라 생각될 수 있지만, 그 이면에는 다양한 문제들이 존재한다.

사실 과거의 생태계에서 가진자와 가지지 못한 자의는 그렇게 크지 않았으며, 그 이유는 역설적이게도 ‘약육강식’의 법칙이 존재했기 때문이다.
동물은 시간이 지나면 자연스럽게 쇠퇴하게 되고 과거 가지지 못했던 자는 ‘무력’을 통해 때로는 ‘약탈’ 과 ‘살해’를 통해 가진자의 재산을 빼앗아 올 수 있었다.
또, 무리에서 도태되거나 약자인 개체는 때로는 무리에 의해 강제로 살해되기도 하고 스스로 경쟁력이 가지지 못하는 개체를 과감히 제거함으로써 사회 전체의 생산성을 유지하고 살벌한 긴장속에서 살아 나갔다.

하지만, 현대 사회의 ‘사회 계약’을 대변하는 ‘법’은 실제로 항상 유산자에게는 유익하고 무산자에게는 해로울 수 밖에 없다.
애초에 이 계약이란 개인이 가진 재산을 타인으로 부터 보호하기 위함이며 누군가의 범법행위가 이루어지지 않는 이상 개인이 가진 재산은 그 사람의 힘과 재능에 관계없이 오랜 시간이 지나도 유지될 수 있다. 이 재산은 세습이라는 형태로 계속해서 누적될 수 있지만, 가진게 없고 지킬게 없는 사람들에게 ‘약탈’ 과 ‘탈취’ 를 막는 ‘법률’은 사실 큰 도움이 되지 못하는 것이 현실이기 때문이다.

오늘날 민주 사회에서 이런 ‘사회 계약’의 이면은 충분히 극복될 수 있으며, 이는 무산자에게 유산자가 될 수 있는 동등한 기회를 제공함과, 사회 계약을 유지하기 위한 유산자의 사회적 기여를 강화함으로써 실현되고 있다.

‘유산자’ 는 우리의 공동체가 자신의 재산을 지켜주고 과거 야생에서 시간이 지남에 따라 잔혹한 결말을 맞이하지 않게 해 주는 것에 대한 감사와 시민으로써의 책임감을 가져야 하며, 누구보다 체제를 지켜나가고 무산자와의 합의점에 이르기 위해 체제를 지키기 위한 경제적 사회적 비용을 제공해야 할 의무가 있음을 의식해야 하며, 무산자라면 우리 공동체가 제공하는 무궁한 기회를 통해 성장해 나가고 훗날 공동체의 훌륭한 시민이 되기 위해 정진해 나가야 할 것이다.


Domain Driven Design 이란 무엇인가

What is domain?

도메인의 사전적 의미는 “정보와 활동의 영역” 을 말하며, 흔히 프로그래머들에게는 어플리케이션 내의 로직들이 관여하는 정보와 활동의 영역이라고 받아들여 집니다.
가령, 어떤 웹 서비스를 만들 때 회원을 가입하고, 회원을 탈퇴하는 일련의 작업은 “회원” 과 관련된 일련의 작업들이며 여기서 “회원” 이라는 도메인이 있다고 볼 수 있습니다.

또 다른 용어로써 “domain layer” 와 “domain login” 이라는 용어가 있습니다. 이는 개발자들에게 일종의 “business logic” 과 동등한 것으로 받아들여져 왔습니다. 이러한 business login 은 비즈니스 주체들(가령 회원, 결제 등) 이 어떤 모델링 된 데이터를 생성하거나 변경하기 위해 서로간에 약속한 높은 수준의 규칙들을 의미합니다.

DDD(Domain Driven Desing)

도메인 주도 디자인이란 개발을 함에 있어 위에서 설명한 도메인이 중심이 되는 개발 방식을 말하며, 그 목적은 소프트웨어의 연관된 부분들을 연결하여 계속 해서 진화하는 새로운 모델을 만들어 나가 복잡한 어플리케이션을 만드는 것을 쉽게 해 주는 것에 있습니다.
DDD의 핵심적인 목표는 Loose Coupling, High Cohesion 으로 각 도메인이 연결성이 적고 높은 정도로 연관되어 보다 가벼운 설계를 위해 탄생하였습니다.

다음은 DDD의 세가지 주요 원리입니다.

  1. 핵심 도메인과 그 기능에 집중하라.
  2. 도메인의 모델의 정교하게 구축하라.
  3. 어플리케이션 모델을 발전시키고 새롭게 생기는 도메인 관련 이슈를 해결하기 위해 도메인 전문가와 끊임없이 협력하라.

Strategic Design

소프트웨어를 디자인 할 때 객체를 기준으로 디자인을 진행하는 것은 Object Oriented Design 이라고 하는데, 이러한 관점에서 볼 때 Strategic Design은 OOD가 잘 이루어진 것으로 볼 수 있습니다.

Strategic Design이란 Context 에 대해 생각하고 이를 기준으로 디자인을 하는 것을 말합니다.

여기서 Context란 무엇일까요?

Context 란 특정 객체 혹은 상황이 벌어지는 주변 환경을 말합니다. 가장 쉬운 예로 가게 안에 접시에 담긴 피자와 혹은 길에 버려진 피자를 생각해 봅시다. 같은 피자이지만 피자가 매장 안의 접시에 있는지 혹은 길에 있는지에 따라 유료, 무료의 차이가 생기게 되고 사실상 다른 것으로 간주될 수 있습니다. 이처럼 같은 사물이나 행동 양상이 벌어지는 상황에 집중하여 디자인을 하는 것이 Strategic Design 의 핵심이라고 할 수 있다.

Strategic Design을 이해하기 위해 간단한 예로 주택을 짓는 경우를 생각해 봅시다. 우리가 원하는 집을 짓기 위해서 우리가 하는 행동 절차는 다음과 같습니다.

  1. 어떤 주택을 지을지 생각을 해 본다.
  2. 그런 뒤에 우리는 Domain Expert 즉, 이 경우 집 전문가와 상의를 한다.
  3. 주택을 지을 때 어떤 핵심적인 가치에 집중하여 집을 지을지를 선택합니다. 가령 헛간이 넓어야 한다던가, 수영장이 커야 한다던가 중점적인 사항을 명시합니다.
  4. 그 뒤 우리는 이미 지어진 다른 집들을 최대한 많이 조사하여 마음속에서 원하는 집의 형상을 떠올려 봅니다.
  5. 그런 뒤에 우리는 그 형상을 실제 집으로 만들어 내기 위해 모델링을 하고
  6. 이를 토대로 구체적인 설계도를 그려 나갑니다. 이 설계도에는 집의 아주 구체적인 부분들이 명시되게 됩니다.

이렇게 DDD를 통한 설계 과정에서 사용되는 용어는 다음과 같습니다.

먼저 집 전체에 대한 설계의 전체를 우리는 domain 이라고 부르며, 커다란 집의 각각의 부분 집합인 헛간, 농장, 수영장 등 큰 파트들을 subdomain 이라고 부릅니다. 또 각각의 subdomain에 대해 각 subdomain의 문맥적 상황을 bounded context 라고 부르며, 실제 subdomain의 구체적인 형상을 나타내는 것을 domain model 이라고 부릅니다.

여기서 bounded context 가 가지는 의미는 바로 특정 모델이 어떤 bounded context 에 속하는 가에 따라서 다른 의미를 가지기 때문입니다.
가령, 주택 건축시에 정문에서 caretaker라는 모델이 있다면 이는 바로 경비원을 말하는 것일 겁니다. 하지만 caretaker라는 단어가 메인 주거 건물 안에서 가지는 의미는 이와 다를 수 있습니다.

이 내용을 간단히 정리하면 다음과 같습니다.

Context
의미를 결정하는 것 처럼 보이는 단어 나 문장이 나타나는 설정으로, 모델에 관한 문장은 context 안에서만 이해될 수 있다.
주택을 구성하는 각 부분 구간들에 대한 환경을 말한다.

Model
도메인의 특정 양상을 묘사한느 추상화 시스템으로 도메인과 관련된 문제를 해결하는 데 사용된다.

Ubiquitous Language
소프트웨어를 만들기 위해서는 많은 사람들이 원활히 소통해야 하고 여기에는 다양한 용어들이 사용된다.

가령, 기획자, 디자이너, 개발자가 모인 자리에서 각자 서로의 언어로 대화를 한다면 이는 원활한 커뮤니케이션을 심각하게 저해하게 된다.

이 경우에 필요한 것이 Ubiquitous Language이며 이는 domain model 을 둘러싼 언어구조를 말한다.

이 언어는 팀 전체가 각각의 업무 파트에서 공통적으로 사용될 수 있어야 하며, 실제 개발의 측면에서 모든 기획자, 디자이너, 개발자가 공통된 어휘를 사용해야 서로간에 이견이 없을 것이며 이러한 공통된 어휘를 ubiquitous language라고 합니다.

Bounded Context
위에서 설명한 Context에 대한 구체적인 설명으로, 특정 모델이 정의되고 적용될 수 있는 영역을 이야기 합니다.
주택을 짓는 경우에 빗대어 생각해 볼 때, Bounded Context는 주택 전체를 구성하는 헛간, 농장, 수영장, 메인 주택 등의 큰 요소들 각각을 둘러싼 상황을 의미합니다.
특정 모델은 어떤 bounded context에 놓이는가에 따라 다르게 이해될 수 있습니다.
실제 소프트웨어를 구축함에서의 예를 들면 가령 sales를 담당한하는 subdomain이 있을 수 있고, 이를 지원하는 support와 accounting 라는 subdomain 이 존재할 수 있습니다. 이러한 각각의 subdomain이 놓인 환경인 bounded context 내에서 특정 모델 customer 가 보여지는 시각은 매우 상이할 수 있습니다. sales 팀에서 고객을 보는 시각은 주로 사회적 관심사, 좋아하는 것, 욕구 등의 것일 겁니다. 하지만 accounting의 측면에서는 사용자는 그저 하나의 계정으로써 그 사람의 결제정보 만이 중요한 정보일 수 있습니다. 즉 각기 다른 bounded context에서 ubiquitous language는 비록 표현은 같지만 다른 의미를 가지게 됩니다.

Context Map
각 bounded context들 사이의 관계를 말하며 즉, 주택 건축시에 헛간, 뒷간, 수영장 등 큰 요소들이 어떤식으로 서로 연관이 되어 있는지를 나타낸다.

Domain Model
Domain Model 이란 실제 세계를 반영하는 구체적인 설계로, 주택 건축시에 주택을 구성하는 메인 주택의 구체적인 설계도를 말한다.

strategic design의 Problem Space와 Solution Space

Tactical Design

Tactical Design

Tactical Design Tool 들은 세부적인 사항을 구현하는 것을 위해 필요하며, 주로 Bounded Context 내의 구성 요소들을 관리합니다.
이것은 개발상의 실제적인 표준을 제공하는데 services, entities, repositories, factories 와 같은 소프트웨어 디렉토리 구조들에 익숙한 개발자들이 많을 것인데, 이 모든 것은 전부 DDD에서 나온 개념입니다. 이러한 Tactical Design은 Strategic Design과 달리 개발을 진행하는 과정에서 계속해서 바뀌고 개선됩니다.

Model Driven Design And Service

Model Driven Design

Tactical Design을 이해하기 위한 Model Driven Design은 위와 같다.
실제 구현은 모델 수준에서 이루어 지고 쉽게 비유하자면 당신의 소프트웨어 전체 즉, domain을 하나의 세계로 표현한다면 각 나라는 subdomain에 해당되고 각 subdomain은 각 나라의 언어인 ubiquitous language를 사용하게 됩니다. 이렇게 각 subdomain은 하나의 Service로 구현되게 됩니다.

Layered Architecture

layered Architecture란 쉽게 말하면 모든 프로세스를 업무순서로 쪼게어 층을 나누어 수행하는 것이다.
가령 맥도날드의 예를 들어보자. 맥도날드에서는 각 종업원들이 맡은 업무를 충실하게 수행하여 아주 효과적으로 업무를 처리한다. 만약 맥도날드의 종업원들이 요리, 계산, 서빙 등 많은 업무를 업무 분담 없이 하게 된다면 분명히 큰 혼란이 초래되고 손님들은 오랜시간 동안 기다려야 하고 형편없는 음식을 먹게 될 것이다. 하지만 맥도날드는 손님을 응대하는 계산원, 주문을 전달하고 컨트롤 하는 중간 매개인, 전체 프로세스에 필요한 인프라를 제공하는 요리사, 사장, 매니저, 필요한 재료들을 보관하는 창고 등으로 구성되어 빠르고 효과적으로 일을 처리한다.

소프트웨어에서도 마찬가지로 고객을 응대하는 request handler, 이를 중재하는 controller, 각종 중요한 비즈니스 로직을 처리하는 business, 다양한 자료구조 등으로 구성되어 클라이언트에 보다 빨리, 조직적으로, 잘 응대할수 있게 되었고, 이에 따라 보다 유연하고 지속가능한 소프트웨어를 구축할 수 있게 되었으며, 각 파트는 자신의 역할을 충실히 수행하고 필요한 경우 여러번 재사용 될 수 있게 된다.

Value Object

소프트웨어의 모델을 구성하는 수치에 대한 객체이며 훌륭한 디자인을 위한 가장 중요한 요소 중의 하나이다.
가령 소프트웨어 내에 화폐를 취급하는 객체가 있다면, 이는 화폐에 관한 모든 처리를 누군가의 도움 없이 스스로 잘 처리할 수 있어야 한다.
단위 환산, 표현법 변경 등 다양한 도메인 로직을 가져야 하며, 스스로 옳바른 값인지 validate 할 수 있어야 할 뿐 아니라 값이 제 3자에 의해 변하지 않고 일관성을 유지해야 한다.

가령 string 객체를 생각해 보자. 이 객체는 문자 어레이를 다루는 value object로써 substring 등의 다양한 기능을 수행하기 때문에 이를 일일히 정의할 필요가 없어져 ubiquitous language 로 소프트웨어의 표현을 간단하게 하고 보강해 준다.

Entity

기존의 attributes 를 기준으로 정의되었던 전통적인 객체와 달리, 연속성의 일관된 스레드에 의해 식별되는 객체이다.
일반적인 개발자들이 이 개념에 대해 알고 있다. Entity는 Value Object로 구성되며 대표적인 예로 db에 있는 row들의 예를 들 수 있다.
Entity는 identified id 를 가지고 business logic을 구현한다.

Aggregate 와 Domain Events

aggregates는 entities의 집합이다. 가령 cutomer, customerInfo, address 라는 세가지 종류의 entities를 생각해 보자. 사실 이 모든 정보는 customer라는 주제로 뭉칠 수 있으며, 여기서 핵심이 되는 entitiy인 customer는 이 세 entities가 이루는 aggregates의 root entity가 된다. 이렇게 되면, 다른 외부 객체는 aggregate 내의 객체로 직접 접근할 수 없고, 하나의 aggregate root item 즉 customer 에만 접근이 가능하며, 이를 통해 해당 aggregate 내에 명령을 전달해야 한다. 이는 실제 프로그래밍에 자주 쓰이는 디자인 패턴 중의 하나이다.

더욱 간편한 예로는 포스트와 댓글의 관계, 질문과 답변의 관계 등이 있다.

여기서 Domain Event 라는 개념에 대해 살표보자.
domain event는 모델의 특정 행동과 관련된 이벤트인데, Aggregate 사이의 일관성을 유지하는데에 사용될 수 있다.
가령 사용자의 주소가 바뀌면 주문 내용도 바뀌어야 하는데, 순서를 살펴보면 사용자의 주소가 바뀌면 같은 aggregate내에 있는 사용자 정보가 바뀌게 되고 이러한 aggregate의 변화는 주문과 관련된 aggregate의 변화를 촉구하기 위해 domain event를 발생시켜 상호간의 정보의 일치를 이룬다.

Factories

Factories는 복잡한 entity 혹은 aggregate를 생성하는 것을 담당한다.
가령 엔진과 부속품을 넣으면 자동차가 나오는 공장과 같이 특정 정보를 factory에 보내면 결과로 aggregate 혹은 entity를 만들어주게 되고, 그 안에서 벌어지는 일에 대해서는 개발자들이 더 이상 신경을 쓰지 않아도 되고, 하나의 모듈로써 사용할 수 있다.

Repositories

일반적인 저장소와 달리 특정 aggregate에 보다 신속하게 접근하고 aggregate 단위로 데이터를 처리할 수 있게 해 준다.
가령 위의 예처럼 customer 가 root entity로 있는 aggregate의 경우 1개의 repo를 만들게 되고, 사용자는 더 이상 기존의 db에서 고객 이름, 나이, 생년 등을 조합해서 사용하지 않고 repo에 aggregate를 통으로 저장해서 보다 쉽게 정보에 접근하고 정보를 변경할 수 있다.

DDD를 통해 얻을 수 있는것

Domain-driven design also heavily emphasizes the ever-more-popular practice of continuous integration, which asks the entire development team to use one shared code repository and push commits to it daily (if not multiple times a day). An automatic process executes at the end of the work day, which checks the integrity of the entire code base, running automated unit tests, regression tests, and the like, to quickly detect any potential problems that may have been introduced in the latest commits.

DDD 구현

어떻게 domain expert와 협의할 것인가

과거에 Use Case Diagram, Sequence Diagram 등 많을 것을 썻다.
때로는 ER Diagram도 사용했다.

하지만 요즘에는 이런 옛 방법을 사용하지 않고, Event Storming을 한다.

이것은 strategic design 을 위해 도메인 모델을 만들기 위한 연습이다.
개발 전문가와 domain 전문가가 만나서 브레인 스토밍을 통해 각 도메인에서 어떤 내용들이 필요할지에 대한 직관을 기른다.

진행 단계

  1. domain expert 와 개발 전문가와 함께 서로간의 질문을 하는 미팅 시간을 가진다.
  2. 포스트잇에 색깔에 따라 events, commands, policies, processes, errors, roles, aggregates, etc 등을 적어 놓는다.
    본 미팅은 event storming 이므로 이벤트를 시간의 순서에 따라 어플리케이션에서 발생 가능한 주요한 이벤트들을 나열한다.
    가령 쇼핑몰의 경우 상품 열람 => 상품 구매 => 상품 배송 => 배송 완료 처럼 디테일한 이벤트들을 순서대로 나열한다.
  3. 다음은 이러한 이벤트들의 포스트잇 주변에 연관된 system action, user action 등을 쭉 붙인다.
  4. 이러한 과정이 마무리 되면 이제 bounded context 를 찾을 시간이다.
    나열된 리스트를 보면 어느정도 분리된 subdomain 들이 보이게 되는데 가령 catalog, payments, delivery 등의 subdomain이 될 수 있다.

참고자료 - Alpha Code 동영상 강의

all images are from Alpha Code Lecture Above

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×