1 00:00:04,001 --> 00:00:07,507 준비 됐나요? 2 00:00:08,922 --> 00:00:10,753 좋습니다. 3 00:00:22,778 --> 00:00:25,208 저기 빨간 점 보이나요? 4 00:00:30,020 --> 00:00:31,743 왜 빨간색일까요? 5 00:00:35,418 --> 00:00:36,934 위험해서라고요? 6 00:00:37,798 --> 00:00:41,339 마음에 드네요. "이봐! 나를 쿠바로 망명시켜줘." 7 00:00:43,073 --> 00:00:51,915 그래요. 이 레이저 때문에 공항에서 잡혀간 적도 있었지요. 8 00:00:51,988 --> 00:00:55,109 거기에는 "DANGER" 이라고 써 붙여 있었어요. 9 00:00:56,990 --> 00:00:59,148 그나저나 왜 빨간색 일까요? 10 00:01:01,035 --> 00:01:02,399 나는 초록색 레이저도 있습니다. 11 00:01:02,469 --> 00:01:05,432 모두 레이저 몇 개 정도는 있어야 해요. 12 00:01:06,280 --> 00:01:09,323 나는 항상 세 개는 들고 다닙니다. 13 00:01:11,184 --> 00:01:15,861 그 중 하나가 빨간색인데요. 가방에 배터리와 함께 들고 다닙니다. 14 00:01:15,901 --> 00:01:17,887 ... 15 00:01:18,277 --> 00:01:22,806 이 빨간색 레이저는 12달러면 살 수 있습니다. 16 00:01:24,341 --> 00:01:25,436 빨간색 레이저 보이지요? 17 00:01:25,460 --> 00:01:28,763 멋지지요? 여기 초록색도 있습니다. 18 00:01:30,029 --> 00:01:31,272 이 것도 좋아요. 19 00:01:33,062 --> 00:01:34,684 아주 밝지요. 20 00:01:34,752 --> 00:01:39,001 특별할 건 없지만 그래도 아주 밝아요. 21 00:01:39,075 --> 00:01:41,025 이 걸 살짝 개조할 수도 있습니다. 22 00:01:41,025 --> 00:01:44,585 레지스터 하나를 교체하면 23 00:01:44,595 --> 00:01:47,797 출력을 0.25와트로 높일 수가 있는데요. 24 00:01:47,847 --> 00:01:50,857 그러면 풍선 정도는 터트릴 수 있습니다. 25 00:01:51,668 --> 00:01:54,919 멋지지요. 펑! 26 00:01:57,124 --> 00:02:00,599 하지만 내가 제일 좋아하는 레이저는 이거입니다. 27 00:02:02,496 --> 00:02:05,139 왜냐하면 28 00:02:06,698 --> 00:02:12,734 저기 보이나요? 29 00:02:14,716 --> 00:02:19,295 작은 보라색 점. 저기 위에 보여요? 30 00:02:20,906 --> 00:02:24,869 어디 봅시다. 오! 밝게 잘 보이네요. 31 00:02:25,269 --> 00:02:27,833 여기 바로 위에요. 아주 밝게 잘 보입니다. 32 00:02:28,344 --> 00:02:31,192 하지만 저기에 비추면 잘 보이지 않아요. 33 00:02:31,445 --> 00:02:33,524 보이나요? 잘 안보입니다. 34 00:02:33,559 --> 00:02:35,886 여기에는 보이나요? 아니군요. 35 00:02:36,492 --> 00:02:39,445 음. 잘 안보여요. 36 00:02:39,477 --> 00:02:48,820 그런데 이런 걸 발견했어요. 37 00:02:51,325 --> 00:02:57,433 그냥 사인펜입니다. 레이저를 쏴도 특별히 달라지진 않네요. 38 00:02:57,465 --> 00:02:59,458 하지만 뚜껑을 보세요. 39 00:03:02,153 --> 00:03:05,457 노란색이네요! 40 00:03:05,529 --> 00:03:07,331 파란색이 아닙니다. 41 00:03:08,210 --> 00:03:11,093 저기 오랜지 색 부분 보이나요? 42 00:03:11,093 --> 00:03:13,747 잘 보세요. 조심스럽게 겨냥해야 합니다. 43 00:03:14,353 --> 00:03:17,780 오! 오랜지 색이에요! 44 00:03:17,838 --> 00:03:19,988 이건 어떤 레이저일까요? 45 00:03:22,060 --> 00:03:26,491 이 건 조금 다른 레이저입니다. 46 00:03:33,884 --> 00:03:41,141 내 안경은 햇빛을 받으면 렌즈가 짙어지는데요 47 00:03:44,719 --> 00:03:47,650 잘 보일지 모르겠지만 렌즈들이 모두 까매졌습니다. 48 00:03:47,688 --> 00:03:50,853 그렇지요? 여러분들이 안보이네요. 49 00:03:50,917 --> 00:03:53,470 이건 자외선 레이저입니다. 50 00:03:53,560 --> 00:03:57,504 하지만 자외선 레이저라고 팔지는 않아요. 아마존에서 17달러면 살 수 있습니다. 51 00:03:57,504 --> 00:04:01,100 보라색 레이저라고 팔고 있지만 거짓말입니다. 52 00:04:01,368 --> 00:04:06,948 보라색 레이저 보다 더 멋진 거에요. 자외선 레이저입니다. (역주: Ultra Violet Laser, Violet Laser) 53 00:04:06,948 --> 00:04:09,637 누구나 자외선 레이저 하나쯤은 있어야 해요. 54 00:04:09,703 --> 00:04:12,649 레이저 포인터로는 쓸모가 없지만 55 00:04:12,701 --> 00:04:16,997 안경에 작은 그림들을 그릴 수는 있어요. 56 00:04:18,598 --> 00:04:21,843 "안경에 이름을 썼어!" 57 00:04:24,672 --> 00:04:26,507 우야당간...... 58 00:04:29,240 --> 00:04:31,126 저기 코드를 보세요. 59 00:04:32,639 --> 00:04:34,428 어떤 코드인지 아는 사람있나요? 60 00:04:35,765 --> 00:04:38,325 안경 렌즈가 까매서 볼 수 가 없네요. 61 00:04:38,771 --> 00:04:40,798 어떤 코드인지 알겠나요? 62 00:04:42,267 --> 00:04:44,242 저건 PDP-8의 소스 코드입니다. 63 00:04:44,945 --> 00:04:48,863 1970년대의 소스코드는 저렇게 생겼었습니다. 64 00:04:48,928 --> 00:04:54,753 내가 20살 즈음에 저런 코드를 작성했었지요. 65 00:04:55,825 --> 00:04:58,618 20대 초반에도 그랬습니다. 66 00:05:00,074 --> 00:05:03,543 저 소스 코드를 보세요. 67 00:05:03,979 --> 00:05:06,305 어떤 의미인지 아는 사람 있나요? 68 00:05:07,940 --> 00:05:13,611 프로그램이 메모리에 로딩될 주소입니다. 69 00:05:15,334 --> 00:05:20,159 당시에는 소스 코드에 프로그램이 로딩될 주소를 명시했었습니다. 70 00:05:21,160 --> 00:05:23,551 이 프로그램은 메모리 주소 200에 로딩될 겁니다. 71 00:05:24,245 --> 00:05:26,996 그리고 데이터는 300에 저장됩니다. 72 00:05:27,042 --> 00:05:28,052 어떤가요? 73 00:05:28,669 --> 00:05:32,636 당연한거에요. 여러분은 프로그램이 어느 주소에 로딩될지 알아야 합니다. 74 00:05:32,668 --> 00:05:34,836 여러분 말고 또 누가 그걸 결정하겠어요? 75 00:05:34,905 --> 00:05:37,708 프로그래머가 메모리를 컨트롤 해야지요. 76 00:05:39,471 --> 00:05:41,323 이대로는 아무런 문제가 없습니다. 77 00:05:43,026 --> 00:05:45,572 다른 그림들도 보여드릴게요. 78 00:05:46,268 --> 00:05:50,080 어디 봅시다. 79 00:05:50,151 --> 00:05:55,087 이게 아니네요. 이 그림 말고 다른 게 있습니다. 80 00:05:56,140 --> 00:06:01,655 요즘은 문서를 열면 81 00:06:02,386 --> 00:06:09,623 같이 열렸던 문서들이 모두 같이 열려버려요. 82 00:06:10,509 --> 00:06:12,138 저장할 필요 없고요. 83 00:06:12,177 --> 00:06:14,630 이게 찾던 그림니다. 84 00:06:17,049 --> 00:06:20,356 여러분이 이런 개발 언어를 사용한다고 생각해보세요. 85 00:06:20,899 --> 00:06:23,826 그리고 이런 프로그램을 작성하는 거지요. 86 00:06:24,626 --> 00:06:28,010 이 프로그램은 여기에 위치합니다. 주소 200에서 시작하지요. 87 00:06:28,900 --> 00:06:32,107 여기 다른 사람이 작성한 서브루틴 라이브러리가 있습니다. 88 00:06:32,524 --> 00:06:35,145 그나저나 그 당시에는 서브루틴 라이브러리가 드물었지요. 89 00:06:35,229 --> 00:06:37,768 필요한 서브루틴은 직접 작성하곤 했습니다. 90 00:06:37,818 --> 00:06:45,607 몇 몇 사람이 아주 유용한 서브루틴을 작성한 후에야 사람들은 자신의 프로그램에 그 것들을 넣기 시작했습니다. 91 00:06:45,637 --> 00:06:50,378 "그냥 프로그램에 추가해서 같이 컴파일 합시다." 92 00:06:50,411 --> 00:06:51,663 보통 그런 방식으로 했지요. 93 00:06:51,695 --> 00:06:53,496 서브루틴의 소스 코드를 가져와서 내 코드와 합치는 거죠. 94 00:06:53,531 --> 00:06:55,465 그럼 어떤 문제가 있을까요? 95 00:06:58,735 --> 00:07:02,218 지금 우린 1970년대를 이야기하고 있습니다. 96 00:07:02,314 --> 00:07:05,566 그 당시 프로그램은 종이 테이프에 저장되었습니다. 97 00:07:06,124 --> 00:07:10,498 종이 테이프는 초당 50문자 정도를 저장했습니다. 운이 좋은 경우에요. 98 00:07:10,534 --> 00:07:19,939 그래서 소스 코드가 길어지면 컴파일 타임이 몇 분씩이나 길어지곤 했습니다. 99 00:07:20,346 --> 00:07:26,642 그러다 보면 서브루틴 라이브러리가 너무 길어서 같이 컴파일 하지 못하는 경우도 생깁니다. 100 00:07:26,642 --> 00:07:35,124 그런 경우는 서브루틴 라이브러리를 따로 컴파일 해서 메모리 주소 1200에 로딩합니다. 101 00:07:35,847 --> 00:07:42,367 메모리 주소 1200에 컴파일된 바이너리 파일을 로딩하는 겁니다. 102 00:07:42,417 --> 00:07:45,363 메인 프로그램은 메모리 주소 200에 로딩합니다. 103 00:07:45,396 --> 00:07:49,044 그리고 심볼 정보를 담은 작은 파일이 있어요. 104 00:07:49,122 --> 00:07:55,016 심볼을 보고 각 서브 루틴들이 어디에 로딩되어 있는지를 알 수 있습니다. 105 00:07:55,016 --> 00:08:03,131 예를 들어 Get 서브루틴이 205번지에 있고 Put 서브루틴이 210번지에 있다는 것을 알 수 있는 거지요. 106 00:08:03,518 --> 00:08:06,998 심볼 정보들은 프로그램과 함께 컴파일이 됩니다. 107 00:08:07,032 --> 00:08:09,907 서브루틴 라이브러리는 따로 로딩됩니다. 그리곤 잘 동작하겠지요. 108 00:08:12,236 --> 00:08:14,215 그럼 무엇이 문제일까요? 109 00:08:15,705 --> 00:08:19,428 프로그램 크기가 변하지 않는 경우가 있을까요? 110 00:08:20,839 --> 00:08:22,122 프로그램은 항상 커집니다! 111 00:08:22,634 --> 00:08:26,489 계속 커지다 보면...... 어디 봅시다. 112 00:08:28,017 --> 00:08:29,632 여기 다른 그림이 있어요. 113 00:08:34,783 --> 00:08:36,475 네 이겁니다. 114 00:08:40,664 --> 00:08:43,767 자! 메인 프로그램이 아주 커졌어요. 115 00:08:43,767 --> 00:08:47,278 서브루틴을 덮어 써버렸네요. 정상적으로 동작하지 않습니다. 116 00:08:49,171 --> 00:08:56,041 메인 프로그램이 서브루틴을 덮어써버렸지만 메인 프로그램은 그걸 모릅니다. 117 00:08:56,073 --> 00:09:02,337 메인 프로그램이 1205번지를 호출하면 서브루틴이 아닌 자기의 어딘가를 실행하게 됩니다. 118 00:09:02,577 --> 00:09:04,491 개발자도 어떤 상황인지 몰라요. 119 00:09:04,510 --> 00:09:08,095 한참 디버깅 한 뒤에야 깨닫습니다. "이런, 프로그램이 너무 커져버렸네!" 120 00:09:08,914 --> 00:09:11,360 그럼 어떻게 해결해야 할까요? 121 00:09:13,744 --> 00:09:17,567 여러분들은 프로그래머자나요? 잘 생각해보세요. 122 00:09:20,598 --> 00:09:23,282 서브루틴 라이브러리를 건너 뛰는 겁니다. 123 00:09:23,954 --> 00:09:27,486 서브루틴들을 피해서 메인 프로그램을 배치하고 실행하는 거지요. 124 00:09:28,322 --> 00:09:31,370 그런데 서브루틴 라이브러리도 점점 커집니다. 125 00:09:32,140 --> 00:09:39,809 그러고 나면...... 이 그림이 맞는지 봅시다. 126 00:09:39,842 --> 00:09:42,093 이건가? 네 맞습니다. 127 00:09:42,505 --> 00:09:45,243 그러고 나면 이런 문제가 생깁니다. 128 00:09:48,209 --> 00:09:50,504 실제 현장에서 발생하던 문제들입니다. 129 00:09:51,014 --> 00:09:53,910 이런 문제들을 해결해야만 했었습니다. 130 00:09:53,946 --> 00:09:55,702 어떻게 해결했는지 알겠나요? 131 00:09:59,595 --> 00:10:04,698 우리는 재배치할 수 있는 코드를 생각해냈습니다. 132 00:10:04,730 --> 00:10:10,495 "이봐, 프로그램을 절대 주소 값에 로딩하는 건 너무 문제가 많아." 133 00:10:10,528 --> 00:10:17,440 "코드에 프로그램이 로딩될 위치를 넣지 않고 컴파일 하는 방법이 필요해." 134 00:10:17,813 --> 00:10:20,630 "로더에게는 로딩할 위치를 따로 알려주는 거야." 135 00:10:21,435 --> 00:10:23,141 그러려면 또 다른 이슈가 있습니다. 136 00:10:23,632 --> 00:10:29,658 바이너리 파일이 순수한 바이너리가 아니게되는 것 입니다. 137 00:10:29,705 --> 00:10:38,706 어떤 숫자는 주소가 아니라 오프셋이라고 말해주는 정보가 바이너리에 추가되기 때문이지요. 138 00:10:39,030 --> 00:10:47,994 로더는 오프셋으로 표시된 모든 주소에 시작 주소를 더해야만 합니다. 139 00:10:49,321 --> 00:10:51,940 결과적으로 재배치 가능한 로더는 잘 동작했습니다. 140 00:10:51,988 --> 00:10:54,619 재배치 가능한 바이너리와 로더를 개발했습니다. 141 00:10:54,619 --> 00:10:57,034 하지만 새로운 문제가 생겼습니다. 142 00:10:57,234 --> 00:11:00,415 서브루틴이 어디에 있는지를 알아야만 했지요. 143 00:11:00,447 --> 00:11:05,737 서브루틴이 임의로 배치된다면 어떻게 로딩된 위치를 알 수 있을까요? 144 00:11:06,007 --> 00:11:11,043 결국 그 정보도 바이너리 파일에 추가되어야 합니다. 145 00:11:11,264 --> 00:11:19,687 처음에는 순수한 바이너리였던 파일이 점점 괴상한 파일이 되어 버립니다. 146 00:11:19,726 --> 00:11:21,301 파일안에 온갖 잡다한 것들이 들어가있지요. 147 00:11:21,372 --> 00:11:28,293 이제 바이너리 파일 안에는 서브루틴들의 이름이 들어가야 합니다. 148 00:11:28,357 --> 00:11:32,468 그리고 각 서브루틴이 어디에 로딩될지도 알려줘야 하지요. 149 00:11:32,523 --> 00:11:37,614 그리고 로더는 각 서브루틴을 어디에 로딩했는지 기억해야 합니다. 150 00:11:37,682 --> 00:11:42,622 그런 후에 프로그램에는 또 필요한 것이 있습니다. 151 00:11:42,694 --> 00:11:47,250 그건 이렇게 말하겠지요. "이봐, 난 이 프로그램들이 어디에 로딩될지 알아야겠어." 152 00:11:47,250 --> 00:11:53,432 "그리고 로더는 프로그램이 사용하는 서브루틴들을 링크해야 해." 153 00:11:57,322 --> 00:12:00,831 그 당시의 컴퓨터는 느렸습니다. 154 00:12:00,899 --> 00:12:02,548 디스크도 매우 느렸지요. 155 00:12:02,626 --> 00:12:04,539 메모리도 많지 않았습니다. 156 00:12:04,621 --> 00:12:08,102 디스크도 운이 좋으면 몇 MB 정도 가질 수 있었지요. 157 00:12:08,173 --> 00:12:14,636 디스크의 탐색 속도도 매우 느렸습니다. 158 00:12:14,673 --> 00:12:18,136 그래서 링크 시간이 아주 오래 걸렸지요. 159 00:12:18,201 --> 00:12:22,206 라이브러리가 늘어나면서 점점 더 심해졌습니다. 160 00:12:22,257 --> 00:12:23,743 프로그램이 더 많아지고 커지면서 161 00:12:23,784 --> 00:12:26,032 링크하는데에 한 시간도 걸렸습니다. 162 00:12:26,082 --> 00:12:28,448 여기 링크에 한 시간이나 걸리는 사람이 있나요? 163 00:12:28,480 --> 00:12:30,845 여기 80년대에서 일하는 사람이 있어요? 164 00:12:30,880 --> 00:12:32,694 이런! 지금도 그렇게 오래 걸린다고요? 165 00:12:32,776 --> 00:12:35,263 그럼 C++ 프로그래머겠군요. 166 00:12:36,524 --> 00:12:38,661 거기 셔츠에 써있어요. 167 00:12:38,701 --> 00:12:40,747 OSLO C++ User Group 이라고요. 168 00:12:41,137 --> 00:12:42,647 링크 시간이 너무 길어지는 문제는 169 00:12:45,358 --> 00:12:50,458 70년대에도 있었습니다. 그때 프로그램은 훨씬 작았었지만요. 170 00:12:50,500 --> 00:12:57,964 해결책은 로딩 중에 링크 단계를 제거하는 거였습니다. 171 00:12:57,964 --> 00:13:02,302 링크는 컴파일에 포함되어 두 번째 단계로 수행됐습니다. 172 00:13:02,302 --> 00:13:07,435 컴파일이 끝나면 모든 링크 정보가 포함된 재배치 가능한 파일이 만들어 졌습니다. 173 00:13:07,468 --> 00:13:10,141 결과적으로 프로그램 실행 시점에 로딩이 가능해졌습니다. 174 00:13:10,141 --> 00:13:12,488 속도도 상대적으로 빨랐습니다. 175 00:13:13,287 --> 00:13:17,964 그 후 여러 해 동안 이 방식이 유지되었습니다. 176 00:13:18,015 --> 00:13:24,358 먼저 컴파일 해서 바이너리 파일을 만들고 바이너리 파일들을 링크해서 실행파일을 만듭니다. 177 00:13:24,401 --> 00:13:26,497 그런 후에 실행 파일은 로딩할 수 있게 됩니다. 178 00:13:26,531 --> 00:13:29,877 90년대까지 그런 방식을 유지했어요. 179 00:13:29,942 --> 00:13:33,540 그러다 90년대에 변화가 생겼습니다. 180 00:13:33,588 --> 00:13:36,238 무어의 법칙입니다. 181 00:13:36,772 --> 00:13:38,009 무어의 법칙이 무엇이지요? 182 00:13:39,302 --> 00:13:43,558 프로세서는 18개월 마다 두 배씩 빨라진다는 것 입니다. 183 00:13:43,671 --> 00:13:52,960 1970년대부터 적용해봅시다. 당시의 프로세서는 0.5 MIPS 정도의 처리 능력을 가졌습니다. 184 00:13:53,640 --> 00:13:56,959 그런 게 1990년대까지 진행되었지요. 185 00:13:57,025 --> 00:13:59,999 그럼 20년이면 18개월이 몇 번이나 지난 것 이지요? 186 00:14:00,048 --> 00:14:02,176 18개월이 몇 번 이지요? 187 00:14:02,176 --> 00:14:03,981 대략 15번 정도네요. 188 00:14:03,981 --> 00:14:07,257 그럼 2의 15승 이네요. 189 00:14:08,369 --> 00:14:09,286 어디봅시다. 190 00:14:09,338 --> 00:14:11,523 2의 15승이면 얼마나 되지요? 191 00:14:11,602 --> 00:14:13,700 대략 32000 정도 향상된 거네요! 192 00:14:13,700 --> 00:14:15,171 실제로도 대략 비슷합니다. 193 00:14:15,223 --> 00:14:18,751 0.5MHz에서 2.8GHz로 증가했으니까요. 194 00:14:18,786 --> 00:14:21,746 음 90년대에는 1GHz 정도였겠지요. 195 00:14:21,787 --> 00:14:24,907 당시에는 디스크의 성능도 좋아졌습니다. 196 00:14:24,941 --> 00:14:27,232 디스크의 회전 속도가 빨라졌습니다. 197 00:14:27,300 --> 00:14:31,782 플래터에 저장되는 데이터도 훨씬 많아져서 헤드가 움직이는 거리도 짧아졌지요. 198 00:14:31,830 --> 00:14:38,692 용량이 수백MB나 되는 디스크도 나왔습니다. 199 00:14:40,512 --> 00:14:44,219 누군가 아주 좋은 아이디어를 냈습니다. 200 00:14:44,270 --> 00:14:46,157 아주 좋은 아이디어에요. 201 00:14:47,454 --> 00:14:50,440 "이제 링크를 따로 할 필요가 없겠는걸." 202 00:14:51,042 --> 00:14:54,378 "로딩할때 같이 링크해도 되겠네." 203 00:14:54,424 --> 00:14:56,582 ActiveX를 기억하나요? 204 00:14:56,621 --> 00:14:58,946 OLE는요? 205 00:14:59,546 --> 00:15:01,917 DLL이 무엇의 약어이지요? 206 00:15:04,119 --> 00:15:08,215 Dynamically Linked Library. 207 00:15:08,258 --> 00:15:11,120 로딩될 때에 링크된다는 뜻 입니다. 208 00:15:11,153 --> 00:15:14,817 링크 단계가 다시 로더에게 넘어갔습니다. 209 00:15:15,699 --> 00:15:19,203 그렇게 지금까지 이어져왔습니다. 210 00:15:20,762 --> 00:15:22,616 여기 닷넷 프로그래머 있나요? 211 00:15:23,668 --> 00:15:25,037 오! 아주 많군요. 212 00:15:25,070 --> 00:15:28,122 자바 프로그래머 손들어 보세요. 213 00:15:28,189 --> 00:15:29,952 얼마 없네요. 어떻게 된 거지요? 214 00:15:31,001 --> 00:15:35,314 어떻게 닷넷 개발자만 있나요? 아... 이 컨퍼런스가 닷넷 관련된 행사 인가요? 215 00:15:36,034 --> 00:15:41,840 닷넷에는 DLL이 있습니다. 216 00:15:41,872 --> 00:15:43,732 Dynamically Linked Libraries. 217 00:15:43,765 --> 00:15:45,922 자바에는 Jar 파일이 있습니다. 218 00:15:45,969 --> 00:15:50,940 Jar 파일도 결국 DLL입니다. 같은 의도로 만들어 졌지요. 219 00:15:51,780 --> 00:15:56,055 C++는...... MS 환경에서 작업을 하면 DLL을 사용합니다. 220 00:15:56,088 --> 00:15:58,850 UNIX 계열 환경에서 작업을 하면 Shared Library가 있는데요 221 00:15:58,850 --> 00:16:01,031 이 것도 역시 DLL과 동일합니다. 222 00:16:01,080 --> 00:16:05,131 지금도 동적으로 링크하는 방식이 일반적인데요 223 00:16:05,165 --> 00:16:07,867 이런 과정들을 거쳐 현재까지 왔습니다. 224 00:16:11,980 --> 00:16:13,626 DLL을 몇 개나 가지고 있나요? 225 00:16:15,342 --> 00:16:18,575 비주얼 스튜디오에서 작업하는 사람들 226 00:16:18,608 --> 00:16:20,415 솔루션에 프로젝트가 몇 개나 있나요? 227 00:16:21,315 --> 00:16:23,550 60개? 그다지 나쁘지 않네요. 228 00:16:23,550 --> 00:16:25,017 60개 보다 많은 사람? 229 00:16:25,060 --> 00:16:26,597 있군요. 230 00:16:26,635 --> 00:16:28,094 200개 이상 되는 사람? 231 00:16:30,942 --> 00:16:33,132 왜 그렇게 하는지 아나요? 232 00:16:33,215 --> 00:16:38,055 왜 소스 코드를 쪼개서 DLL들에 분산시켜 놓는지 아나요? 233 00:16:38,886 --> 00:16:40,692 질문을 다르게 해보겠습니다. 234 00:16:41,272 --> 00:16:43,624 어플리케이션을 배포할 때에 235 00:16:44,590 --> 00:16:50,366 모든 DLL을 모아서 한 묶음으로 배포하나요? 236 00:16:52,521 --> 00:16:57,677 그렇다면 왜 동적으로 링크하지요? 237 00:16:57,728 --> 00:16:59,395 정적으로 링크하세요. 238 00:17:00,269 --> 00:17:04,819 왜 굳이 동적으로 링크하지요? 모든 DLL을 모아서 239 00:17:04,887 --> 00:17:07,260 하나의 거대한 덩어리로 만들고 240 00:17:07,313 --> 00:17:10,358 그 덩어리를 디렉터리에 저장한 후에, "이게 우리 시스템이야" 241 00:17:11,996 --> 00:17:16,857 동적으로 배포 안 하는데 왜 동적으로 링크하지요? 242 00:17:17,540 --> 00:17:21,675 왜 동적 라이브러리가 생겨났지요? 243 00:17:21,742 --> 00:17:28,603 동적 라이브러리는 동적으로 배포하기 위해서 만들어진 겁니다. 244 00:17:29,093 --> 00:17:30,155 왜지요? 245 00:17:32,571 --> 00:17:35,630 네트워크 속도는 조금 있다 이야기 하겠습니다. 잠시만요. 246 00:17:35,676 --> 00:17:38,946 네트워크 속도로 인한 변화는 이야기할게 아주 많습니다. 247 00:17:38,996 --> 00:17:43,985 90년대에 한 고객이 있었습니다. 실행 파일 크기가 250MB 정도였는데요 248 00:17:43,985 --> 00:17:46,594 그 당시에는 아주 큰 프로그램이었습니다. 지금은 아니지만요. 249 00:17:47,267 --> 00:17:51,733 그 당시 250MB는 아주 큰 용량이었습니다. CD 한 장에 들어가지도 않았지요. 250 00:17:52,250 --> 00:17:57,127 CAD 프로그램이었지요. 포드 같은 회사에 납품했었습니다. 251 00:17:57,127 --> 00:18:01,548 포드는 이 프로그램으로 기어나 레버 등을 디자인했습니다. 252 00:18:02,876 --> 00:18:04,331 그 고객은 이 프로그램을 정적으로 컴파일 했지요. 253 00:18:05,035 --> 00:18:11,207 배포하기 위해 CD 여러장이 필요했습니다. 254 00:18:11,844 --> 00:18:15,109 소스 코드 한 줄이 수정되면 255 00:18:16,782 --> 00:18:26,422 다시 컴파일 하고 링크한 후에 모든 CD를 다시 구워서 고개들에게 전달해야 했습니다. 256 00:18:27,237 --> 00:18:29,756 얼마나 많은 비용이 들었을지 상상이 갈 겁니다. 257 00:18:31,981 --> 00:18:34,189 나는 90년대 중반에 거기에 갔었어요. 258 00:18:34,246 --> 00:18:36,615 그들을 만났습니다. 259 00:18:36,665 --> 00:18:44,005 당시에 그들은 실행파일을 여러 개의 DLL로 쪼개려고 하고 있었는데요. 260 00:18:44,262 --> 00:18:48,902 왜냐하면 여러 개의 DLL로 실행파일을 분리해 놓으면 261 00:18:48,902 --> 00:18:52,166 소스 코드가 한 줄 바뀌었을 때에 262 00:18:52,205 --> 00:18:56,740 관련된 DLL 하나만 배포하면 되기 때문이지요. 263 00:18:57,545 --> 00:19:01,125 이메일로 보낼 수 도 있었습니다. 그 당시에는 그것도 큰 일 이었지요. 264 00:19:01,168 --> 00:19:03,370 그 당시에 이메일로는 250MB 파일을 보낼 수 없었습니다. 265 00:19:03,439 --> 00:19:07,631 요즘에야 어렵지 않지만 266 00:19:07,703 --> 00:19:17,166 당시에는 250MB를 이메일로 보내는 건 불가능했습니다. 하지만 100KB 크기의 DLL을 보내는건 가능했지요. 267 00:19:17,219 --> 00:19:20,058 그 고객에겐 아주 바람직한 것이었습니다. 268 00:19:20,058 --> 00:19:22,188 몇 달을 노력을 해서 269 00:19:22,188 --> 00:19:24,972 어플리케이션을 잘게 쪼개서 270 00:19:25,010 --> 00:19:26,933 여러 개의 DLL로 만들었지요. 271 00:19:27,021 --> 00:19:29,465 그런 후에 치명적인 실수를 깨달았습니다. 272 00:19:30,557 --> 00:19:35,474 치명적인 실수는 시스템을 임의의 DLL들로 쪼개는 것이 273 00:19:35,474 --> 00:19:39,293 아무런 도움이 안 된다는 것 입니다. DLL들이 서로 서로 의존하는 상황이라면요. 274 00:19:40,189 --> 00:19:42,742 DLL들이 서로 의존하고 있는 상황이라면...... 275 00:19:51,828 --> 00:19:56,005 여기 스캇 마이어의 세미나에 들어갔던 사람 있나요? 276 00:19:56,091 --> 00:19:58,434 한 시간 전에 그가 한 연설이요. 277 00:19:58,466 --> 00:20:01,075 열쇠구멍 문제에 대한 이야기였지요. 278 00:20:01,126 --> 00:20:07,846 열쇠구멍 문제라는 것은 아무런 이유 없이 임의로 제약을 주는 것을 이야기합니다. 279 00:20:07,894 --> 00:20:09,813 그냥 임의로 사람들을 구속하는 겁니다. 280 00:20:09,849 --> 00:20:14,522 GUI를 예로 들면 281 00:20:14,572 --> 00:20:16,453 너무 작은 텍스트 박스를 본 적이 있지요? 282 00:20:16,521 --> 00:20:21,868 텍스트 박스에 내용을 많이 적었는데 크기를 조절 할 수 없는 경우 말이에요. 283 00:20:21,868 --> 00:20:25,885 심지어 스크롤도 불가능해서 잘 안 보이는 채로 입력한 적 있지 않나요? 284 00:20:25,930 --> 00:20:29,602 아니면 스크롤은 할 수 있지만 텍스트의 일부분이 가려지는 경우는요? 285 00:20:29,656 --> 00:20:34,728 이게 그가 말한 열쇠구멍 문제입니다. 286 00:20:34,795 --> 00:20:38,273 그런데 여기에서도 그런 문제가 있어요. 287 00:20:39,093 --> 00:20:43,362 "나는 항상 키보드로 작업을 해야 합니다. 5분이상 손을 떼고 있으면 안 되요." 288 00:20:43,412 --> 00:20:48,041 "너무 오래 손을 떼고 있으면 벌을 받게 되요." 289 00:20:52,043 --> 00:20:54,513 무슨 이야기를 하고 있었지요? 아 DLL. 290 00:20:54,513 --> 00:20:58,225 그래서 그 사람은 모든 DLL을 한 군데에 모았습니다. 291 00:20:58,276 --> 00:21:00,500 그런데 DLL들이 서로 서로 의존하고 있다는 것을 잊고 있었어요. 292 00:21:00,534 --> 00:21:04,391 원래 목표는 소스 코드 한 줄을 수정하면 293 00:21:04,423 --> 00:21:07,752 관련된 DLL 하나 만 배포하는 것 있었지요. 294 00:21:07,821 --> 00:21:12,386 '#includes.' C++ 개발자들은 내가 무슨 이야기하는지 알 겁니다. 295 00:21:12,450 --> 00:21:15,307 그런데 모든 '#includes' 들이 끔찍하게 얽혀있다는 것을 깨닫게 되었습니다. 296 00:21:15,358 --> 00:21:18,146 모두 다시 컴파일하고 다 같이 배포해야만 했던 거지요. 297 00:21:18,218 --> 00:21:19,680 결국 그들의 사업을 망했습니다. 298 00:21:22,666 --> 00:21:27,814 오늘 강연의 주제는 299 00:21:29,349 --> 00:21:31,336 컴포넌트에 대한 것 입니다. 300 00:21:31,381 --> 00:21:33,408 컴포넌트 레벨의 디자인 문제들 이지요. 301 00:21:33,480 --> 00:21:36,167 가장 먼저 해야 할 것은 '컴포넌트'에 대한 정의입니다. 302 00:21:36,213 --> 00:21:38,665 컴포넌트는 무엇인가요? DLL입니다. 303 00:21:39,475 --> 00:21:42,531 이제부터 말하는 컴포넌트는 DLL을 이야기하는 겁니다. 304 00:21:42,565 --> 00:21:47,002 특정한 종류의 DLL 입니다. 동적으로 배포가 가능한 DLL이요. 305 00:21:49,185 --> 00:21:52,573 동적으로 배포 가능한 DLL. 306 00:21:53,473 --> 00:21:55,929 왜 동적으로 배포해야 할까요? 307 00:21:56,816 --> 00:21:59,877 그건 소스 코드 한 줄이 변경되었을 때에 308 00:21:59,926 --> 00:22:03,113 다른 DLL은 그대로 두고 변경된 DLL 한 개만 배포하려고 이겠지요. 309 00:22:03,163 --> 00:22:05,399 'DLL 지옥'이 어떤 뜻이지요? 310 00:22:05,448 --> 00:22:09,273 Microsoft에서 자기들의 문제를 표현하기 위해 311 00:22:10,135 --> 00:22:12,442 정의한 용어입니다. 312 00:22:12,509 --> 00:22:17,506 그리고 닷넷이 나오면서 해결됐어야 했지요. 313 00:22:17,540 --> 00:22:22,185 그 문구 기억하나요? "닷넷이 DLL 지옥을 치료합니다." 314 00:22:22,185 --> 00:22:27,531 하하하! 치료하지 못했지요. 315 00:22:27,541 --> 00:22:32,285 DLL 지옥이란 수많은 컴포넌트들이 각각 다른 버전을 가지고 있을 때에 316 00:22:32,285 --> 00:22:35,084 서로 맞는 짝이 어떤 것인지 모르는 상태를 이야기합니다. 317 00:22:35,150 --> 00:22:38,669 그래서 Maven 같은 툴이 나왔지요. 318 00:22:38,742 --> 00:22:40,642 닷넷에는 어떤 툴을 사용하나요? 319 00:22:41,176 --> 00:22:45,925 여러 버전들의 DLL들을 관리해주는 툴 말입니다. 320 00:22:45,974 --> 00:22:50,143 이 DLL의 버전 1과 저 DLL의 버전 3을 같이 다운받을 수 있게 하는 툴이요. 321 00:22:50,176 --> 00:22:52,714 그런 툴이 있나요? 322 00:22:53,961 --> 00:22:54,957 너겟 이요? (역주: NuGet과 음식 너겟(Nugget)의 발음이 유사함) 323 00:22:54,957 --> 00:22:56,854 부드럽고 맛있는 치킨 너겟이요? 324 00:22:58,944 --> 00:23:00,720 됐습니다. 325 00:23:09,766 --> 00:23:17,987 화면의 저 그래프는 x의 제곱 그래프입니다. 326 00:23:18,477 --> 00:23:20,371 그냥 x의 제곱 그래프에요. 327 00:23:21,242 --> 00:23:23,102 하지만 다른 의미도 있습니다. 328 00:23:23,134 --> 00:23:29,186 저 Y 축은 시스템의 모듈 개수 입니다. 329 00:23:29,276 --> 00:23:33,748 모듈의 수에 따라서 가능한 의존 관계의 최대 개수입니다. 330 00:23:33,798 --> 00:23:38,206 모듈 개수가 선형적으로 증가할 때에 331 00:23:38,256 --> 00:23:40,969 의존 관계는 제곱에 비례해서 증가합니다. 332 00:23:44,473 --> 00:23:48,699 이론적으로 연관 관계의 최대 개수는 333 00:23:50,586 --> 00:23:54,750 모듈 수의 제곱에 비례합니다. 334 00:23:54,786 --> 00:24:01,275 물론 시스템의 모듈들이 서로 마구 마구 의존하게 만들지는 않을 겁니다. 335 00:24:02,578 --> 00:24:03,733 설마 그러고 있나요? 336 00:24:06,355 --> 00:24:08,209 그래프를 봅시다. 337 00:24:09,181 --> 00:24:19,898 모듈의 수에 따른 팀의 생산성을 보여주는 그래프입니다. 338 00:24:19,898 --> 00:24:24,953 그나저나 이건 그냥 x의 마이너스 제곱 그래프입니다. 339 00:24:25,389 --> 00:24:28,168 실제 데이터를 수집해서 만든 게 아닙니다. 340 00:24:28,935 --> 00:24:34,197 그간 겪어온 다양한 사례들을 생각하면서 임의로 만들어 본겁니다. 341 00:24:34,197 --> 00:24:38,003 시간이 지나면서 점점 개발 속도가 느려졌던 개발팀들을 생각하면서 말입니다. 342 00:24:38,035 --> 00:24:39,495 혹시 경험해본 적 있나요? 343 00:24:39,532 --> 00:24:42,367 초기에는 아주 빠른 속도로 개발을 하지요. 세상을 정복할 기세로 말입니다. 344 00:24:42,416 --> 00:24:45,923 하지만 1년 지난 후에는 늪지대를 지나는 것처럼 느려져 있지요. 345 00:24:46,366 --> 00:24:48,664 왜 느려졌는지도 몰라요. 346 00:24:48,721 --> 00:24:52,936 예전에는 1주일이면 가능했던 일이 이제 석 달은 필요합니다. 347 00:24:53,378 --> 00:24:58,136 그런데 막상 작업하면 버그가 너무 많이 생겨서 석 달도 부족해져요. 348 00:24:58,212 --> 00:25:04,435 개발 기간이 길어지다보면 나타나는 문제들입니다. 349 00:25:04,480 --> 00:25:09,831 그 원인 중 하나는 의존 관계가 많아지는 것 입니다. 350 00:25:10,571 --> 00:25:11,522 왜 그럴까요? 351 00:25:11,842 --> 00:25:20,778 저건 모듈 끼리 가질 수 있는 의존 관계의 최대치입니다. 352 00:25:20,823 --> 00:25:22,847 이건 최소의 경우이지요. 353 00:25:23,172 --> 00:25:28,910 연관된 모듈들은 서로 의존하기 마련입니다. 354 00:25:28,966 --> 00:25:32,231 트리 형태일 때가 의존도가 제일 적습니다. 355 00:25:32,231 --> 00:25:35,620 동적으로 링크한다면 더 적게 만들 수도 있겠지요. 356 00:25:35,620 --> 00:25:39,531 하지만 보통은 작은 수의 의존 관계를 갖게 됩니다. 357 00:25:39,573 --> 00:25:42,272 의존 관계가 몇 개 있지요? 1. 2. 3. 4. 5. 6. 358 00:25:42,272 --> 00:25:44,587 모듈 7개 중에 6개로군요. 359 00:25:44,627 --> 00:25:46,659 반면에 여기에는 360 00:25:46,659 --> 00:25:50,570 아마도 49의 절반인가 보군요. 361 00:25:50,570 --> 00:25:54,202 아니죠 그럼 너무 숫자가 적겠네요. 362 00:25:54,257 --> 00:25:58,264 그럼 그냥 49개인가요? 모르겠네요. 어쨌든 아주 많습니다. 363 00:25:58,349 --> 00:26:01,067 아마도 몇 인가의 제곱에 비례하겠지요. 364 00:26:01,133 --> 00:26:03,280 어쩌면 0.5 * (n^2 + 1) 일 수도 있겠습니다. 365 00:26:03,362 --> 00:26:04,893 뭐 그런 식이겠지요. 366 00:26:04,923 --> 00:26:07,859 어찌되었건 의존 관계의 수가 아주 많습니다. 367 00:26:07,892 --> 00:26:10,906 우리가 원하는 건 이게 아니라 저 트리 모양입니다. 368 00:26:10,974 --> 00:26:13,134 저렇게 만들기 위해서 노력을 많이 해야 합니다. 369 00:26:13,168 --> 00:26:21,088 그런데 어떤 얼간이가 이렇게 만들어버립니다. 370 00:26:24,111 --> 00:26:26,011 비주얼 스튜디오는 이런 걸 금지합니다. 371 00:26:27,014 --> 00:26:28,507 하지만 비주얼 스튜디오 솔루션 내에서만 해당되지요. 372 00:26:29,029 --> 00:26:34,189 비주얼 스튜디오 솔루션에 속한 프로젝트들은 순환 참조를 할 수가 없습니다. 373 00:26:34,243 --> 00:26:35,019 아주 바람직한 거지요. 374 00:26:35,086 --> 00:26:36,004 순환 참조를 막아주니까요. 375 00:26:36,473 --> 00:26:38,744 하지만 솔루션들 간에는 보장되지 않습니다. 376 00:26:38,778 --> 00:26:40,359 비주얼 스튜디오의 솔루션이 여러 개 있다면요 377 00:26:40,407 --> 00:26:45,270 서로 다른 솔루션에서 빌드된 것들을 링크한다면 여전히 순환 참조가 가능해집니다. 378 00:26:45,304 --> 00:26:50,766 저렇게 순환 참조를 만들면 그냥 의존 관계가 하나 늘어난 것처럼 보이지요. 379 00:26:51,385 --> 00:26:52,776 하지만 그냥 하나만 추가되는 게 아닙니다. 380 00:26:52,817 --> 00:26:57,299 왜냐하면 6번이 2번을 참조합니다. 1번도 2번을 참조하지요. 381 00:26:57,371 --> 00:26:59,139 의존관계는 전이됩니다. 382 00:26:59,230 --> 00:27:04,568 그래서 6번은 4번과 5번을 의존합니다. 그리고 6번은 3번과 7번을 의존하지요. 383 00:27:04,771 --> 00:27:06,851 결국 6번은 모든 모듈에 의존하는 셈입니다. 384 00:27:07,561 --> 00:27:13,921 그래서 순환 참조를 가지는 순간 의존관계의 수는 급격하게 늘어나게 됩니다. 385 00:27:21,943 --> 00:27:23,726 다시 n의 제곱 그래프입니다. 386 00:27:25,092 --> 00:27:28,693 동시에 C++ 컴파에 걸리는 시간의 그래프이기도 하지요. 387 00:27:28,759 --> 00:27:31,253 모듈을 추가함에 따라 388 00:27:31,352 --> 00:27:34,100 정적으로 링크한다면 컴파일 시간과 링킹 시간이 제곱에 비례해서 증가합니다. 389 00:27:34,100 --> 00:27:35,737 하지만 정적으로 링크하지 않는 경우에도 마찬가지입니다. 390 00:27:35,793 --> 00:27:39,881 컴파일 시간은 모듈 수의 제곱에 비례해서 증가합니다. 391 00:27:39,935 --> 00:27:44,671 모든 모듈들이 서로 의존하고 있다면 말입니다. 392 00:27:44,736 --> 00:27:52,241 '#include', import, using 구문들이 순환되게 참조하고 있다면 말입니다. 393 00:27:53,119 --> 00:27:58,560 그렇게 되어 있다면 컴파일 타임이 아주 크게 증가해버립니다. 394 00:27:58,594 --> 00:28:00,859 C++은 특히 더 그렇습니다. 395 00:28:00,949 --> 00:28:02,659 자바와 닷넷은 그렇지 않습니다. 396 00:28:03,917 --> 00:28:06,240 자바와 닷넷의 컴파일 시간은 다른 기준을 가집니다. 397 00:28:06,240 --> 00:28:12,053 C++ 과는 다른 방식으로 소스 코드를 참조합니다. 398 00:28:12,105 --> 00:28:15,349 자바와 닷넷은 선언문을 얻기 위해 바이너리 파일을 읽습니다. 399 00:28:15,385 --> 00:28:18,574 C++은 소스 파일을 읽지요. 400 00:28:18,615 --> 00:28:23,778 그래서 C++에선 순환 참조가 발생하면 대가를 치룹니다. 401 00:28:25,281 --> 00:28:27,059 매우 긴 컴파일 타임으로 말입니다. 402 00:28:27,125 --> 00:28:28,832 아주 심하게요. 403 00:28:28,900 --> 00:28:30,244 제곱에 비례해서 증가합니다. 404 00:28:30,292 --> 00:28:33,036 그래서 모듈이 몇 개 늘어나면 컴파일 타임이 두 배로 증가해버립니다. 405 00:28:33,036 --> 00:28:35,560 그래서 우린 뭔가 조치를 해야만 했습니다. 406 00:28:36,190 --> 00:28:38,804 워드 커닝햄이 누구인지 아는 사람 있나요? 407 00:28:39,549 --> 00:28:40,459 오. 몇 사람 있군요. 408 00:28:40,494 --> 00:28:41,964 좋습니다. 모르는 사람들을 위해서 설명하면 409 00:28:42,014 --> 00:28:43,392 워드 커닝햄은 위키를 개발한 사람입니다. 410 00:28:43,462 --> 00:28:46,579 워드 커닝햄이 위키를 개발했지요. 411 00:28:46,623 --> 00:28:51,552 그리고 캔트 벡을 도와 페어 프로그래밍과 테스트 주도 개발을 발명할 수 있게 했습니다. 412 00:28:51,637 --> 00:28:53,158 그리고 대부분의 애자일 방법들도요. 413 00:28:53,207 --> 00:28:57,016 워드 커닝햄이 누구인지 알아보세요. 아주 흥미로운 친구입니다. 414 00:28:57,049 --> 00:28:58,832 아주 오래 전에 그는 스몰 토크 프로그래머였는데요 415 00:28:58,877 --> 00:29:00,634 언젠가 물어봤습니다. 416 00:29:00,686 --> 00:29:03,304 "워드, 스몰 토크는 왜 사라진 거지?" 417 00:29:03,367 --> 00:29:10,085 그가 말했습니다. "스몰 토크는 너무 쉽게 엉망으로 만들 수 있어서 사라졌어." 418 00:29:10,834 --> 00:29:12,810 "너 같은 C++ 프로그래머들은" 419 00:29:12,846 --> 00:29:14,382 당시에 나는 C++ 프로그래머였습니다. 420 00:29:14,458 --> 00:29:16,678 "C++ 프로그래머들은 운이 좋은 거야." 421 00:29:16,729 --> 00:29:19,467 "네가 엉망으로 만들면 대가를 치루게 되거든." 422 00:29:19,960 --> 00:29:21,830 "스몰토크는 그러지 않았지." 423 00:29:23,425 --> 00:29:26,515 자바나 C#도 그러지 않습니다. 424 00:29:26,965 --> 00:29:28,502 대가를 치루지 않아도 됩니다. 425 00:29:28,570 --> 00:29:30,997 어렵지 않게 엉망으로 만들 수 있습니다. 426 00:29:31,368 --> 00:29:34,879 아주 복잡하게 엉키게 만들어버려도 깨닫지를 못해요. 427 00:29:34,910 --> 00:29:38,958 다행스럼게도 비주얼 스튜디오는 일부나마 순환 참조를 막아주지요. 428 00:29:44,173 --> 00:29:49,045 우리는 nLogN 수준의 생산성을 추구합니다. nLogN 이죠. 429 00:29:49,109 --> 00:29:52,376 n^2 대신에요. 430 00:29:52,776 --> 00:29:59,683 컴포넌트간의 의존관계는 이렇게 생산성에 큰 영향을 미칩니다. 431 00:30:01,753 --> 00:30:06,973 그리고, 1990년대와 2000년 사이에 큰 변화가 생겼습니다. 432 00:30:06,973 --> 00:30:10,136 네트워크 속도가 비약적으로 향상되었지요. 433 00:30:10,635 --> 00:30:15,790 요즘에는 1GB 크기의 파일을 받기는 어렵지 않습니다. 434 00:30:15,870 --> 00:30:17,661 1GB를 10초만에 업로드 할 수도 있지요. 435 00:30:17,726 --> 00:30:19,335 요즘엔 아주 쉬운 일이지만요 436 00:30:19,386 --> 00:30:21,706 예전에는 훨씬 어려웠습니다. 437 00:30:22,031 --> 00:30:28,315 그래서 예전에는 DLL을 하나만 배포하는게 유리하다고 생각했습니다. 438 00:30:28,535 --> 00:30:31,939 요즘에는 그냥 모두 모아서 한 덩어리로 배포하지요. 439 00:30:32,237 --> 00:30:35,835 왜요? 네트워크가 충분히 빨라져서 지요. 그냥 보내면 됩니다. 440 00:30:35,835 --> 00:30:40,311 많은 DLL들을 그냥 하나로 링크된 바이너리처럼 다룰 수 있습니다. 441 00:30:41,661 --> 00:30:43,208 그런데 또 다른 이슈가 있습니다. 442 00:30:44,215 --> 00:30:45,744 여기 팀으로 일하는 사람이 얼마나 있지요? 443 00:30:47,252 --> 00:30:49,511 그렇지요. 모두가 팀으로 일합니다. 444 00:30:50,551 --> 00:30:54,415 아침 8시에 출근을 했다고 생각해봅시다. 445 00:30:55,883 --> 00:30:59,277 디버깅할 프로그램이 있었어요. 446 00:30:59,346 --> 00:31:02,371 제대로 동작하도록 하루 종일 일했습니다. 447 00:31:02,488 --> 00:31:03,728 결국 퇴근 할 때엔 완벽하게 동작하게 만들었지요. 448 00:31:03,766 --> 00:31:04,907 체크인하고 퇴근을 합니다. 449 00:31:04,961 --> 00:31:07,271 그런데 다음 날에 출근해서 보니 동작을 하지 않았습니다. 450 00:31:07,328 --> 00:31:08,086 왜 그럴까요? 451 00:31:09,766 --> 00:31:12,402 누군가 당신보다 더 늦게 퇴근을 한 거지요. 452 00:31:13,452 --> 00:31:15,836 그 사람이 당신이 사용하는 뭔가를 수정한 것 입니다. 453 00:31:16,626 --> 00:31:21,774 그래서 다시 동작하도록 하루 종일 일했습니다. 454 00:31:21,774 --> 00:31:24,409 그리고 다음 날 출근해 보니 또 동작을 안 합니다. 455 00:31:24,523 --> 00:31:26,390 이런 문제가 얼마나 반복 될 수 있을까요? 456 00:31:27,398 --> 00:31:30,942 아주 오랜 기간 가능할 겁니다. 규모가 큰 팀에서는 항상 발생할 수 있는 일입니다. 457 00:31:31,048 --> 00:31:34,662 서로 서로 방해하게 되는 거지요. 458 00:31:34,745 --> 00:31:36,862 물론 이런 문제를 해결할 툴들이 있지요. 459 00:31:36,862 --> 00:31:38,921 소스 코드 관리 시스템이 있고요 460 00:31:38,921 --> 00:31:41,559 그 밖에도 수 많은 좋은 툴들이 있습니다. 461 00:31:41,799 --> 00:31:47,395 그럼에도 불구하고 제대로 관리하지 않으면 이런 문제는 계속 발생합니다. 462 00:31:47,814 --> 00:31:52,414 그럼 프로젝트는 어떻게 관리해야 할까요? 463 00:31:55,951 --> 00:31:57,741 여기에 원칙이 있습니다. 464 00:32:06,670 --> 00:32:10,849 Acyclic Dependencies Principle 이라고 부릅니다. (역주: 비 순환적인 의존관계의 원칙) 465 00:32:13,189 --> 00:32:18,585 이런 뜻 입니다. "컴포넌트를 여러 개 가지고 있다면" 466 00:32:18,618 --> 00:32:22,764 "순환 참조가 없도록 배열해야 한다." 467 00:32:22,849 --> 00:32:25,957 그래야만하는 이유는 여럿 입니다. 이미 하나는 이야기 했지요. 468 00:32:26,023 --> 00:32:30,402 컴파일 시간이요. 또 의존 관계로 의한 부하도 이야기 했지요. 469 00:32:30,402 --> 00:32:31,599 그리고 하나 더 있습니다. 470 00:32:33,727 --> 00:32:38,577 Alarm 모듈의 새로운 버전을 릴리즈하려고 합니다. 471 00:32:38,986 --> 00:32:43,013 Alarm 모듈을 담당하는 팀은 1.0 버전을 릴리즈하려고 작업 중입니다. 472 00:32:43,144 --> 00:32:48,812 Alarm 모듈은 다른 모듈을 사용하지 않습니다. 473 00:32:48,812 --> 00:32:52,349 따라서 자유롭게 릴리즈할 수 있지요. 474 00:32:52,401 --> 00:32:56,011 1.0 버전을 릴리즈하고 475 00:32:56,011 --> 00:32:58,006 1.1 버전 개발을 착수합니다. 476 00:32:58,896 --> 00:33:02,169 그런데 지금 Alarm 1.0 버전이 릴리즈되었니까 477 00:33:02,220 --> 00:33:05,977 Elevator 모듈과 Conveyor 모듈도 릴리즈할 수 있게 되었습니다. 478 00:33:06,916 --> 00:33:12,386 릴리즈 후에 두 모듈도 각각 1.1 버전 개발을 시작합니다. 479 00:33:12,419 --> 00:33:15,740 이제 Transport 모듈도 릴리즈 합니다. 480 00:33:15,776 --> 00:33:17,759 어떻게 돌아가는지 알겠지요? 481 00:33:17,806 --> 00:33:21,079 버전 넘버가 밑에서부터 타고 올라갑니다. 482 00:33:21,148 --> 00:33:27,448 1.0 버전이 밑에서 생성되면. 점 점 위로 전파되어 맨 위에까지 도달합니다. 483 00:33:27,497 --> 00:33:30,021 버전 넘버가 밑에서부터 위로 전파되는 거지요. 484 00:33:30,053 --> 00:33:32,633 자세히 보면 알게 될 겁니다. 485 00:33:32,633 --> 00:33:37,550 버전 넘버가 전파되는 경로는 빌드 순서와 동일합니다. 486 00:33:37,615 --> 00:33:42,422 의존 관계는 빌드 순서를 따라 전파됩니다. 487 00:33:43,318 --> 00:33:50,357 그런데 어떤 얼간이가 이런 짓을 합니다. 488 00:33:50,454 --> 00:33:52,601 누구지요? 489 00:33:52,703 --> 00:33:54,192 나에요. 내가 그랬어요. 490 00:33:54,303 --> 00:33:58,542 난 알람의 서브시스템을 담당하고 있는데 491 00:33:58,542 --> 00:34:02,255 컨트롤 패널 화면에 메시지를 표시해야만 해요. 492 00:34:02,329 --> 00:34:06,963 그런데 마침 컨트롤 패널에는 Display라는 펑션이 있더라고요. 493 00:34:06,963 --> 00:34:10,025 "오. 이걸 호출하면 되겠군." 하면서 사용했습니다. 494 00:34:10,025 --> 00:34:13,315 문제 없이 호출할 수 있었어요. 495 00:34:13,315 --> 00:34:17,092 컴파일 됐고, 동작도 문제 없었습니다. 496 00:34:18,482 --> 00:34:23,495 그런데 다음 날 사람들이 화가나서 내게 찾아왔지요. 497 00:34:23,542 --> 00:34:25,243 "도대체 무슨 짓을 한 거야?" 498 00:34:25,652 --> 00:34:32,592 "그냥 컨트롤 패널의 Display 펑션을 호출 했을 뿐이에요." 499 00:34:32,628 --> 00:34:34,553 "화면에 메시지를 뿌려야만 했거든요." 500 00:34:34,587 --> 00:34:35,763 "그렇게 하면 안되지!" 501 00:34:36,351 --> 00:34:37,908 왜 안되는 걸까요? 502 00:34:39,777 --> 00:34:41,172 우선 503 00:34:43,752 --> 00:34:47,603 저 모듈들은 어떤 순서로 빌드해야 할까요? 504 00:34:49,893 --> 00:34:52,737 원래는 밑에서부터 위로 빌드해야 합니다. 505 00:34:53,853 --> 00:34:55,666 그런데 지금은 밑이 없습니다. 506 00:34:55,717 --> 00:34:58,090 따라서 올바른 빌드 순서가 없습니다. 507 00:34:58,341 --> 00:35:01,242 컴포넌트 그래프에서 순환 관계가 있다면 508 00:35:01,608 --> 00:35:06,485 올바른 빌드 순서를 정할 수 없게 됩니다. 509 00:35:06,524 --> 00:35:11,136 따라서 시스템 동작도 정의할 수 없게 됩니다. 510 00:35:11,676 --> 00:35:14,992 "Undefined"가 무슨 뜻 이지요? "Undefined"의 정의가 무엇 인가요? 511 00:35:16,210 --> 00:35:17,867 정해진 조건에서만 동작한다는 것 입니다. 512 00:35:19,656 --> 00:35:24,308 "Undefined" 인 것은 배포 전에는 잘 동작합니다. 하지만 배포되고 나면 동작하지 않게 되지요. 513 00:35:25,442 --> 00:35:29,006 이런 순환참조가 있으면 시스템은 심각한 오류를 발생할 수 있습니다. 514 00:35:29,043 --> 00:35:30,945 자바에선 흔히 볼 수 있습니다. 515 00:35:31,044 --> 00:35:35,951 순환 참조가 있는 자바 시스템이 있다면...... 516 00:35:35,951 --> 00:35:37,061 빌드는 할 수 있지요. 517 00:35:37,093 --> 00:35:39,021 정확한 빌드 순서가 없더라도 말입니다. 518 00:35:39,129 --> 00:35:41,327 그런데 테스트를 돌리면 실패합니다. 519 00:35:41,540 --> 00:35:44,626 그런데 다른 순서로 빌드를 하면 520 00:35:44,661 --> 00:35:45,804 테스트가 성공하기도 합니다. 521 00:35:45,855 --> 00:35:49,166 테스트가 패스할 때까지 계속 빌드를 하는 회사도 본적이 있습니다. 522 00:35:54,627 --> 00:35:56,380 그런데 더욱 심각한 문제가 있습니다. 523 00:35:56,923 --> 00:36:03,659 Conveyor 모듈을 릴리즈 하려고 합니다. 524 00:36:03,690 --> 00:36:05,879 1.1 버전을 릴리즈 하려고 하지요. 525 00:36:05,911 --> 00:36:11,089 그러러면 Alarm 1.1 버전과 같이 테스트해야 합니다. 526 00:36:11,885 --> 00:36:17,858 하지만 Alarm 1.1 버전은 Control Panel 1.1 버전을 기다리고 있지요. 그리고 Control Panel 1.1 버전은 Transport 1.1 버전을 기다리고 있습니다. 527 00:36:17,904 --> 00:36:21,646 Transport 1.1 버전은 지금 릴리즈 하려는 Conveyor 1.1 버전을 기다리고 있습니다. 528 00:36:21,646 --> 00:36:27,729 그러므로 모든 소스코드를 한군데에 모으기 전에는 릴리즈 할 방법이 없어집니다. 529 00:36:27,818 --> 00:36:31,004 통합작업. 누구 기억하는 사람 있나요? 530 00:36:31,037 --> 00:36:32,305 통합작업의 즐거움이요. 531 00:36:32,354 --> 00:36:37,126 모든 시스템을 통합한 이후에 동작하게 하는 것 이지요. 532 00:36:37,945 --> 00:36:41,044 그러는 동안에는 모듈끼리 서로서로 얽히게 되지요. 533 00:36:41,354 --> 00:36:49,582 결국 아침에 출근했더니 코드가 동작하지 않는 문제가 다시 발생하게 됩니다. 534 00:36:50,164 --> 00:36:52,095 그런데 더 큰 문제가 있습니다. 535 00:36:52,717 --> 00:36:58,439 Conveyor를 테스트하려면 Alarm이 필요한데요 536 00:36:58,472 --> 00:37:02,409 Alarm은 Control Panel이 필요하고, Control Panel은 Revenue가 필요하고, Revenue는 데이터베이스가 필요합니다. 537 00:37:02,499 --> 00:37:06,248 그리고 데이터베이스는 45분이나 걸려서 로딩했더니 테스트하자마자 죽어버립니다. 538 00:37:06,528 --> 00:37:08,966 도저히 테스트를 실행할 수가 없어요. 539 00:37:09,026 --> 00:37:13,999 Conveyor 모듈 담당자들은 이야기 합니다. "대체 우리 모듈이 데이터베이스가 왜 필요한 거야!?" 540 00:37:14,150 --> 00:37:17,344 "음, 의존관계가 이상하게 꼬여서 데이터베이스가 필요한 거야." 541 00:37:17,504 --> 00:37:21,891 프로그램을 실행하고 로딩된 DLL 목록을 보면서 이상하게 여긴 사람 없나요? 542 00:37:21,891 --> 00:37:23,811 "내가 왜 이런 것들을 사용하지?" 543 00:37:23,849 --> 00:37:26,895 C++ 개발자 중에 링크 목록을 보고 놀랐던 사람 없나요? 544 00:37:26,999 --> 00:37:28,962 "왜 이런 것들이 링크 목록에 포함되어있는거야?" 545 00:37:29,005 --> 00:37:30,530 "내가 왜 이런 것들을 사용하는 거지?" 546 00:37:30,564 --> 00:37:32,993 순환 참조를 가지고 있기 때문입니다. 547 00:37:33,026 --> 00:37:34,532 그래서 잡스러운 것들이 이것 저것 끌려오는 거지요. 548 00:37:34,599 --> 00:37:42,656 그해서 첫 번째 원칙은 컴포넌트간에 순환 참조가 없어야 한다는 것 입니다. 549 00:37:42,695 --> 00:37:45,059 그럼 어떻게 해결할 수 있을까요? 550 00:37:45,835 --> 00:37:51,747 밑에 있는 모듈이 저 위에 있는 모듈의 펑션을 호출하려면요? 551 00:37:51,747 --> 00:37:53,107 어떻게 하겠습니까? 552 00:37:55,377 --> 00:37:57,370 음...... 컴포넌트를 하나 추가해도 되겠지요. 553 00:37:58,446 --> 00:37:59,868 가능한 방법 중 하나입니다. 554 00:37:59,939 --> 00:38:03,339 Control Panel 컴포넌트에서 클래스를 하나 떼어내서 555 00:38:03,373 --> 00:38:05,327 Display 컴포넌트에 추가합니다. 556 00:38:05,327 --> 00:38:07,961 Alarm 컴포넌트는 Display 컴포넌트를 호출할 수 있어요. 557 00:38:07,961 --> 00:38:10,255 Control Panel 컴포넌트도 Display 컴포넌트를 호출할 수 있습니다. 558 00:38:10,516 --> 00:38:12,199 이렇게 하면 순환 관계를 깰 수 있지요. 559 00:38:12,263 --> 00:38:14,242 일반적인 방법입니다. 560 00:38:14,287 --> 00:38:16,061 이 모든 컴포넌트들은 DLL이었지요? 561 00:38:16,114 --> 00:38:23,034 따라서 순환 관계를 추가되면 결국 DLL 수가 늘어나게 됩니다. 562 00:38:23,086 --> 00:38:24,603 아마도요. 563 00:38:25,019 --> 00:38:28,364 또 다른 해결 방법이 있습니다. 564 00:38:30,440 --> 00:38:33,076 Dependency Inversion을 사용하는 것이지요. 565 00:38:33,124 --> 00:38:40,010 인터페이스를 하나 만듭니다. Display 인터페이스요. 566 00:38:40,064 --> 00:38:42,278 Alarm 서브시스템에 추가합니다. 567 00:38:42,330 --> 00:38:44,778 그리고 Control Panel이 Display 인터페이스를 구현하게 합니다. 568 00:38:45,764 --> 00:38:48,321 그러면 의존 관계가 뒤집히게 됩니다. 569 00:38:49,643 --> 00:38:52,663 그리고 순환 관계도 선형으로 바뀝니다. 570 00:38:59,790 --> 00:39:01,324 객체지향은 무엇인가요? 571 00:39:04,009 --> 00:39:06,269 객체지향 프로그래밍이 무엇인가요? 572 00:39:08,802 --> 00:39:10,474 우리가 왜 좋아할까요? 573 00:39:10,538 --> 00:39:14,936 어쩌다 모든 프로그래밍 언어가 객체지향이 되었을까요? 574 00:39:14,936 --> 00:39:16,884 벌써 30년동안 사용하고 있습니다. 어떤 것인지는 알아야겠지요. 575 00:39:16,952 --> 00:39:18,560 (청중) 현실 세계를 모델링 할 수 있습니다. 576 00:39:18,560 --> 00:39:20,193 현실 세계를 모델링 할 수 있다. 감사합니다. 577 00:39:20,193 --> 00:39:22,727 내가 이렇게 답하라고 저 사람을 여러분 사이에 심어놨습니다. 578 00:39:22,727 --> 00:39:24,924 내가 저사람의 답변을 발기 발기 찢어버리려고요. 579 00:39:24,974 --> 00:39:26,852 아닙니다. 아주 터무니없는 이야기에요. 580 00:39:26,852 --> 00:39:31,641 객체지향이 실 세계를 모델 하기에 더 좋다는 생각은 말도 안됩니다. 581 00:39:31,712 --> 00:39:35,366 그건 오래 전에 어떤 사람이 꾸며낸 이야기입니다. 582 00:39:35,450 --> 00:39:39,479 관리자를 설득해서 1만2천 달러짜리 C++ 컴파일러를 사게 하려고요. 583 00:39:39,512 --> 00:39:42,092 그 것 말고는 관리자를 설득할 방법을 못 찾았기 때문에요. 584 00:39:42,144 --> 00:39:46,391 1만2천 달러. 초기 C++ 컴파일러는 매우 비쌌습니다. 585 00:39:46,391 --> 00:39:48,092 "1만2천 달러! 그 돈 주고 컴파일러를 사지는 않겠네." 586 00:39:48,092 --> 00:39:49,961 "하지만 그게 있으면 현실 세계를 더 잘 반영할 수 있습니다." 587 00:39:49,961 --> 00:39:53,086 "아! 그렇다면야......" 588 00:39:53,125 --> 00:39:57,739 실세계를 더 잘 반영한다는 것은 완전히 어리석은 생각입니다. 589 00:39:57,771 --> 00:40:04,560 객체지향이란게 그냥 데이터와 펑션들이 같이 모여있다는 것 이외에 뭐가 다를 게 있겠어요? 590 00:40:04,560 --> 00:40:06,822 캡슐화요. 좋습니다. 캡슐화. 591 00:40:06,822 --> 00:40:09,407 하지만 펑션들이 데이터 구조체를 가진다는 점은 592 00:40:09,407 --> 00:40:11,590 객체지향이 아닌 언어와 다를 게 있나요? 593 00:40:13,393 --> 00:40:15,497 쉽게 답하기는 어렵지요. 594 00:40:16,282 --> 00:40:18,067 어떻게 다를까요? 595 00:40:18,129 --> 00:40:21,940 네. 데이터 구조체를 펑션과 같이 넣어서 사용하고 있지요. 596 00:40:21,994 --> 00:40:23,659 하지만 항상 그래왔습니다. 597 00:40:24,161 --> 00:40:26,806 예전의 C 프로그래머도 항상 그래왔습니다. 598 00:40:27,058 --> 00:40:29,959 데이터 구조체도 항상 같이 있었죠. 599 00:40:29,959 --> 00:40:33,588 아주 유명한 책이 있었지요. "Algorithms plus data structures equals programs" 600 00:40:34,290 --> 00:40:36,530 데이터 구조와 펑션이 같이 동작합니다. 601 00:40:36,583 --> 00:40:39,288 객체지향에 특별할 것은 없습니다. 602 00:40:39,288 --> 00:40:43,754 하지만 객체지향으로 인해 가능해진 게 하나 있긴 합니다. 603 00:40:43,754 --> 00:40:45,537 예전에는 위험해서 잘 안 썼지요. 604 00:40:45,597 --> 00:40:47,267 다형성입니다. 605 00:40:47,304 --> 00:40:50,987 아주 사용하기 쉬운 다형성이지요. 606 00:40:51,024 --> 00:40:53,266 C에도 있긴 했습니다. 607 00:40:53,924 --> 00:40:57,898 하드웨어에 독립적인 모든 OS는 다형성의 예입니다. 608 00:40:57,947 --> 00:41:02,791 어떤 디바이스를 사용할지 모르고 프로그램을 작성할 수 있다면 609 00:41:02,862 --> 00:41:04,842 분명히 다형적인 특징을 사용하고 있는 것 입니다. 610 00:41:05,568 --> 00:41:08,694 하지만 대부분의 언어에서는 위험합니다. 611 00:41:08,762 --> 00:41:10,472 적어도 예전에는 그랬습니다. 612 00:41:10,472 --> 00:41:12,262 왜냐하면 펑션 포인터들을 만지작거려야 하거든요. 613 00:41:12,262 --> 00:41:13,533 항상 위험한 작업이었지요. 614 00:41:14,638 --> 00:41:18,563 객체지향의 도입으로 아주 편리하게 구현할 수 있게 되었습니다. 615 00:41:18,639 --> 00:41:20,773 특별히 다형성을 생각하지 않아도 됩니다. 616 00:41:20,773 --> 00:41:23,674 자바 같은 경우에는 모든 메소드가 다형적입니다. 617 00:41:23,674 --> 00:41:25,108 선택의 여지가 없지요. 618 00:41:25,175 --> 00:41:29,289 C#은 선택할 수 있습니다. virtual 키워드를 사용하면 되지요. 619 00:41:29,322 --> 00:41:35,234 C++ 프로그래머도 선택할 수 있지요. virtual 키워드를 사용하면 됩니다. 소멸자에는 반드시 써야 하지요. 620 00:41:35,871 --> 00:41:38,933 하지만 대부분 별로 신경을 쓰지 않아도 됩니다. 621 00:41:38,933 --> 00:41:42,007 모든 펑션들이 다형적이에요. 특별히 신경 쓰지 않아도 됩니다. 622 00:41:42,055 --> 00:41:42,936 왜 그럴까요? 623 00:41:44,166 --> 00:41:49,384 펑션이 다형적 특징을 가지고 있다면 뭔가 근사한 일이 생깁니다. 624 00:41:49,964 --> 00:41:55,192 컨트롤 흐름은 상위 클래스에서 하위 클래스로 향합니다. 625 00:41:55,242 --> 00:41:59,150 하지만 소스코드의 의존관계는 반대로 하위 클래스에서 상위 클래스로 향합니다. 626 00:41:59,828 --> 00:42:07,917 런타임 의존관계를 변경하지 않고도 소스코드의 의존관계를 뒤집을 수 있습니다. 627 00:42:07,917 --> 00:42:10,110 DLL을 어떻게 만들지요? 628 00:42:10,110 --> 00:42:11,872 컴포넌트는 어떻게 만드나요? 629 00:42:11,872 --> 00:42:13,614 다른 것들과 분리시켜서 만듭니다. 630 00:42:13,614 --> 00:42:16,954 하지만 런타임 의존관계는 유지해야 합니다. 631 00:42:21,441 --> 00:42:22,710 비주얼스튜디오 쓰는 사람들 632 00:42:24,865 --> 00:42:27,552 ReSharper 사용하나요? 633 00:42:28,532 --> 00:42:30,060 ReSharper 사용하는 사람? 634 00:42:30,091 --> 00:42:31,576 보세요. 모두가 사용합니다. 635 00:42:32,816 --> 00:42:35,606 비주얼스튜디오가 ReSharper에 대해서 아나요? 636 00:42:38,009 --> 00:42:38,645 아닙니다. 637 00:42:38,718 --> 00:42:42,338 비주얼스튜디오가 ReSharper를 호출하나요? 638 00:42:43,465 --> 00:42:44,725 그렇지요. 639 00:42:44,790 --> 00:42:49,106 컨트롤 흐름은 비주얼 스튜디오에서 Resharper로 향합니다. 640 00:42:49,106 --> 00:42:54,477 비주얼 스튜디오는 필요한대로 ReSharper의 펑션을 호출합니다. 641 00:42:54,477 --> 00:43:00,686 하지만 비주얼스튜디오 소스 코드는 ReSharper의 소스 코드에 의존하지 않지요. 642 00:43:00,686 --> 00:43:03,086 왜냐하면 의존 관계의 방향이 뒤집어졌기 때문이지요. 643 00:43:04,025 --> 00:43:09,912 어플리케이션이 어떤 걸 호출할지 모르는 상태에서도 644 00:43:09,945 --> 00:43:12,495 호출될 DLL들을 만들 수 있습니다. 645 00:43:12,527 --> 00:43:15,585 의존 관계를 뒤집어서 말입니다. 646 00:43:15,864 --> 00:43:17,072 의존 관계가 역전되는 거지요. 647 00:43:17,156 --> 00:43:19,280 이 것도 순환 참조를 해결하는 좋은 방법입니다. 648 00:43:19,652 --> 00:43:28,943 그럼 Control Panel은 Alarm 시스템에 플러그인이 됩니다. 649 00:43:29,025 --> 00:43:31,590 Alarm 시스템은 Control Panel에 대해서 모릅니다. 650 00:43:31,590 --> 00:43:35,765 Control Panel 은 플러그인이에요. 651 00:43:35,813 --> 00:43:38,609 Alarm 시스템은 어떤 플러그인이라도 사용할 수 있습니다. 652 00:43:38,609 --> 00:43:42,568 어떤 것이든지 이 Display 펑션을 구현할 수 있습니다. 653 00:43:42,568 --> 00:43:45,262 그러면 아주 많은 것들에 알람을 적용할 수 있는 거지요. 654 00:43:52,942 --> 00:43:55,184 어떤 것에 의존하겠습니까? 655 00:44:01,501 --> 00:44:04,620 안정적인 컴포넌트를 의존하겠습니까? 656 00:44:07,014 --> 00:44:08,996 아니면 불안정한 컴포넌트요? 657 00:44:10,785 --> 00:44:12,145 뻔한 질문입니다. 658 00:44:12,195 --> 00:44:17,812 누구나 안정적인 것을 의존하고 싶어합니다. 659 00:44:22,582 --> 00:44:25,278 그러면 안정적이라는 단어를 정의해봅시다. 660 00:44:28,542 --> 00:44:30,590 내 레이저 포인터는 안정적인가요? 661 00:44:34,332 --> 00:44:36,273 이건 변하지는 않지요. 662 00:44:38,883 --> 00:44:40,569 하지만 안정적인가요? 663 00:44:40,614 --> 00:44:43,667 안정성은 그렇다 아니다로 표현할 수가 없습니다. 664 00:44:43,732 --> 00:44:46,330 안정성은 지속적인 특징을 가집니다. 665 00:44:46,379 --> 00:44:50,612 그리고 변화 시키는 데에 필요한 일의 양으로 정의되지요. 666 00:44:50,657 --> 00:44:53,396 힘이 많이 필요하면 안정적인 것 입니다. 667 00:44:53,433 --> 00:44:56,250 조금의 힘으로도 변화시킬 수 있다면 불안정적인 것이지요. 668 00:44:56,301 --> 00:45:00,212 저건 불안정적 입니다. 669 00:45:00,283 --> 00:45:03,767 조금만 힘을 써도 상태를 변경시킬 수 있거든요. 670 00:45:03,825 --> 00:45:08,630 이건 안정적이라고 말하진 않겠습니다. 671 00:45:08,736 --> 00:45:11,505 뒤집는데 힘이 많이 들지 않겠거든요. 672 00:45:11,542 --> 00:45:14,952 그리고 여기 강단은 그다지 안정적이지 않은 것 같아요. 673 00:45:15,780 --> 00:45:18,945 조심해서 움직여야겠네요. 674 00:45:18,976 --> 00:45:21,597 다시 질문해보겠습니다. 675 00:45:21,632 --> 00:45:24,712 어떤 것을 의존하겠습니까? 676 00:45:24,766 --> 00:45:26,956 쉽게 변경되는 것에 의존하겠어요? 677 00:45:26,997 --> 00:45:28,735 아니면 잘 변경되지 않는 것에요? 678 00:45:28,774 --> 00:45:33,115 소스코드를 수정하는 경우라면 요? 679 00:45:33,725 --> 00:45:35,199 어떤 것에 의존 하겠습니까? 680 00:45:35,199 --> 00:45:39,812 소스 코드 변경하기 어려운 모듈에 의존할까요? 아니면 소스 코드를 변겨하기 쉬운 모듈에요? 681 00:45:42,290 --> 00:45:43,366 같은 답변입니다. 682 00:45:43,439 --> 00:45:45,699 변경하기 어려운 것에 의존해야 합니다. 683 00:45:45,731 --> 00:45:48,997 이유는 아주 간단합니다. 684 00:45:48,997 --> 00:45:51,956 문자열 클래스를 사용하기 꺼려지나요? 685 00:45:51,988 --> 00:45:52,725 아닙니다. 686 00:45:52,725 --> 00:45:54,946 왜지요? 687 00:45:54,946 --> 00:45:58,409 만약에 누군가가 문자열 클래스를 변경한다면 큰 대가를 지불할 겁니다. 688 00:45:59,679 --> 00:46:01,405 문자열 클래스를 사용하는 여러분 보다 훨씬 더 괴로울 거에요. 689 00:46:01,619 --> 00:46:04,157 그게 우리가 이야기하는 방정식입니다. 690 00:46:04,157 --> 00:46:06,488 어떤 모듈을 사용하는 조건은 다음과 같습니다. 691 00:46:06,528 --> 00:46:11,525 그 모듈이 변경됐을 경우 나보다 그 모듈의 개발자가 할 일이 더 많으면 사용합니다. 692 00:46:11,564 --> 00:46:13,814 그게 적절한 조건이에요. 693 00:46:13,854 --> 00:46:15,598 그런 경우엔 안심하고 사용할 수 있습니다. 694 00:46:15,598 --> 00:46:19,202 그 모듈이 잘 변경되지 않을 것 같거나 변경되더라도 그걸 변경한 나쁜 자식이 합당한 대가를 치루게 되는 경우 말입니다. 695 00:46:19,202 --> 00:46:25,356 그렇습니다. 우린 손쉽게 변경되는 것에 의존하지 않으려고 합니다. 696 00:46:27,384 --> 00:46:28,906 잘 생각해보세요. 697 00:46:28,906 --> 00:46:32,846 쉽게 변경되는 것에는 의존하지 않습니다. 698 00:46:34,594 --> 00:46:40,272 시스템을 설계할 때에 쉽게 변경할 수 있게 만드는 곳이 있나요? 699 00:46:42,648 --> 00:46:43,785 있습니다. 700 00:46:44,137 --> 00:46:49,977 시스템 중 어떤 부분이 가장 쉽게 변경될 수 있어야 하지요? 701 00:46:53,137 --> 00:46:54,321 GUI입니다. 702 00:46:56,888 --> 00:46:58,286 GUI는 쉽게 변합니다. 703 00:46:58,286 --> 00:47:01,589 특별한 이유 없이 바뀌기도 합니다. 704 00:47:01,622 --> 00:47:05,068 사람들은 그냥 느낌 만으로도 GUI를 변경하기도 하지요. 705 00:47:05,105 --> 00:47:07,851 제품 위원회에서 이야기합니다. 706 00:47:07,851 --> 00:47:09,743 "이봐, 우리 시스템은 좀 오래되 보여" 707 00:47:09,780 --> 00:47:11,500 그게 무슨 말인가요? 708 00:47:11,500 --> 00:47:14,542 "우리 시스템은 좀 오래되 보여. 디자인을 바꿔야겠어." 709 00:47:14,902 --> 00:47:19,376 "마케팅 팀에서 결정 났어. 완전 새로운 Look & Feel을 입히자고." 710 00:47:19,410 --> 00:47:21,035 "동작을 변경할 필요는 없고" 711 00:47:21,090 --> 00:47:22,895 "GUI의 Look & Feel 만 변경하는 거야." 712 00:47:22,927 --> 00:47:25,044 GUI는 쉽게 바꿀 수 있어야 합니다. 713 00:47:25,044 --> 00:47:28,509 GUI 모듈의 소스 코드는 쉽게 변경할 수 있어야 합니다. 714 00:47:28,549 --> 00:47:33,005 그 건 다른 모듈이 GUI 모듈에 의존하면 안 된다는 말이지요. 715 00:47:33,627 --> 00:47:36,668 어떤 모듈의 소스 코드도 GUI 모듈을 참조해선 안됩니다. 716 00:47:37,533 --> 00:47:41,976 GUI 모듈을 향하는 의존 관계가 없어야 합니다. 717 00:47:42,029 --> 00:47:45,183 GUI 컴포넌트가 어플리케이션의 다른 모듈들을 의존해야 합니다. 718 00:47:45,226 --> 00:47:48,528 다른 컴포넌트들은 GUI 컴포넌트에 의존하면 안됩니다. 719 00:47:49,110 --> 00:47:53,207 그렇지 않으면 결국 시스템의 GUI는 수정하기 어렵게 될 겁니다. 720 00:47:53,254 --> 00:47:56,567 시스템을 테스트하는 사람이 얼마나 되나요? 721 00:47:56,617 --> 00:47:57,882 자동화된 테스트요. 722 00:47:58,844 --> 00:47:59,910 GUI를 통해서요. 723 00:48:02,644 --> 00:48:03,858 두어 사람 있군요. 724 00:48:04,807 --> 00:48:06,618 GUI를 통해서 테스트를 한다고요. 725 00:48:07,383 --> 00:48:11,009 그렇다면 쉽게 변해야 하는 것에 의존하고 있는 것 입니다. 726 00:48:11,058 --> 00:48:13,231 그러면 결국 GUI 변경하기 어렵게 만들 겁니다. 727 00:48:13,296 --> 00:48:15,598 GUI를 통해서 시스템을 테스트를 한다면요. 728 00:48:15,667 --> 00:48:19,399 15,000개의 테스트를 GUI를 통해서 수행하는 고객이 있었습니다. 729 00:48:19,432 --> 00:48:20,850 앞에서 이야기한 그 고객입니다. 730 00:48:20,934 --> 00:48:22,070 그 망한 고객이요. 731 00:48:22,102 --> 00:48:25,786 GUI 기반의 15,000개의 테스트요. 732 00:48:25,838 --> 00:48:29,291 테스트가 너무 많아서 어떤 테스트인지도 모르고 있었지요. 733 00:48:29,324 --> 00:48:30,828 그냥 모두 패스해야 한다는 것만 알았지요. 734 00:48:30,863 --> 00:48:32,783 누군가 GUI를 변경한다면요 735 00:48:32,819 --> 00:48:35,233 테스트 케이스 중 1000개는 실패하겠지요. 736 00:48:35,283 --> 00:48:37,060 너무 많아서 수정하기도 힘들었겠지요. 737 00:48:37,108 --> 00:48:39,223 그래서 아주 간단한 규칙을 생각해냈습니다. 738 00:48:39,265 --> 00:48:40,797 무엇이었을까요? 739 00:48:40,851 --> 00:48:43,575 GUI는 변경하지 않는다! 740 00:48:43,611 --> 00:48:47,117 그들은 GUI를 변경하기 어렵게 만들었어요. 741 00:48:47,532 --> 00:48:51,696 테스트 케이스를 못쓰게 되는 경우도 있었겠지요. 742 00:48:52,566 --> 00:48:58,428 12 M/M를 투자해서 GUI를 통한 테스트 수트를 만들었다고 합시다. 743 00:48:58,468 --> 00:49:01,944 그런데 누군가 결정했어요. "GUI 디자인을 변경해야겠어." 744 00:49:01,984 --> 00:49:04,359 "기존 GUI를 걷어내고 새로운 GUI를 개발합시다." 745 00:49:04,404 --> 00:49:05,969 테스트들은 쓸모가 없어집니다. 746 00:49:06,000 --> 00:49:09,706 테스트 케이스를 다시 작성해야 합니다. 하지만 테스트할 시스템이 그 것만 있는 게 아니지요. 747 00:49:09,748 --> 00:49:11,771 GUI는 테스트하지 마세요. 748 00:49:11,809 --> 00:49:13,777 GUI를 통해서는 아무것도 하지 마세요. 749 00:49:13,777 --> 00:49:19,387 어떤 의존 관계도 GUI를 향해선 안됩니다. 750 00:49:19,450 --> 00:49:22,799 쉽게 변경하고 싶어하는 게 또 뭐가 있을까요? 751 00:49:22,881 --> 00:49:26,047 데이터베이스요. 752 00:49:26,047 --> 00:49:28,340 데이터베이스도 쉽게 변경하고 싶어하지요. 753 00:49:28,340 --> 00:49:32,347 어플리케이션을 엎어버리지 않고 데이터베이스를 변경 할 수 있기를 원합니다. 754 00:49:33,814 --> 00:49:37,646 어떤 의존 관계도 데이터베이스로 향하면 안되겠지요. 755 00:49:37,646 --> 00:49:40,613 아무 것도 데이터베이스를 의존하지 않게 해야 합니다. 756 00:49:40,681 --> 00:49:44,228 아무 것도 GUI를 의존하지 않게 해야 합니다. 757 00:49:46,310 --> 00:49:54,150 불안정적인 것은 의존하면 안됩니다. 758 00:49:54,701 --> 00:49:58,444 불안정성은 어떻게 측정 할 수 있을까요? 759 00:50:02,013 --> 00:50:03,818 저기 보이나요? 760 00:50:04,997 --> 00:50:06,322 저기 위에 있는 컴포넌트요. 761 00:50:06,750 --> 00:50:08,926 저건 안정적인가요? 아니면 불안정적인가요? 762 00:50:09,001 --> 00:50:13,261 많은 모듈들이 의존하고 있지요. 763 00:50:13,329 --> 00:50:15,624 자기가 의존하는 것은 없습니다. 764 00:50:15,687 --> 00:50:17,099 따라서 변경하기 어렵지요. 765 00:50:17,152 --> 00:50:20,353 변경을 하게 되면 다른 모듈들에도 영향을 미칩니다. 766 00:50:20,404 --> 00:50:24,940 따라서 저 컴포넌트는 다른 모듈들에 책임을 지게 되는 거지요. 767 00:50:25,010 --> 00:50:28,996 음 이 컴포넌트는 독립적이군요. 768 00:50:29,077 --> 00:50:30,892 다른 모듈을 의존하지는 않습니다. 769 00:50:30,892 --> 00:50:32,803 책임감있고 독립적입니다. 770 00:50:32,803 --> 00:50:33,852 마치 어른 처럼요. 771 00:50:36,724 --> 00:50:39,079 안정적이고 어른과 같습니다. 772 00:50:40,048 --> 00:50:41,089 저기 아래 컴포넌트를 보세요. 773 00:50:41,619 --> 00:50:44,444 많은 모듈들을 이용하고 있네요. 774 00:50:44,953 --> 00:50:46,787 저 컴포넌트를 이용하는 모듈은 없어요. 775 00:50:46,840 --> 00:50:48,367 책임질 필요가 없겠지요? 776 00:50:48,434 --> 00:50:49,643 그리고 의존적입니다. 777 00:50:49,682 --> 00:50:51,274 청소년과 같습니다. 778 00:50:52,014 --> 00:50:53,581 그리고 안정적이지 않습니다. 779 00:50:54,058 --> 00:50:57,624 서로 완전히 반대되는 컴포넌트들이지요. 780 00:50:57,683 --> 00:51:00,395 컴포넌트 종류의 양 극단이라고 할 수 있습니다. 781 00:51:00,429 --> 00:51:02,870 아주 안정적인 어른과 782 00:51:02,937 --> 00:51:06,786 아주 불안정적인 청소년이지요. 783 00:51:06,878 --> 00:51:09,071 불안정적인 것은 쉽게 변합니다. 784 00:51:09,154 --> 00:51:11,685 가능한 코드를 적게 넣어야겠지요. 785 00:51:12,391 --> 00:51:15,128 안정적인 것은 변경하기 어렵습니다. 786 00:51:16,378 --> 00:51:22,870 안정적인 정도를 측정할 수 있는 지표를 만들 수 있습니다. 787 00:51:22,902 --> 00:51:25,828 'I'라고 부를 거에요. 788 00:51:26,816 --> 00:51:33,597 'I' 는 다른 것을 이용하는 관계의 수를 789 00:51:33,669 --> 00:51:37,095 나를 이용하는 관계의 수와 다른 것을 이용하는 관계의 수를 더한 것으로 나눈 값입니다. 790 00:51:37,183 --> 00:51:40,231 곰곰히 생각해보면 791 00:51:40,263 --> 00:51:43,563 'I'는 0부터 1 사이의 값이라는 것을 알게 될 것 입니다. 792 00:51:43,647 --> 00:51:46,835 0은 안정적이고, 1은 불안정적입니다. 793 00:51:46,869 --> 00:51:50,026 0은 어른이고, 1은 청소년입니다. 794 00:51:50,092 --> 00:51:53,337 모두 의존 관계에 대한 이야기입니다. 795 00:51:53,370 --> 00:51:59,273 자 그럼 원칙을 다르게 표현해보겠습니다. 796 00:52:05,664 --> 00:52:13,948 컴포넌트는 자기보다 잘 변하지 않는 것에 의존해야 한다. 797 00:52:14,348 --> 00:52:21,748 다르게 말한다면, 의존 관계의 방향은 'I'가 감소하는 방향으로 향해야 한다. 798 00:52:21,827 --> 00:52:25,394 불안정성이 감소하는 것은 안정성이 높아지는 것 이지요. 799 00:52:25,426 --> 00:52:30,656 참조하는 수와 참조되는 수를 가지고 간단하게 확인할 수 있어요. 800 00:52:31,576 --> 00:52:36,733 순환 참조가 왜 나쁘지요? 801 00:52:37,981 --> 00:52:41,441 안정적인 것이 잘 변하는 것을 이용하게되기 때문입니다. 802 00:52:44,864 --> 00:52:48,128 그러면 새로운 문제가 생깁니다. 803 00:52:48,167 --> 00:52:49,920 뭐냐하면 804 00:52:54,953 --> 00:52:56,228 저 맨 밑에 있는 컴포넌트는 어떻지요? 805 00:52:57,662 --> 00:52:59,327 안정적인가요? 아닌가요? 806 00:53:01,337 --> 00:53:02,724 아주 안정적인 컴포넌트입니다. 807 00:53:02,774 --> 00:53:05,103 맨 밑에 위치하기도 하고 808 00:53:05,175 --> 00:53:07,800 많은 모듈들이 사용하고 있습니다. 809 00:53:08,595 --> 00:53:10,422 변경하기 아주 어려워요. 810 00:53:10,764 --> 00:53:14,927 저 컴포넌트를 수정하면 많은 모듈들이 영향을 받게 됩니다. 811 00:53:14,927 --> 00:53:18,348 그냥 버전 넘버만 바뀌었는데도 말입니다. 812 00:53:23,941 --> 00:53:29,017 저 밑에 있는 것들은 변경하기가 아주 까다롭지요. 813 00:53:30,887 --> 00:53:33,373 하지만 벗어날 방법이 있습니다. 814 00:53:33,725 --> 00:53:35,338 다형성을 사용하는 것 입니다. 815 00:53:36,750 --> 00:53:42,927 어떻게 하면 쉽게 확장되게 만들 수 있을까요? 816 00:53:43,791 --> 00:53:46,479 변경하기 까다로운 것이라도 말입니다. 817 00:53:48,710 --> 00:53:50,260 추상 클래스로 만드는 것 입니다. 818 00:53:51,098 --> 00:53:54,422 추상 클래스는 쉽게 확장할 수 있습니다. 819 00:53:55,209 --> 00:53:57,365 직접 수정하지 않고도 820 00:53:57,456 --> 00:54:00,423 시스템에 새로운 피처를 추가할 수 있습니다. 821 00:54:00,472 --> 00:54:05,741 새로운 기능을 파생 클래스에 담아서 말입니다. 822 00:54:06,201 --> 00:54:08,904 그래서 마지막 원칙은 다음과 같습니다. 823 00:54:09,760 --> 00:54:16,153 밑에 위치할 수록 더욱 추상적이어야 한다. 824 00:54:16,185 --> 00:54:18,480 저 위의 것은 구체적입니다. 825 00:54:18,513 --> 00:54:20,310 불안정하고 구체적이지요. 826 00:54:20,310 --> 00:54:23,135 저 밑의 것은 추상적이고 안정적입니다. 827 00:54:23,135 --> 00:54:30,237 저 트리를 따라 내려갈 수록 추상성은 점점 커져갑니다. 828 00:54:32,090 --> 00:54:39,393 추상성은 숫자로 표현될 수 있습니다. 829 00:54:39,425 --> 00:54:46,424 추상 클래스의 개 수를 컴포넌트의 전체 클래스 수로 나누는 것 이지요. 830 00:54:46,895 --> 00:54:50,355 그러면 0부터 1 사이의 'A' 값을 구할 수 있습니다. 831 00:54:50,355 --> 00:54:51,672 0은 구체적인 것 이고요. 832 00:54:51,708 --> 00:54:54,826 1은 모두 추상적인 것 입니다. 컴포넌트에 인터페이스 밖에 없는 거지요. 833 00:54:54,878 --> 00:54:58,622 그러면 아주 흥미로운 일을 할 수 있습니다. 834 00:54:58,698 --> 00:55:09,120 컴포넌트의 'A'와 'I'의 값을 합치면 1이됩니다. 835 00:55:09,152 --> 00:55:13,091 'A' 가 1이어서 추상적이거나 836 00:55:13,129 --> 00:55:15,504 'I'가 0이어서 안정적입니다. 837 00:55:15,541 --> 00:55:19,557 'I'가 0인 경우 불안정적이고 838 00:55:19,606 --> 00:55:21,130 'A'가 0인 경우 구체적입니다. 839 00:55:21,130 --> 00:55:23,375 'A'와 'I'를 합하면 1이됩니다. 840 00:55:23,423 --> 00:55:26,733 마법의 공식입니다. 'A' 더하기 'I'는 1입니다. 841 00:55:26,733 --> 00:55:30,863 저기 위에 추상적인 어른이 있지요 842 00:55:30,897 --> 00:55:33,340 다른 모두가 의존하고 있습니다. 안정적이란 말이지요. 843 00:55:33,378 --> 00:55:35,859 저기 아래에 청소년이 있습니다. 844 00:55:37,254 --> 00:55:41,781 다른 곳에서 사용하고 있지 않지요. 하지만 구체적입니다. 845 00:55:41,815 --> 00:55:43,602 이 것은 무엇인가요? 846 00:55:43,635 --> 00:55:47,142 'A'와 'I'의 합이 1인 것을 보여주고 있지요. 847 00:55:48,472 --> 00:55:53,458 컴포넌트들은 저 두 끝 지점에 위치하는 게 가장 이상적이겠지요. 848 00:55:53,499 --> 00:55:54,376 왜 그럴까요? 849 00:55:55,583 --> 00:55:59,496 여기 왼쪽 위에는 어떤가요? 850 00:56:00,981 --> 00:56:03,951 아주 추상적이지요. 아무 것도 의존하지 않습니다. 851 00:56:05,366 --> 00:56:08,097 인터페이스가 구현하는 모듈이 하나도 없는 경우이지요. 쓸모 없습니다. 852 00:56:08,729 --> 00:56:11,022 여기 쓸 데가 없는 것들입니다. 853 00:56:11,067 --> 00:56:14,316 컴포넌트를 저쪽에 위치하게 하면 안됩니다. 854 00:56:14,388 --> 00:56:15,600 그럼 여기 오른쪽 아래에는 어떤가요? 855 00:56:17,040 --> 00:56:19,658 아주 구체적입니다. 모두가 의존하고 있습니다. 856 00:56:20,230 --> 00:56:21,560 데이터베이스 스키마. 857 00:56:23,292 --> 00:56:25,212 구체적입니다. 모두가 의존하고 있지요. 858 00:56:25,262 --> 00:56:26,519 변경하면 아주 재미나겠지요. 859 00:56:27,371 --> 00:56:29,629 그렇지요? 여기 밑에 위치하면 안됩니다. 860 00:56:29,669 --> 00:56:31,019 아주 고통스러운 구역이에요. 861 00:56:31,713 --> 00:56:36,199 컴포넌트는 저 두 지점에서 가능한 멀리 위치해야 합니다. 862 00:56:36,199 --> 00:56:39,298 이상적으로는 컴포넌트를 여기 여기에 위치하면 좋겠지만 863 00:56:39,333 --> 00:56:42,253 그렇게 하면 컴포넌트가 까다로워집니다. 864 00:56:42,304 --> 00:56:45,450 그래서 최소한 이 선 위에 위치하도록 해야 합니다. 865 00:56:45,962 --> 00:56:48,414 아니면 선에 가깝게요. 866 00:56:48,914 --> 00:56:51,407 여기에서 마지막 측정 기준이 나옵니다. 867 00:56:52,574 --> 00:56:53,566 'D' 입니다. 868 00:56:54,316 --> 00:56:56,975 컴포넌트가 저 선에서 얼마나 떨어져있나를 의미합니다. 869 00:56:57,594 --> 00:57:02,086 'D'는 'A' 더하기 'I' 빼기 1의 절대값 입니다. 870 00:57:02,086 --> 00:57:04,714 계산하기 어렵지 않습니다. 871 00:57:04,714 --> 00:57:07,210 'D'는 0과 1사이의 값입니다. 872 00:57:07,460 --> 00:57:09,574 0은 선위에 있다는 뜻이고 873 00:57:09,607 --> 00:57:11,638 1은 저 나쁜 두 지점에 있다는 것 입니다. 874 00:57:12,111 --> 00:57:14,831 저 두 지점 중에 어느 쪽이냐는 절대값 기호를 빼면 알 수 있겠지요. 875 00:57:14,831 --> 00:57:16,361 뭐 상관 없습니다. 876 00:57:16,481 --> 00:57:22,408 'D'는 의존하는 관계와 의존되는 관계를 보고 알 수 있습니다. 877 00:57:22,437 --> 00:57:23,996 추상적인 정도를 측정하는 것 이지요. 878 00:57:24,075 --> 00:57:27,696 계산 자체는 어렵지 않습니다. 879 00:57:27,733 --> 00:57:33,595 컴포넌트가 저 선위에 있는지 보세요 880 00:57:34,044 --> 00:57:40,423 선 위에 있으면 추상적이고 의존되고 있지요. 881 00:57:41,387 --> 00:57:46,815 선 위에 없으면 추상적이지만 의존되고 있지 않은 것 입니다. 882 00:57:46,885 --> 00:57:49,023 아니면 아주 구체적인데 많이 참조되고 있는 것 입니다. 883 00:57:49,023 --> 00:57:50,361 둘다 아주 나쁜 거지요. 884 00:57:51,455 --> 00:57:55,190 많은 툴들이 이런 지표들을 자동으로 계산해줍니다. 885 00:57:55,261 --> 00:57:58,665 NDepend 써봤나요? NDepend도 이런 지표들을 계산해줍니다. 886 00:57:58,698 --> 00:58:02,580 대부분의 정적 분석 툴들이 887 00:58:02,658 --> 00:58:06,184 I, D 와 같은 지표들을 계산해줍니다. 888 00:58:06,255 --> 00:58:09,529 컴포넌트들의 지표 값들을 쉽게 확인할 수 있습니다. 889 00:58:09,568 --> 00:58:14,219 그리고 어떤 것들이 변경하기 쉬워야 할지 생각해보세요. 890 00:58:14,825 --> 00:58:17,924 변경하기 쉬운 것들은 청소년과 같은 것들입니다. 891 00:58:19,047 --> 00:58:23,650 변경하기 어려운 것은 성인과 같아야 하고 추상적이어야 합니다. 892 00:58:23,650 --> 00:58:27,629 구체적이고 청소년 같은 것 들은 변경하기 쉬워야 합니다. 893 00:58:28,283 --> 00:58:31,796 추상적이고 어른과 같은 것 들은 변경하기 어려워야 합니다. 894 00:58:32,967 --> 00:58:34,178 질문있나요? 895 00:58:36,316 --> 00:58:40,364 PDP-8 어셈블리 코드로 시작해서 여기까지 왔군요. 896 00:58:42,809 --> 00:58:44,617 질문 있나요? 없어요? 897 00:58:45,151 --> 00:58:45,653 좋습니다. 898 00:58:46,559 --> 00:58:47,809 이런 899 00:58:49,760 --> 00:58:51,276 괜찮습니다. 좋아요. 900 00:58:51,393 --> 00:58:56,854 (질문 중) 901 00:58:56,854 --> 00:58:57,486 네 902 00:58:57,486 --> 00:59:03,080 (질문 중) 903 00:59:03,080 --> 00:59:04,955 두 개의 버전이요. 904 00:59:04,955 --> 00:59:07,015 (질문 중) 905 00:59:07,015 --> 00:59:10,351 하나의 컴포넌트가 2개의 버전으로 존재하는 경우요. 아주 어렵지요. 906 00:59:10,540 --> 00:59:11,189 네 907 00:59:11,599 --> 00:59:15,284 같은 컴포넌트의 각각 다른 버전의 파일들을 한 시스템에 두지 마세요. 908 00:59:15,320 --> 00:59:16,923 그게 DLL 지옥입니다. 909 00:59:17,847 --> 00:59:19,909 다른 사람 있나요? 910 00:59:21,349 --> 00:59:24,025 String 클래스의 위치는 어디냐고요? 아주 아주 좋은 질문입니다. 911 00:59:24,025 --> 00:59:26,186 String 클래스는 저기에 위치합니다. 912 00:59:26,952 --> 00:59:31,841 최악의 자리지요. 하지만 아무도 변경하지 않습니다. 따라서 신경 쓸 필요 없습니다. 913 00:59:32,118 --> 00:59:35,767 오늘의 모든 이야기는 현재 개발중인 것에 해당됩니다. 914 00:59:35,809 --> 00:59:37,831 현재 변경 중인 것 이요. 915 00:59:38,061 --> 00:59:42,786 우리 라이브러리의 변경되고 있는 것들을 아주 유의해서 봐야 합니다. 916 00:59:42,786 --> 00:59:45,880 라이브러리 중에서 변경되지 않는 것이나 917 00:59:45,918 --> 00:59:49,029 변경되지 않는 오래된 라이브러리의 것 들은 918 00:59:49,066 --> 00:59:50,470 신경 쓸 필요가 없습니다. 919 00:59:50,513 --> 00:59:52,332 그 중 많은 것들이 저런 곳에 위치하겠지만 920 00:59:52,332 --> 00:59:53,456 괜찮습니다. 921 00:59:53,456 --> 00:59:54,923 저기에 위치하는 것은 없을 것 입니다. 922 00:59:55,733 --> 00:59:57,620 뭐 조금은 있을 수도 있겠지요 923 00:59:57,620 --> 00:59:59,589 죽은 코드를 제거해본 적 있나요? 924 00:59:59,624 --> 01:00:01,948 아무도 상속받지 않는 추상 클래스처럼요? 925 01:00:02,007 --> 01:00:04,869 네 실제로 조금은 있을 수 있겠어요. 926 01:00:04,901 --> 01:00:11,720 String, Vector, 그 밖의 라이브러리 등이 저기에 위치할 수 있겠습니다. 하지만 신경 쓸 필요 없습니다. 쉽게 변경되지 않을 테니까요. 927 01:00:11,756 --> 01:00:16,272 저 그래프로부터 제 3의 축이 여러분 쪽으로 향한다고 생각해보세요. 928 01:00:16,306 --> 01:00:18,368 그게 가변성에 대한 축입니다. 929 01:00:18,368 --> 01:00:21,573 이 화면의 그래프는 가변성이 1에 가까운 상황이죠. 930 01:00:22,123 --> 01:00:24,836 가변성이 0인 경우는 신경 쓸 필요가 없습니다. 931 01:00:26,136 --> 01:00:27,084 또 질문 있나요? 932 01:00:27,963 --> 01:00:29,200 저기 뒤에요.