YouTube

Got a YouTube account?

New: enable viewer-created translations and captions on your YouTube channel!

Korean subtitles

← Robert C. Martin - Clean Architecture and Design

Get Embed Code
3 Languages

Showing Revision 54 created 05/10/2017 by YongWook Kim.

  1. (4분45초에 시작. 실제 강연과 한글 자막은 11:05에 시작)
  2. 뒤에 잘 들리나요?
  3. 저 뒤에도 잘 들리나요? 오케이 좋습니다.
  4. Um what is an electron?
  5. So part of atom, everybody knows that, I think
  6. It's um.. (Screams from other room) yeah I think so, . I think that's royal ???
  7. Um electron is part of atom
  8. it's carries a unit of electronic charge, negative charge, as oppose to a proton which carries a positive charge
  9. It apparently has ??? not very much, thousands of electron... very very small amount of mass
  10. And we think of it as a particle, although that misleading um.. electron actually behaves much more like a wave than like a particle
  11. why do we think of it as particle?
  12. and the reason we do that is that when electron interacts a location like a particle would
  13. when electron is moving through the space it does not moves the way a particle would
  14. moves as a wave and the wave has no location
  15. you look at an ocean wave, and ocean wave can be huge
  16. it has no distinct location it has well defined energy but no distinct location
  17. this is how an electron moves
  18. electrons obey a principle and it's a mistruster principle
  19. It's called the poly exclusion principle
  20. two electrons bound into the same system will not be in the same state
  21. for whatever reason they cannot be in the same state
  22. so if there are two electrons in an atom
  23. those two electrons must be different somehow
  24. now they might different in the direction of their spin
  25. an electron can spin to the left or spin to the right
  26. two electrons that have exactly same energy could fit together spinning one left and one right
  27. there's no way to get a third one in there
  28. so the next electron must have higher energy and then you can have two more
  29. one spinning left one spinning right
  30. but if you wanted to add another that would have to be something different about them
  31. and you could arrange them differently in space
  32. so you could have one group of two this way and another group of two this way and another group of two this way and one group of two in a sphere and that adds up the eight by the way.
  33. most of our atoms that we know of have this need to have 8 electrons in their shells
  34. The reason for that is just this nice little geometry. the sphere and then three rows and each one of those can contain two
  35. have you ever thought about water?
  36. I got some here. Fascinating substance
  37. what's it made of?
  38. two hydrogen atoms one oxygen atom
    that's what makes a water molecule
  39. and what's it shaped like?
  40. Mickey mouse! yes, there is big oxygen in the middle and two little hydrogens forming the ears
  41. The angle there is the result of (??) the shell arrangement.
  42. What makes the hydrogen and oxygen stick together?
  43. think of two atoms, two atoms covered by electrons, two electrons are parallel each other
  44. what would make two hydrogens and an oxygen stick together?
  45. And it turns out that if you take these two hydrogens and big oxygen you lay them next to each other
  46. and you think of the electrons as waves, not particles, then where those waves like to be?
  47. and those waves would like to be mostly between protons. Protons in hydrogen atom and protons in oxygen atom
  48. So they will congregate those electron waves will congregate more
  49. between two atoms, between three atoms actually, then everywhere else
  50. they still go everywhere else that just that more likely to be between them
  51. that means there's little extra negative charge between the atoms and that little extra negative charge to tracks the protons and that's covalent bonds
  52. now if you take this Mickey mouse atom and you divide it in half
  53. you find there's more negative charge above the one and below the one
  54. cause all that negative charge likes to sit there between the two hydrogen atoms and oxygen atoms
  55. So there's more negative charge on one side than the other which means that water molecule is a dipole
  56. it is negative one side and positive on the other
  57. this is why water is wet.
  58. Water sticks to your hand because all the water molecules rotate to stick to the electrically charged surface of your skin
  59. even though it is not very electrically charged
  60. this is why water makes it good solvent because the little water molecules would rotate to attract to the parts of the other molecule that they want want to stick to
  61. this is why water makes it a good cleanser
  62. and this is why water will do one of the most wonderful things you can do with water. Who's done this experiment?
  63. You get a water faucet. You turn it on just so you get a really thin stream of water. Not very fast, just tiny stream of water
  64. And then you get a balloon and you rub the balloon on your head. And then you hold the balloon close to that stream of water and watch the water bend towards the balloon
  65. as all the water molecules turn around get it tracked the electric charge
  66. 물론 오늘의 발표 주제는 이게 아니지요.
  67. 오늘 이야기할 주제는 "아키텍처, 잃어 버린 시간" 입니다. 지난 몇 년 동안 강연해왔던 주제인데요.
  68. 클린 코드와 클린 디자인의 다음 단계에 대한 이야기입니다.
  69. 클린 시스템 스트럭쳐에 대한 이야기 입니다.
  70. 화면을 보세요.
  71. 이 그림은 내가 10년 전에 작성했던 어플리케이션의 디렉터리 구조입니다.
  72. 당시에 Rails를 배우고 있었지요. 여기 Ruby 프로그래머가 있나요? Ruby on Rails 프로그래머?
  73. 저쪽에 손 흔드는 사람이 한 명 있네요. 오케이.
  74. 당시에 Rails를 배우면서 이 어플리케이션을 작성했지요.
  75. 책의 내용을 그대로 따라 작성했습니다.
  76. 책에서 이야기하는 데로 그대로 작성했더니 이런 형태의 결과가 나왔습니다.
  77. 만족스럽게 마무리했고 그뒤로 오랫동안 보지 않았지요.
  78. 그리고 한 3년 전에 아들에게 어플리케이션을 하나 작성해달라고 했습니다.
  79. 작성된 어플리케이션을 봤더니
  80. 디렉터리 구조가 똑같았어요.
  81. 이 둘은 전혀 다른 어플리케이션이고 아무런 연관도 없습니다.
  82. 그런데 디렉터리 구조는 똑같아요. 이걸 보면서
  83. 왜 두 어플리케이션의 최상위 구조가 같은지에 대해서 고민했습니다.
  84. 이 둘은 전혀 다른 어플리케이션이거든요.
  85. 두 어플리케이션의 디렉터리 구조가 동일한 이유는 둘 다 Rails 어플리케이션이기 때문이었습니다.
  86. 그러자 이게 왜 중요한지가 궁금해졌습니다.
  87. Rails 같은 프레임워크가 얼마나 중요하길래 어플리케이션의 최상위 디렉터리로 구조를 결정지어버리는 걸 까요?
  88. 내가 생각한 이유는 바로 다음과 같습니다.
  89. 웹은 전달을 위한 장치입니다. 웹은 I/O 채널이에요.
  90. 웹 자체는 아키텍처적으로 중요하지 않습니다.
  91. 흔히 웹 어플리케이션을 작성한다고 이야기합니다.
  92. 하지만 그렇지 않습니다.
  93. 우리는 어플리케이션을 작성하고 있는 것 입니다. 단지 어플리케이션이 웹 이라고 하는 I/O 채널을 통해 콘텐트를 전달하는 것뿐이지요.
  94. 그러면 왜 I/O 채널이 그렇게 중요할까요?
  95. 혹시 웹이 번성하기 시작한 시기를 기억하나요? 1980년대? 1990년대?
  96. 얼마나 큰 변화였는지 기억하나요? 얼마나 모든 것이 근본적으로 변했는지 기억하나요?
  97. 그다지 큰 변화는 없었습니다. 왜냐하면 실제로 크게 달라진 것이 없었기 때문이지요.
  98. 우리는 단지 입력 소스로부터 입력을 받고, 처리하고, 출력 소스로 내보내기만 했습니다.
  99. 웹은 그냥 그런 거에요.
  100. 그런데 왜 웹이 모든 것들을 결정해버릴까요?
  101. 그래서 나는 건축에 대해서 생각해봤습니다. 건축 도면을 봤어요.
  102. 저 도면을 보세요. 저 위에 도서관이라는 글씨가 없더라도 깨닫는데 얼마 걸리지 않을 겁니다.
  103. 도서관이라는게 너무 명백하거든요.
  104. 책장들이 많이 있고 책상도 많습니다.
  105. 책상위에 컴퓨터도 보이고요 책을 대출하고 반납하는 곳도 보여요.
  106. 저 도면을 보고 도서관이라는 것을 알아채는 데에 오랜 시간이 걸리지 않을 겁니다.
  107. 다른 것도 봐볼까요? 저건 교회에요. 누가 봐도 교회지요.
  108. 어쩌면 극장이라고 생각할 수 도 있겠지요. 극장이랑 교회는 공통 부분이 있으니까요.
  109. 하지만 이건 분명히 교회입니다. 제단, 바깥의 교실,
  110. 분명히 교회지요.
  111. 이 건물의 아키텍처는 어떻게 지을 수 있는지 말하지 않습니다. 이 건물의 아키텍처는 그 의도를 말하고 있습니다.
  112. 아키텍처는 의도를 표현하는 것 입니다.
  113. 하지만 저 Rails 어플리케이션들의 최상위 구조는 그 의도가 보이지 않습니다.
  114. 단지 Rails 어플리케이션이라고 말하고 있지요. 무언가 잘못되었어요.
  115. 그리고 이런 생각이 들었습니다.
  116. 이건 이미 알려진 문제인가? 이미 해결되었던 문제인가? 이 문제는 1992년에 이바 야콥슨이 저술한 책에서 거론되고 해결되었었습니다.
  117. 이 책을 가진 사람이 있나요? 읽어 본 사람? 여기 한 사람있네요 또 없나요?
  118. Object-Oriented Software Engineering. 아주 훌륭한 책이에요.
  119. 1992년에 출반된 책이지만 상관없어요. 책에 담긴 원칙들은 여전히 유효합니다.
  120. 부제를 보세요. 부제는 'A Usecase driven approach' 입니다.
  121. 유즈케이스 기억하는 사람 있나요? 1990년대에는 아주 아주 유명했었습니다.
  122. 사실 너무 유명해서 수많은 컨설턴트들이 본래의 의미를 변질시켰지요.
  123. 기억하나요? 수많은 컨설턴트들이 자신의 유즈케이스 양식을 앞다투어 인터넷에 올렸었지요.
  124. 결국 양식만 중요하게 되어 버렸어요. 표준 양식의 빈칸을 채우도록 강요 받았지요.
  125. 유즈케이스의 이름, 입력값, 사전조건, 사후조건, 주액터, 부액터 등을 채워야 했습니다.
  126. .
  127. 우리는 모든 빈칸을 채워야만 했고 결국 유자케이스의 가장 중요한 점은 그 기능이 아니라 양식이 되버렸습니다.
  128. 그 즈음에 에자일 운동이 시작되었습니다.
  129. 우리는 유즈케이스에 대한 이야기는 멈추고 유저 스토리에 대해 이야기했습니다. 유즈케이스에 대해서는 아무도 이야기하지 않게 되었지요.
  130. 그래서 나는 이 책을 다시 읽어봤어요.
  131. 야콥슨이 쓴 것들을 다시 기억해냈습니다.
  132. 여기 유즈케이스가 있습니다. 전형적인 야콥슨 스타일의 유즈케이스에요.
  133. 보다시피 매우 작은 양식이에요.
  134. '주문 생성'이라는 이름이 있네요. 주문 처리 시스템의 유즈케이스라고 생각해보세요.
  135. 입력 값으로 고객 아이디, 고객 연락처, 수신처 등이 보이네요.
  136. 여기에는 세부적인 내용은 없어요. 고객 아이디가 어떤 것인지 기술하지 않습니다.
  137. 숫자이건 문자열이건 상관없어요.
  138. 고객 연락처가 어떤 것인지 기술하지 않습니다. 아마도 이름 날자 주소 등등 이겠지요.
  139. 하지만 세부사항들은 여기에 명시되어있지 않습니다.
  140. 여기 메인 흐름이 있네요.
  141. 메인 흐름은 유즈케이스를 만족시키기 위해 컴퓨터가 실행하는 단계들이에요.
  142. 첫 번째로 주문 담당자는 '주문 생성'을 요청합니다.
  143. 그리고 시스템이 데이터를 검증합니다. 어떻게 검증한다는 이야기는 안 했지요? 어떻게든 검증을 하는지는 중요하지 않습니다. 그냥 검증을 한다는 게 중요합니다.
  144. 세번째로 시스템이 주문을 생성하고 ID를 결정합니다.
  145. 아마도 어떤 데이터베이스 작업이겠지만 이야기는 안 하겠습니다.
  146. 그리고 시스템은 담당자에게 ID를 전달합니다. 아마도 웹 페이지를 통해서겠지만 이야기는 안 하겠습니다.
  147. 실제로 이 유즈케이스는 웹에 대해 아무런 이야기도 하지 않습니다.
  148. 이 유즈케이스는 어떤 I/O 채널을 통해서도 구현이 가능하겠지요.
  149. 이 유즈케이스는 콘솔 앱, 데스크탑 앱, SOA 앱, 아이폰 앱에서도 구현이 가능합니다.
  150. 유즈케이스는 I/O 채널을 모르기 때문에 가능한 것 입니다.
  151. 야콥슨은 유즈케이스를 오브젝트로 바꿀 수 있다고 했습니다.
  152. 야콥슨은 저것을 Control Object라고 불렀지만 MVC의 Controller와 헷갈릴 수 있으므로 Interactor라고 이름을 바꿨습니다.
  153. 어쩌면 유즈케이스라는 이름이 더 좋겠지만 그렇게 하지는 않았습니다. Interactor로 부르겠습니다.
  154. Interactor 오브젝트는 유즈케이스를 구현합니다. 유즈케이스의 입력값을 입력 받아서 유즈케이스의 출력 값을 출력합니다.
  155. 그리고 유즈케이스의 처리 흐름을 구현합니다.
  156. 밑에 설명을 보면 어플리케이션 별 비즈니스 규칙들을 가진다고 되어있지요?
  157. 거기에는 두 종류의 비즈니스 규칙이 있습니다.
  158. 먼저 글로벌 한 비즈니스 규칙이 있습니다. 모든 어플리케이션에 적용이 가능하지요.
  159. 그리고 개발중인 어플리케이션에만 해당하는 비즈니스 규칙들이 있습니다.
  160. 예를 들어서 주문 입력 어플리케이션과 주문 처리 어플리케이션이 있다고 생각해봅시다.
  161. 둘 다 '주문'이라는 오브젝트가 있을 겁니다. 그리고 그 주문 오브젝트들은 같은 비즈니스 규칙을 가지고 있겠지요.
  162. 하지만 둘 중 하나의 어플리케이션만 주문 추가라는 유즈케이스를 가지고 있을 겁니다.
  163. 유즈케이스는 어플리케이션에 따라 다릅니다. 유즈케이스는 특정 어플리케이션에 종속되지요.
  164. 비즈니스 규칙은 어플리케이션에 따라 다르지 않습니다. 엔티티 오브젝트에 종속됩니다. 비즈니스 오브젝트라고도 이야기 하지요.
  165. 나는 비즈니스 오브젝트라는 말은 좋아하지는 않습니다. 야콥슨도 엔티티 오브젝트라고 불렀지요.
  166. 어플리케이션 비종속적인 비즈니스 규칙들을 엔티티 오브젝트에 넣고 Interactor가 엔티티 오브젝트들을 관장합니다.
  167. 그리고 입력값과 출력값을 다른 유즈케이스에 전달하는 방법을 정합니다.
  168. 이 경우 인터페이스를 사용합니다. 객체지향 방식의 인터페이스로 표현을 했는데요.
  169. Interactor는 인터페이스 중 하나는 사용하고 있고 다른 하나는 구현을 하고 있습니다.
  170. Interactor가 구현하고 있는 것은 입력 인터페이스이고요 Interactor가 사용하고 있는 것은 출력 인퍼테이스입니다.
  171. 두 인터페이스와 Interactor 사이의 화살표가 같은 방향이지요? 아주 중요한 포인트입니다!!!!!
  172. 이게 왜 중요한지는 조금 뒤에 이야기하겠습니다.
  173. 야콥슨은 이 세가지를 어플리케이션 아키텍처의 일부로 이야기했습니다.
  174. 자 그럼 이것들이 어떻게 작용하는지 봅시다.
  175. 평범한 어플리케이션이 있습니다. 저기 작은 사람이 유저입니다.
  176. 이 사람이 어떤 전달 매커니즘을 통해서 시스템과 상호작용합니다.
  177. 전달 매커니즘은 웹일 수도 아닐 수도 있겠지요. 아무런 상관 없습니다.
  178. 저 유저는 버튼이나 키보드를 사용해서 시스템이 데이터를 받아들이도록 합니다.
  179. 어떤 전달 메커니즘을 통하는지는 전혀 중요하지 않습니다.
  180. 시스템에 전달된 데이터는 Request Model이라는 것으로 변형됩니다.
  181. Request Model은 순수한 데이터 구조입니다.
  182. POJO나 POCO와 같은 순수 데이터 구조 입니다. 데이터가 어디에서 왔는지 모르고 웹과 아무런 연관도 없습니다.
  183. 메소드도 없는 단순한 데이터 구조입니다.
  184. Public 데이터만 있는 구조로서 모든 입력 값을 저장하게 됩니다.
  185. Request Model은 입력 인터페이스를 통해 Interactor에게 전달됩니다.
  186. Interactor는 Request Model를 읽어 해석하고
  187. 작은 여러 커맨드들로 변환하여 엔티티에 보냅니다.
  188. 모든 비즈니스 오브젝트들은 엔티티로 호출되는 메소드들을 컨트롤합니다.
  189. 작업이 끝나면 반대 방향으로 진행됩니다. Interactor는 엔티티를 조회하여 변경사항을 확인합니다.
  190. 그 결과로 Result Model이라는 또다른 데이터 구조를 만들게됩니다.
  191. Result Model도 역시 순수한 데이터 구조입니다. 단순한 POJO나 POCO이지요.
  192. Result Model은 출력 인터페이스를 통해서 전달 매커니즘으로 전해집니다. 출력 인터페이스를 통해 어떻게던 유저에게 전달이 됩니다.
  193. 어플리케이션의 일반적인 처리 과정입니다.
  194. 그럼 Interactor를 테스트할 수 있을까요?
  195. 매우 쉽겠지요?
  196. 입력 데이터 자료를 생성해서 Interactor를 호출하고 출력 데이터를 보면됩니다.
  197. 테스트를 위해 웹 서버가 필요할까요?
  198. 아닙니다. Interactor는 단순히 POJO나 POCO만을 사용하기 때문이지요.
  199. 테스트를 위해 데이터베이스가 필요할까요? 어쩌면 필요할 수도 있겠지요 하지만 이 문제는 조금 있다가 이야기하겠습니다.
  200. 전달 메커니즘이 없어도 테스트가 가능합니다.
  201. 전달 매커니즘이 웹 인가요? 상관 없습니다. Interactor를 테스트하는데에 웹 서버는 실행할 필요가 없어요.
  202. 웹 페이지도 없이 테스트가 가능합니다.
  203. 처음 입력단 부터 마지막 출력단까지 확인하지 않아도 테스트가 가능합니다.
  204. MVC에 대해 이야기 해볼까요?
  205. MVC는 당연히 따라야 하는 거 아닌가요?
  206. MVC는 무엇의 약자이지요? Model View Controller 입니다. 그럼 누가 발명했나요?
  207. 저 사람입니다. 난 저 사람의 이름을 제대로 발음할 줄 모릅니다. 여러분이 제대로 발음할겁니다.
  208. 트릭뷔 륀스카욱. 여러분은 정확히 발음하겠지요.
    (역주: 트릭뷔 륀스카욱은 청중들과 마찬가지로 노르웨이 사람임.)
  209. 나는 저 사람을 만나봤습니다. 저 사람이 1970년대에 MVC를 발명한 사람입니다.
  210. 나는 2년 전에 여기에서 만나봤습니다.
  211. 그때 대기 라운지에서 전원 콘센트를 찾고 있었지요. 그때 어떤 나이든 사람이 다가와서 콘센트를 건네 줬습니다.
  212. 누군가 돌려 보니 "트릭뷔 린스카욱!"
  213. 멀티탭을 주고 받을 때에 손가락이 스쳤어요!
  214. 나는 한동안 손을 안씼었습니다. 트뤽뷔 린스카욱.
  215. 오늘 몇 사람이 내게 와서 사진을 찍었는데요, 나도 역시 비슷한 부류입니다.
  216. 70년대 말에서 80년대 초에 트뤽비 린스카욱은 Model View Controller라고 부르는 이 구조를 제시했습니다.
  217. 스몰토크 플랫폼 위에서 이걸 만들었지요.
  218. 기본 개념은 매우 간단합니다.
  219. 모델 오브젝트가 있습니다. 모델 오브젝트는 비즈니스 규칙을 담고 있지요.
  220. 모델 오브젝트는 자신이 어떻게 유저에게 보여질지 전혀 모릅니다. 입력 값이 어디에서 오는지도 몰라요.
  221. 단지 순수한 비즈니스 규칙입니다. 저기 아래에 있는 컨트롤러는 입력 값들을 처리합니다.
  222. 컨트롤러는 입력 기기들을 쳐다 봅니다. 어떤 입력 기기인지는 중요하지 않습니다. 사용자의 행동을 커맨드로 만들어 Model에게 전달합니다.
  223. 그리고 View가 있지요.
  224. View에 쌍선으로 그려진 화살표가 있는데요. 옵저버 관계를 의미합니다.
  225. View는 Model에 등록을 해놓습니다. 그리고 Model이 변하면 View는 이를 통지 받아 화면을 업데이트합니다.
  226. View의 역할은 Model의 컨텐츠를 표시하거나 전달하는 것 입니다.
  227. MVC는 GUI 환경에 아주 적합합니다. 그리고 콘솔, SOA 등에도 잘 적용될 수 있습니다.
  228. 일부는 입력을 전담하고 (Controller)
    일부는 프로세스를 전담하고 (Model)
    또 일부는 출력을 전담합니다. (View)
  229. MVC는 최초로 이름을 가진 디자인 패턴일 텐데요 원래는 아주 작은 것들에 사용하는 게 목적이었습니다.
  230. MVC는 버튼에 쓰일 수 있지요. MVC는 체크박스에도 쓰일 수 있습니다. 그리고 MVC는 텍스트 필드에도 쓰일 수 있습니다.
  231. 스크린에는 MVC가 쓰이지 않습니다.
  232. 아주 오래 전 부터 MVC는 비틀어지고 변형되어 왔습니다. 소프트웨어 분야에서 흔히 일어나는 일이지요.
  233. 무언가 매우 좋은 것이라고 여겨지면 다른 모든 사람들이 모방을 시작합니다. 그리곤 완전히 다른 것에 같은 이름을 붙이고는 그 역시 좋은 것이라고 주장합니다.
  234. 객체지향도 그랬고, 구조, 오브젝트 에자일 등도 마찬가지였습니다.
  235. 어떤 이름이 좋은 것을 의미한다면 다른 사람들이 그 이름을 자기 것에 붙이려고 합니다.
  236. MVC도 마찬가지 입니다. 요즘 MVC 프레임워크들이 많이 있습니다.
  237. 그런 MVC 프레임워크들은 원래 MVC와는 전혀 다릅니다. 트릭뷔 린스카욱의 MVC와는 전혀 다른 개념의 것 입니다.
  238. 아주 많이 달라요. 보통 이렇게 생겼지요.
  239. 저기 많은 컨트롤러들이 있지요. 웹 환경에서는 저 컨트롤러들은 웹에 의해 작동됩니다.
  240. 저 구름 너머에 있는 웹 프레임워크지요. Rails 일지 Spring일지 어떤 것이든지 상관없어요.
  241. 그 복잡하고 끔찍한 URL을 어떻게인가 전달해서 컨트롤러에 전달합니다.
  242. 웹으로부터 받은 파라메터와 데이터를 컨트롤러에게 전달합니다.
  243. 그러면 컨트롤러들은 비즈니스 오브젝트들에게 일을 하라고 소리를 칩니다.
  244. 그리고 비즈니스 오브젝트에서 데이터를 모아서 뷰에게 이야기합니다. 그러면 뷰들은 다시 비즈니스 오브젝트들에게서 데이터들을 조회하고 화면에 표시합니다.
  245. 결국 비즈니스 오브젝트에는 컨트롤러나 뷰에나 있을 법한 펑션들로 채워지면서 오염되어 버립니다.
  246. 펑션의 적절한 위치를 찾기가 어려워서 비즈니스 오브젝트에 구현하면 안 되는 것 들을 구현해 넣기도 합니다.
  247. 그럼 출력은 어떻게 처리할까요?
  248. 여기 Interactor는 일을 끝냈습니다.
  249. 유즈케이스를 끝내면서 데이터를 조회했지요. 조회된 Response Model을 출력 인터페이스를 통해 전달하려는 시점입니다.
  250. 저 출력 인터페이스를 구현하는 것은 무엇 일까요? Presenter라 불리우는 것 입니다.
  251. Presenter의 역할은 순수 데이터 구조인 Response Model을 받아서
  252. View Model이라는 또다른 데이터 구조로 변형시킵니다.
  253. View Model은 출력 값을 표현하는 순수한 데이터 구조입니다.
  254. 하지만 만약에 화면에 표가 있다면 View Model에도 표가 있을 겁니다.
  255. 만약에 화면에 텍스트 필드가 보인다면 View Model에도 텍스트 필드가 있을겁니다.
  256. 화면의 숫자를 소수점 이하 두 자리 까지만 표현하겠다면 ViewModel은 TrimToTwoDecimalPlaces와 ConvertIntToString라는 메소드를 가지게됩니다.
  257. 음수를 괄호로 표현하고 있다면 Presenter가 데이터에 괄호를 붙여서 View Model에 저장을 한 것 입니다.
  258. 메뉴 아이템들이 있다면 그 이름들도 View Model에 저장이 됩니다.
  259. 비활성화된 메뉴 아이템은 회색으로 보여져야 한다면 View Model에는 활성 상태를 저장하는 불린 값이 있을 겁니다.
  260. 화면에 표시되는 모든 것들은 View Model에 저장이 됩니다. 여전히 추상화된 방식으로요.
  261. 그리고 View에 입력이 됩니다.
  262. View는 멍청해요. View는 저것들과 아무런 관련이 없고 단순히 View Model로 부터 데이터를 가져갑니다.
  263. 아무 것도 처리하지 않습니다. If 문도 없습니다. 아마 테이블을 표시하기 위한 루프문 정도는 있겠만 그 정도가 전부 입니다.
  264. View는 아주 멍청해서 신경 쓸 이유가 없습니다. 일반적으로 테스트도 잘 안 하지요. 어찌되었건 우리 눈으로 보게 되니까요.
  265. 그럼 Presenter를 테스트 할 수 있을까요?
  266. 할 수 있습니다. Request Model을 입력한 후에 결과로 나온 View Model을 체크하면 됩니다.
  267. Presenter를 테스트 할 때에 웹 서버가 실행되어야 할까요?
  268. 아니지요. 웹 서버가 없어도 모두 테스트할 수 있습니다.
  269. 스프링 같은 컨테이너들을 실행할 필요도 없지요.
  270. 그런 것 들을 실행하는 방법을 몰라도 됩니다.
  271. 그냥 평범한 데이터 구조체를 테스트하는 것처럼 모두 테스트 할 수 있습니다.
  272. 그나저나 이게 목표입니다. 다른 아무것도 실행하지 않고 가능한 많은 테스트를 하는 것 입니다.
  273. 30초에서 1분씩이나 써가면서 이것 저것들을 구동하지 않아도 됩니다.
  274. 다른 것들 없이 테스트만 실행할 수 있으면 됩니다. 다른 거 없이 가능한 빠르게 착착착 끝내면 됩니다.
  275. 저게 전체 그림입니다.
  276. Interactor는 입력 인터페이스로 들어온 Request Model에서 데이터를 읽습니다.
  277. 그리고 Response Model에 데이터를 저장하고 출력 인터페이스를 통해 Presenter에게 전달합니다.
  278. 저기 검정색 선을 보세요. 저 선이 어플리케이션과 전달 매커니즘을 구분하는 선입니다.
  279. 그리고 검정선을 지나는 모든 화살표가 어플리케이션을 향하는 것을 보세요.
  280. 따라서 어플리케이션은 Controller나 Presenter에 대해 아무것도 모릅니다.
  281. 어플리케이션은 웹이나 I/O 채널에 대해 아무 것도 모릅니다.
  282. I/O 채널은 어플리케이션을 알고 있지만 어플리케이션은 I/O 채널에 대해 모르고 있습니다.
  283. 만약에 저 둘을 서로 다른 Jar 파일에 담는다면 어플리케이션 Jar 파일은 웹 Jar 파일에 의존하지 않게됩니다.
  284. 저 둘을 다른 Jar 파일에 담는 게 바람직하겠지요. 하나는 웹에 대한 Jar 파일이고 하나는 어플리케이션이 담긴 Jar 파일입니다.
  285. 그리고 어쩌면 또 다른 I/O 매커니즘에 대한 Jar 파일을 만들 수도 있겠지요.
  286. 그리고 I/O 매커니즘을 변경하려면 그냥 Jar 파일만 바꿔치면 됩니다.
  287. 웹이라는 I/O 매커니즘을 플러그인이라고 생각하세요. 여기 .Net Sharp 사용자가 있나요?
  288. 여기 모두 .Net 개발자 아닌가요?
  289. 어떤 IDE를 사용하지요? IDE용 플러그인을 사용하나요?
  290. IDE 개발자와 플러그인 개발자 중에 상대방에 대해 아는 사람은 누구일까요?
  291. 플러그인 개발자가 IDE 개발자를 알지요. IDE 개발자는 플러그인 개발자에 대해서 아무것도 모릅니다.
  292. 상관 안 합니다.
  293. 둘 중에 누가 상대방에 피해를 줄 수 있을까요? 플러그인 개발자들이 비주얼 스튜디오를 해칠 수 있을까요?
  294. 여기 Resharper 쓰는 사람? Resharper 제작자들이 비주얼 스튜디오를 해칠 수 있을까요?
  295. - (청중) 예!
    - (로버트 마틴) 아마 실행 중에 죽일 수는 있겠지요.
  296. 하지만 그렇다고 비주얼 스튜디오 개발자들이 대응을 해야 할까요?
  297. MS의 개발자들이 JetBrains에게 신경 쓸까요?
  298. 아니지요! 그들은 JetBrains는 신경쓰지 않습니다.
  299. 그럼 MS의 개발자들이 JetBrains의 개발자들이 자신들을 따라오게 할 수 있을까요?
  300. 그렇지요!
  301. 그럼 여러분 어플리케이션에 대해 생각해봅시다.
  302. 어플리케이션의 어떤 파트가 어플리케이션의 다른 파트로부터 보호되어야 할까요?
  303. 어떤 파트가 어플리케이션의 다른 파트의 변경에 따라 수정되어야 할까요? 어떤 파트가 다른 파트의 변경에도 영향을 받지 않아야 할까요?
  304. 답은 아주 명확합니다.
  305. 비즈니스 규칙을 웹으로부터 보호해야 합니다.
  306. 그 반대는 안됩니다.
  307. 웹에 어떠한 변경이 생기더라도 비즈니스 규칙에는 영향이 없어야 합니다. 아키텍처적으로 보장되어야 합니다.
  308. 저기 모든 화살표가 어플리케이션을 향하고 있습니다. 명심하세요. 저게 플러그인 아키텍처입니다.
  309. 이제 데이터 베이스에 대해 이야기해봅시다.
  310. 저 그림 속의 데이터베이스가 당신이 생각하는 것과 비슷한가요?
  311. 데이터베이스가 세상의 중심이고 어플리케이션은 변방에 위치한 아랫것들 인가요?
  312. 여기 DBA 있나요?
  313. 아! 없군요 좋습니다.
  314. 혹시 이런 DBA와 일 해본 경험 있나요? 어플리케이션은 구석으로 밀쳐버리고, 스키마를 정해버리고, 데이터베이스만 우선시하는?
  315. 이게 여러분이 생각하는 데이터베이스인가요?
  316. 내 이야기의 요점은 이 것입니다.
  317. 데이터베이스는 디테일이에요.
  318. 아키텍처적으로 큰 의미가 없습니다.
  319. 데이터베이스는 그냥 데이터 저장소일 뿐입니다.
  320. 시스템에서 아키텍처적으로 중요한 것이 아닙니다.
  321. 비즈니스 규칙과도 아무런 연관이 없지요.
  322. 설마 Stored Procedure로 비즈니스 규칙을 구현했나요?
  323. Stored Procedure에는 비즈니스 규칙 대신 쿼리, 검증, 무결성 검증 등이 들어가야 합니다.
  324. 그럼 왜 데이터베이스를 사용할까요?
  325. 데이터베이스는 왜 생겨났을까요? 오라클은 왜 존재할까요?
  326. 데이터베이스 이전에는 데이터를 어디에 저장했었을까요?
  327. 회전하는 디스크에 저장했었습니다. 여기 디스크 드라이버 개발해본 사람 있나요?
  328. 회전하는 디스크에 데이터를 입출력 하는 프로그램을 개발해본 사람 있나요?
  329. 없나요?
  330. 디스켓? 그것도 마찬가지지요.
  331. 데이터를 디스크에 저장하고 읽는 것은 매우 어렵습니다. 왜지요?
  332. 디스크에 데이터가 저장되는 방식 때문입니다.
  333. 데이터는 디스크의 원형 트랙에 저장됩니다.
  334. 플래터 표면에 원형의 트랙이 있습니다. 플래터는 여러 개가 있을 수 있지요.
  335. 헤드가 트랙을 찾기 위해 전/후로 움직입니다. 그러므로 원하는 트랙으로 헤드를 움직여야 하지요.
  336. 그리고 디스크가 회전하면서 데이터를 읽게 됩니다.
  337. 그 다음에 원하는 섹터를 찾아야 합니다. 트랙에는 50~60개의 섹터가 있고요 각각의 섹터는 4k 바이트의 데이터를 가지고 있습니다.
  338. 그러므로 디스크가 회전해서 원하는 섹터가 올 때까지 기다렸다가 데이터를 읽어야 합니다.
  339. 그리고 읽은 데이터에서 원하는 바이트를 찾아야 합니다.
  340. 어렵습니다. 그리고 느려요.
  341. 제대로 작성하지 않으면 아주 아주 오래 걸릴 수도 있습니다.
  342. 그래서 사람들은 이 문제를 전담할 시스템을 만들었습니다. 데이터베이스 말입니다.
  343. 그런데 상황이 변했습니다.
  344. 여기 내 노트북 보이나요? 내 노트북은 500MB짜리 SSD가 있습니다. 디스크는 없어요. 놀랍지는 않지요?
  345. 여기 디스크를 가진 사람 있나요?
  346. 여기 회전하는 디스크를 가진 사람?
  347. 이런! 진짜로요?
  348. 요즘 HDD를 사고싶은 사람은 없어요. SSD가 대세입니다.
  349. 어쩌면 서버 룸에는 HDD가 있을지도 모릅니다. 하지만 거기도 조만간 없어질 겁니다.
  350. 앞으로 몇 년 후에는 HDD는 사라질 겁니다. 모든 것이 RAM으로 교체되겠지요.
  351. RAM 말입니다.
  352. RAM은 원하는 바이트를 직접 읽을 수 있습니다.
  353. 무한한 용량을 가진 비휘발성 RAM이 우리가 추구하는 것 입니다.
  354. 가장 이상적인 저장 매체이지요.
  355. 그렇게 직접 액세스할 수 있는 저장 매체가 있다면 왜 SQL을 써야만 할까요?
  356. SQL은 어렵습니다. Table도 어렵습니다.
  357. 해시 테이블에서 데이터를 검색하기 보다는 포인터로 바로 액세스하는 것이 좋겠지요?
  358. 지금도 그렇게 하고 있지 않나요? 테이블에 저장된 데이터를 읽은 후에 사용하기에 더 좋은 구조에 저장합니다.
  359. 그냥 우리가 사용하는 포맷 그대로 저장하면 어떨까요?
  360. 내가 오라클이라면 아주 겁이 날 겁니다.
  361. 존재의 이유가 서서히 사라지고 있거든요.
  362. 대규모 데이터베이스 시스템이란 개념은 점차 사라지고 있습니다.
  363. 그럼 어플리케이션을 이런 사소한 것으로 어떻게 보호할까요?
  364. 이런 사소한 데이터베이스가 모든 것을 결정해버리곤 합니다. 하지만 웹을 격리한 방법으로 어플리케이션을 데이터베이스로부터 보호할 수 있습니다.
  365. 자 여기 또 하나 굵은 선을 그립니다.
  366. 자세히 보세요, 이 선을 지나는 모든 선은 어플리케이션을 향하고 있습니다.
  367. 데이터베이스를 어플리케이션의 플러그인으로 만들었습니다.
  368. 이제 오라클을 MySQL로 바꿀 수 있습니다.
  369. 아니면 MySQL을 버리고 CouchDB로 바꿀 수도 있지요.
  370. 아니면 CouchDB를 버리고 Datomic이나 다른 걸로 바꿀 수 있습니다.
  371. 데이터베이스를 플러그인처럼 교체할 수 있습니다.
  372. 데이터베이스를 실제로 바꾸지 않을지도 몰라요. 하지만 그럴 수 있다는 것은 좋은 겁니다. 실제로 필요하지 않다고 해도 말입니다.
  373. 그럼 어떻게 하면될까요? 저 위에 인터페이스를 하나 더 두면 됩니다.
  374. 엔티티 게이트웨이라고 이름을 붙였습니다.
  375. 보통 엔티티 하나에 게이트웨이 하나를 둡니다. 엔티티 게이트웨이의 메소드들은 모두 쿼리 메소드들 입니다.
  376. 모든 쿼리문에 해당하는 메소드가 존재합니다.
  377. 엔티티 게이트웨이의 구현부는 저 선 아래에 위치합니다.
  378. 구현부는 아마도 데이터베이스를 사용하겠지요.
  379. 자세히보세요. 데이터베이스에 관한 어떤 부분도 어플리케이션에 노출되지 않습니다.
  380. 그럼 엔티티 오브젝트는 어디에서 올까요? 아마도 데이터베이스에서 읽어져 올라올 겁니다. 테이블에 어떤 모양으로 저장되어있건 말이지요.
  381. 엔티티 게이트웨이의 구현체는 그 데이터들을 읽어 모아 엔티티 오브젝트에 저장합니다.
  382. 그런 후에 저 선 위로 전달하는 거지요.
  383. 저 선을 넘어오면 어플리케이션에게 엔티티 오브젝트가 되는 겁니다.
  384. 여기 Hibernate 쓰는 사람 있나요? ORM 툴?
  385. 누구 쓰는 사람 있어요?
  386. ORM 툴은 저 그림에서 어디에 있을까요?
  387. 구현부에 있습니다. 저 선 아래지요!
  388. 저 선 위에선 ORM 툴의 존재에 대해 아무것도 모릅니다.
  389. 혹시 비즈니스 오브젝트에 어노테이션이나 어트리뷰트가 붙어있나요? 없애 버리세요!
  390. 비즈니스 오브젝트들은 Hibernate 같은 툴과 직접적인 연관이 없어야 합니다.
  391. 저 선 아래의 것들은 데이터베이스 등에 오염된 사람이 개발하게 하세요.
  392. 비즈니스 오브젝트는 오염되지 않아야 합니다. 왜일까요?
  393. 오브젝트란 무엇인가요?
  394. 천천히 이야기해봅시다.
  395. 오브젝트란 무엇인가요? 오브젝트는 퍼블릭 메소드들의 집합입니다.
  396. 그 외에는 알려져선 안됩니다. 그렇지요?
  397. 그 안에 데이터가 있을지도 몰라요. 하지만 그걸 볼 수 있으면 안됩니다. 모두 비밀입니다.
  398. 여러분의 관점에서 오브젝트는 메소드 덩어리입니다. 데이터 덩어리가 아닙니다.
  399. 오브젝트는 메소드 덩어리입니다.
  400. 그러므로 오브젝트는 행위에 대한 내용입니다.
  401. 그러므로 오브젝트는 비즈니스 규칙에 대한 내용입니다.
  402. 데이터가 아닙니다.
  403. 아마도 안에 데이터가 있긴 하겠지요. 하지만 우리는 몰라요.
  404. 어떤 형태로 저장되는지 모릅니다. 알 필요도 없어요.
  405. 그럼 데이터 구조체는 무엇일까요?
    (역주: Object와 Data Structure를 구분하여 사용하고 있음)
  406. 데이터 구조체는 잘 알려진 데이터 요소들입니다. 누구에게나 공개되지요.
    (역주: Object와 Data Structure를 구분하여 사용하고 있음)
  407. 데이터 구조체에는 메소드가 없습니다.
  408. 데이터 구조체는 펑션이 없어요.
  409. 오브젝트와 데이터 구조체는 완전히 반대되는 것들입니다.
  410. 데이터 구조체는 공개된 데이터를 가지고 메소드가 없습니다.
    오브젝트는 메소드를 가지지만 공개된 데이터가 없습니다.
  411. 정확하게 반대이지요.
  412. ORM이란 말은 틀린 말입니다.
  413. 오브젝트와 관계데이터는 매칭할 수가 없어요.
  414. 데이터베이스에서 나온 것은 데이터 구조체입니다. 데이터 구조체는 오브젝트에 매칭할 수가 없는 것 이지요.
  415. 서로 완전히 다른 것이기 때문입니다.
  416. 엔티티에 저장되는 데이터는 어딘가에서 제공됩니다. 어딘지는 아무도 몰라요.
  417. 그리고 엔티티로 전달됩니다. 어떻게 전달되는지는 상관없어요.
  418. 그 엔티티 오브젝트들은 Hibernate가 생성한게 아닙니다.
  419. 아마도 엔티티 오브젝트들은 Hibernate가 만든 데이터 구조체들을 사용하고 있을지도 몰라요. 어떻게 하는지는 관심 없습니다.
  420. 저 검정선 아래의 Hibernate나 프레임워크에 대해선 아무 것도 몰라도 됩니다.
  421. 저 선 아래의 것들은 오염될 수도 있습니다.
  422. 저 선 위의 것들은 내 속살과 같이 소중한 것 입니다. 아주 소중하게 보호해야 하는 것 이지요.
  423. 저 위의 것들은 비즈니스 규칙들입니다. 나는 내 비즈니스 규칙들이 프레임워크로 오염되지 않게 할겁니다.
  424. 프레임워크. 사람들은 자신들이 사용하는 프레임워크를 좋아합니다. 아주 멋지지요.
  425. 프레임워크는 많은 시간을 절감해준다고 생각합니다. 실제로도 그렇습니다.
  426. 하지만 프레임워크 제작자는 우리를 프레임워크에 종속되도록 유도합니다.
  427. 그들은 베이스 클래스를 만들어서 우리가 그것들을 상속해서 사용하기를 바랍니다.
  428. 프레임워크의 베이스 클래스를 상속하는 순간 우리는 벗어나지를 못합니다.
  429. 그 베이스 클래스에 아주 강하게 엮이게 되는 거지요. 상속보다 더 강한 관계는 없습니다.
  430. 다른 사람의 베이스 클래스를 상속한다는 것은 아주 무거운 맹세를 하는 것과 같습니다.
  431. 반대로 프레임워크는 당신에게 아무런 맹세를 하지 않습니다.
  432. 비대칭적인 관계이지요.
  433. 프레임워크 제작자는 우리의 헌신으로 이익을 챙기지만 그들은 우리에게 어떤 책임도 지지 않습니다.
  434. 곰곰히 생각해보세요.
  435. 현명한 아키텍트는 저런 관계를 맺지않습니다.
  436. 현명한 아키텍트는 프레임워크를 비판적으로 바라봅니다. "저 프레임워크가 일을 어렵게 만들 수 있겠는 걸"
  437. "어플리케이션을 프레임워크에 단단히 엮으려고 하는 걸. 그럴 순 없지."
  438. "비즈니스 규칙과 프레임워크 사이에 경계를 만들어야겠어."
  439. "그래야 비즈니스 규칙들이 Hibernate나 Spring 같은 것들에 영원히 묶이지 않게 말이야."
  440. 나는 프레임워크를 이용할 겁니다. 아주 조심스럽게요.
  441. 왜냐하면 프레임워크 제작자는 내가 가장 중요하게 생각하는 것이 무엇인지 모르기 때문입니다.
  442. Fitnesse는 나와 아들 그리고 몇 몇 사람이 오래 전에 만들었습니다.
  443. 여기 Fitnesse 쓰는 사람이 있나요? 오 많군요 좋습니다.
  444. Fitnesse는 인수테스트를 작성하는 툴입니다.
  445. 위키 기반으로 개발되었지요. 위키 기반이라는 것이 중요합니다.
  446. 누가 위키를 개발했지요?
  447. 워드 커닝햄. 워드 커닝햄은 어떤 사람인가요?
  448. 위키 개발자! 하~ 그 것 보다 더 많습니다.
  449. 워드 커닝햄은 구루들의 구루입니다. 모든 구루들은 워드 커닝햄이 누구인지 압니다.
  450. 나처럼 컨퍼런스에 연사로 초빙되는 사람들은 모두 워드 커닝햄에 대해 알고있습니다.
  451. 우리는 워드 커닝햄을 리뷰합니다.
  452. 그가 에릭 감마에게 전화 걸어 이야기 했지요
  453. "이봐 에릭, 디자인 패턴이란 책을 써보는 게 어때?"
  454. 그는 캔트 백의 멘토이기도 했지요. 캔트 백에게 페어 프로그래밍, TDD, 에자일 개발 등을 가르쳤습니다.
  455. 당신이 소프트웨어의 역사를 유심히 본다면 아주 많은 곳에서 그의 흔적을 찾을 수 있을 겁니다.
  456. Fitnesse는 Wiki와 Fit를 기반으로 개발되었습니다. 둘다 워드 커닝햄의 발명품이지요.
  457. 오늘은 Wiki에 대해서만 이야기하겠습니다.
  458. 우리들은 Fitnesse를 자바로 개발하기로 결정했습니다. 12년이나 13년 전에요.
  459. 우리는 위키 형태로 만들기로 했습니다.
  460. 우린 처음에 생각했습니다. "위키 페이지들을 저장할 공간이 필요하겠군, 데이터베이스에 저장합시다. 어떤 데이터베이스가 좋을까"
  461. 그때는 오픈소스 데이터베이스는 MySQL밖에 없었습니다. 그래서 MySQL을 사용하기로 했지요.
  462. 그래서 MySQL을 설치하고 데이터 스키마를 정하려고 할 때에 누군가 이야기했습니다.
  463. "지금 당장 할 필요는 없지 않겠어?"
  464. "그건 나중에 하고 일단 다른 문제들 부터 해결하는게 좋을 것 같아."
  465. 다른 문제들이란 위키 텍스트를 HTML로 변경하는 작업이었습니다. 위키의 기본 기능이지요.
  466. 위키에 입력한 텍스트들을 받아서 HTML로 변경하는 것 말입니다.
  467. 그런 변환 작업이 아주 많이 있었어요.
  468. 그래서 3개월 동안은 데이터베이스는 잊고 지냈습니다.
  469. 위키 텍스트를 HTML로 저장하기위해 우린 WikiPage라는 오브젝트를 만들었습니다.
  470. 저기 위에 있지요.
  471. 추상 클래스인 WikiPage는 MockWikiPage가 구현하고 있습니다.
  472. WikiPage는 Load, Save 같은 펑션들을 가지고 있습니다.
  473. 하지만 실제 구현은 되어있지 않습니다. MockWikiPage의 Load/Save는 그냥 빈 껍데기입니다.
  474. 한 3달 동안 그렇게 작업했습니다.
  475. 모든 페이지 변환 코드가 끝난 후에 말했습니다. "자 이제 데이터베이스를 구동합시다."
  476. "저 페이지들을 어딘가에는 저장해야만 해요"
  477. 누군가가 말했습니다. "글쎄 아직 데이터베이스는 없어도 될 것 같은데"
  478. "대신에 변환된 페이지를 메모리에 저장하면 될 것 같아"
  479. "아직은 디스크에 저장할 필요는 없지 않아?"
  480. 그럴 필요는 없었지요. 그때 단위테스트 작성하느라 바빴거든요.
  481. 그래서 우린 WikiPage를 구현하는 또 다른 클래스를 만들었습니다. InMemoryPage였지요. 우린 그 안의 해시테이블에 모든 것을 저장했습니다.
  482. 우린 그렇게 1년을 더 보냈습니다.
  483. 데이터를 메모리에 저장하면서 계속 개발 했습니다.
  484. 드디어 Fitnesse가 동작을 했습니다.
  485. 실제 디스크에 저장하지 않는 상태로요.
  486. 아주 좋았던 점은 테스트들이 매우 빠르게 실행된다는 거였습니다. 데이터 베이스가 없었거든요.
  487. 반면에 전원을 끄고나면 모든 것이 사라지는건 좀 불편했지요.
  488. 그러다가 누군가 말했습니다. "자 이제 데이터베이스를 구동할 시간이야. MySQL을 설치합시다."
  489. 마침 그때 마이클 페더스가 같이 있었는데요
  490. 마이클이 이야기 했습니다. "글쎄 아직은 MySQL이 없어도 되지 않겠어?"
  491. "실제 필요한 것은 저장하는 거잖아. 그냥 해시 테이블의 내용을 파일에 저장하는게 훨씬 간단하지 않겠어?"
  492. 좀 옹색하지만 당분간은 괜찮아 보였습니다. 나중에 MySQL로 바꾸면되니까 일단 그렇게 했습니다.
  493. 그 뒤로 3개월간 계속 개발을 했습니다.
  494. 우린 들고 다니면서 사람들에게 보여줄 수 있어서 좋았습니다. 실제 저장도 되었고요.
  495. 진짜 위키처럼 동작을 했지요.
  496. 3개월 뒤에 누군가 이야기했습니다. "데이터베이스가 필요 없겠는걸."
  497. "잘 동작하는데. 파일에 저장해도 충분히 빨라"
  498. "이거면 충분한데."
  499. 우린 아키텍처적으로 매우 중요한 결정을 최대한 연기했고 결국엔 결정할 필요가 없게 되었습니다.
  500. 데이터베이스는 아예 넣지 않았습니다. 그런데 실제로는 다른 누군가가 추가하긴 했었지요.
  501. 고객 중 한 명이 와서 이야기 했습니다. "우린 데이터베이스가 필요합니다."
  502. "왜요? 파일시스템으로도 잘 동작합니다."
  503. 그가 이야기했습니다. "회사 정책입니다. 모든 데이터는 데이터베이스에 저장되어야 합니다."
  504. 누가 그렇게 이야기했는지는 모르겠습니다. 아주 유능한 데이터베이스 영업 사원이 있었나봅니다.
  505. 그래서 이야기했습니다. "꼭 데이터베이스가 필요하다면"
  506. "여기 WikiPage를 구현하는 MySQLPage를 만드세요. 그렇게만 하면 될겁니다."
  507. 바로 다음 날에 MySQL과 연동 작업은 끝났습니다.
  508. MySQL 연동 기능을 플러그인으로 배포했었는데요 아무도 사용하지 않아서 이젠 배포하고 있지 않습니다.
  509. 우린 아키텍처에 대한 의사결정을 미루고 미루고 또 미뤘습니다.
  510. 프로젝트의 마지막까지 미뤘고 결국에는 하지를 않았습니다.
  511. 우리가 가장 먼저 결정해야 한다고 생각했던 것인데 결국엔 안했어요.
  512. 따라서 이런 원칙을 이야기할 수 있겠지요.
  513. 좋은 아키텍처는 중요한 의사결정을 뒤로 미룰 수 있게 합니다.
  514. 아키텍트의 목표는 결정을 안 하는 것이에요.
  515. 가능한 정보를 많이 가지고 결정 할 수 있게 미루고 미루는 것 이지요.
  516. 상위 레벨의 결정을 미룰 수 있도록 아키텍처나 코드 구조를 설계해야 합니다.
  517. 어플리케이션 아키텍처를 설명할 때에 프레워크 이름을 말하지 마세요.
  518. "어플리케이션의 아키텍처가 무엇입니까? 네 우린 SQL서버, MVVM, ..."
  519. 이건 아키텍처에 대한 설명이 아닙니다.
  520. 단지 사용하는 툴들을 나열하는 것뿐입니다.
  521. 그건 어플리케이션의 아키텍처가 아닙니다.
  522. 어플리케이션의 아키텍처는 유즈케이스들입니다.
  523. 유즈케이스는 툴에 대해 몰라야 합니다.
  524. 저런 툴에 대한 결정은 가능한 늦게 해야 합니다.
  525. 웹이나 데이터베이스 없이 어플리케이션의 모든 부분을 실행 할 수 있어야 합니다.
  526. 어쩌면 설치가 쉬운 작은 웹 프레임워크를 잠시 쓸 수는 있겠지요.
  527. 간단한 시연을 위해서요. 거대한 웹 프레임워크를 구동하지 않고도요.
  528. 어쩌면 아주 심플한 데이터베이스를 사용할 수도 있겠지요. 단순히 데이터가 저장되는 것을 확인하려고요.
  529. 오라클 등으로 저런 작업을 하려면 라이선스 비용처럼 이것 저것 복잡한게 많습니다.
  530. 다음에 어플리케이션을 개발할 때는 어떤 결정을 미룰 수 있는지 생각해보세요.
  531. 어플리케이션은 플러그인 구조이어야 합니다. 아키텍처는 플러그인 구조여야 합니다.
  532. GUI, 데이터베이스, 프레임워크 같은 디테일들은 모두 유즈케이스의 플러그인이 되어야 합니다.
  533. 유즈케이스가 어플리케이션의 핵심이기 때문입니다.
  534. 물론 고객은 웹 페이지를 보고 싶어하지요.
  535. 플러그인 아키텍처로도 역시 고객에게 웹 페이지를 보여줄 수 있습니다.
  536. 프레임워크에 큰 헌신을 맹세할 필요가 없습니다.
  537. 웹 프레임워크에 막대한 헌신을 맹세할 필요가 없습니다.
  538. 처음엔 간단한 웹 프레임워크를 사용해서 보여주면 됩니다.
  539. 만약에 꼭 제대로 된 프레임워크를 사용하고 싶다면, 그렇게 하세요. 단 플러그인 구조는 유지하세요.
  540. 그래야 필요할 때 빠르게 대체할 수 있습니다.
  541. 이제 마지막 주제입니다. (TDD)
  542. TDD는 이미 이야기했지요?
  543. 감사합니다. 질문 있습니까?
  544. 잘 안보이네요. 밑으로 내려가보겠습니다.
  545. 여전히 안보이군요.
  546. 자 질문 있습니까?
  547. 손드는게 안보이니까 크게 이야기해주세요.
  548. (질문 중)
  549. 오라클 같은 관계형 데이터베이스의 종말을 예고했는데 그 다음은 어떤 것이 될 거라고 생각하냐고요?
  550. 아주 좋은 질문입니다.
  551. 그냥 RAM으로 충분할지도 모르지요. 왜 데이터베이스를 대체할 것이 필요할까요?
  552. RAM에 데이터를 구성하고 RAM의 데이터가 비휘발성이라면, 더 필요한 게 있을까요?
  553. 하지만 더 필요한 게 있다고 가정하고 이야기해봅시다.
  554. 그 다음은 어떤 것 일까요?
  555. 여기 CQRS에 대해 들어본 사람 있나요?
  556. 조금 있군요.
  557. CQRS는 참 흥미로운 아이디어입니다.
  558. 우리가 무한대의 고속 메모리를 가졌다고 생각해봅시다. 아주 빠른 RAM이요.
  559. 어쩌면 디스크일 수도 있겠지요.
  560. 상태 값을 저장할 이유가 있을까요?
  561. 그냥 트랜즈액션만 저장하면 되지 않을까요?
  562. 은행 계좌의 잔고를 저장하는 대신에 계좌를 생성한 트랜잭션을 저장하면 어떨까요?
  563. 은행 계좌의 이름, 주소, 잔고를 변경시키는 트랜잭션들이요.
  564. 왜 트랜잭션들을 저장한 후에 상태 값들을 재구성하면 어떨까요?
  565. 아마도 시간이 오래 걸린 거라고 생각할겁니다.
  566. 맞아요. 하지만 CPU의 처리능력은 막강합니다.
  567. 이제는 할 수 있어요. 우린 거의 무한대의 처리능력과 메모리를 가지고 있습니다.
  568. 그냥 이벤트들만 저장하는 건 어떨까요?
  569. 매우 흥미로운 아이디어라고 생각합니다.
  570. 이벤트들을 저장하면 아무 것도 삭제할 필요가 없습니다.
  571. 업데이트를 할 필요도 없지요.
  572. CRUD 알지요? Create. Read. Update. Delete.
  573. U와 D 두 글자를 없어지고 C와 R만 남게될 겁니다.
  574. 생성하고 조회만합니다. 업데이트나 삭제 할 필요가 없어집니다.
  575. 업데이트나 삭제를 안한다면 트랜잭션은 없어도 됩니다.
  576. 업데이트를 안 한다면 동시성과 관련된 문제가 없어집니다.
  577. 아주 흥미롭지요.
  578. 이런 생각들을 기반으로 하는 프레임워크들이 있을까요? 네 있습니다.
  579. 몇 개인가 있지요.
  580. Write Only 데이터베이스들이지요. Write Once & Read Many Times.
  581. 지금은 이야기를 하지 않겠습니다만 웹에서 검색을 하면 나옵니다.
  582. 한 번 찾아보세요.
  583. 관계형 데이터베이스를 그런 것 들로 대체할지도 모르지요.
  584. Couch나 Mongo DB로 교체할지도 모릅니다. 어떠면 새로 만들 수도 있겠지요.
  585. 상관없어요. 대형 벤더에서 제공하는 것을 사용할 필요가 없습니다.
  586. 저 하늘 위의 거대한 회사들이요.
  587. 저 하늘 위에서 말합니다. "그래 우리 데이터베이스 시스템의 사용을 허락하노라."
  588. 그냥 DB를 만들어 써도 됩니다. 그렇게 어렵지 않아요.
  589. 다른 질문 있나요?
  590. 그렇게 하니까 잘 보이네요.
  591. 오케이. 또 다른 질문 없나요?
  592. (누군가 질문 하는 중)
  593. 의사결정을 미루는 것이 어려울 때도 있는데...
  594. 가족이 있을 때요? (청중들이 웃음)
  595. 가족 동반 휴가처럼 여러 요소들이 같이 결정되는 것을 이야기하는 것 이지요? 결정이 필요한 것 중에 연기가 가능한 것들이 있습니다.
  596. 예를 들어, 어떤 언어로 개발을 할까? 와 같은 결정은
  597. 일찍 해야겠지요.
  598. 그렇지요? 뭔가 작성을 해야 합니다.
  599. 데이터베이스가 있어야 한다는 것은 아마도 일찍 결정해야 할 겁니다.
  600. 웹 어플리케이션이어야 한다는 것도 일찍 결정해야 할 겁니다.
  601. 어떤 프레임워크를 사용할지 결정하는 것? 아닙니다.
  602. 가족 동반 휴가에 비유했었지요?
  603. 휴가로 어디를 갈지는 일찍 결정해야겠지요. 어떤 차 모델을 선택할지도 미리 결정해야 할까요?
  604. 6개월 전에 여행을 계획할 때에 미리 신차를 뽑아야 할까요?
  605. 여행 전에 차가 고장이 날지도 모릅니다.
  606. 차는 단순히 이동 수단입니다. 짐을 싣고 가족이 탈 수 있으면 충분한 거지요.
  607. 여행을 갈 수 있으면 되는 겁니다.
  608. 데이터베이스 시스템은 차와 같습니다. 여행의 초반에 미리 결정할 필요가 없는 거지요.
  609. 가장 최후까지 지연시킬 수 있습니다.
  610. 여행가기 전 날에 신차를 살 수도 있는 거지요.
  611. 왜요?
  612. 복권에 당첨될지도 모르지요.
  613. 어쩌면 아기가 태어나서 공간이 더 필요할지도 모릅니다.
  614. 여행가기 직전까지 여러 일들이 발생할 수 있습니다.
  615. 다른 질문 있나요?
  616. 네 저기 뒤에요.
  617. (누군가 질문 중)
  618. 레거시 시스템은 어떻게 하냐고요?
    (역주: 에자일 세계에서 레거시 시스템은 단위 테스트가 없는 시스템을 의미함)
  619. 남은 시간으로 설명하긴 힘들겠군요.
  620. 그래서 한 단어로 답변하고. 그에 대해 설명하겠습니다.
  621. 점진적인 접근입니다.
  622. 사람들은 레거시 코드를 없애 버리고 새로 개발하고 싶어합니다.
  623. 그렇게 하지 마세요.
  624. 보통 실패하게됩니다. 많은 시간과 돈을 낭비하고 말입니다.
  625. 시스템의 작은 부분을 선택한 후에
  626. 그 부분만 다시 작성하고
  627. 동작하게 만드세요.
  628. 결국 군데 군데 수정이 되겠지요. 하지만 수정된 부분은 원래 코드보다 개선됩니다.
  629. 그렇게 계속 반복합니다.
  630. 오랜 시간 동안 많은 노력을 기울여 점진적으로 개선이 될 것 입니다.
  631. 신규 기능을 추가할 때에도 같은 방법으로 합니다.
  632. 사실 이건 일반적인 코드 개선 과정입니다.
  633. 크게 변경하는 것은 하지 마세요. 위험합니다.
  634. 감사합니다. 다음에 봅시다.