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