1 00:00:06,700 --> 00:00:08,970 - When you are ready to really sit down 2 00:00:08,970 --> 00:00:11,610 and build a production level project, 3 00:00:11,610 --> 00:00:14,060 Package Oriented Design is gonna be your friend. 4 00:00:14,060 --> 00:00:16,780 You really, I really want you to spend some time 5 00:00:16,780 --> 00:00:19,310 reading those links that I have on this page. 6 00:00:19,310 --> 00:00:21,260 Because they go into a lot of detail about what I'm 7 00:00:21,260 --> 00:00:22,170 going to cover. 8 00:00:22,170 --> 00:00:24,600 But Package Oriented Design is really important. 9 00:00:24,600 --> 00:00:25,780 'Cause what it's going to do is, 10 00:00:25,780 --> 00:00:29,800 is give you and engineering decision 11 00:00:29,800 --> 00:00:32,220 about where packages go 12 00:00:32,220 --> 00:00:35,890 and it's going to help you identify how your Go project 13 00:00:35,890 --> 00:00:37,010 should be structured. 14 00:00:37,010 --> 00:00:39,900 And it's going to really improve communication 15 00:00:39,900 --> 00:00:41,610 between you and your team members. 16 00:00:41,610 --> 00:00:43,780 The whole idea here is that we want clean 17 00:00:43,780 --> 00:00:46,870 package design and project architecture 18 00:00:46,870 --> 00:00:50,120 that is not random but 19 00:00:50,120 --> 00:00:51,070 very predictable. 20 00:00:51,070 --> 00:00:52,760 The whole idea around mental models 21 00:00:52,760 --> 00:00:54,780 is knowing where everything is. 22 00:00:54,780 --> 00:00:58,220 And if you don't have a Package Oriented Design 23 00:00:58,220 --> 00:01:00,740 around your project structure and your packages, 24 00:01:00,740 --> 00:01:03,410 you're really going to have lots of problems. 25 00:01:03,410 --> 00:01:06,120 Maybe not today, maybe not a month from now, 26 00:01:06,120 --> 00:01:07,830 but you will definitely years. 27 00:01:07,830 --> 00:01:10,453 And also depending what kind of turnover you have. 28 00:01:11,350 --> 00:01:15,123 What's interesting to me is the history behind packaging. 29 00:01:16,260 --> 00:01:19,000 There was an interview given to Brian Kernighan, 30 00:01:19,000 --> 00:01:20,700 in the year 2000. 31 00:01:20,700 --> 00:01:22,920 And Brian was asked this question, 32 00:01:22,920 --> 00:01:26,290 can you tell us about the worse features 33 00:01:26,290 --> 00:01:29,660 of C, the C programming language, from your point of view? 34 00:01:29,660 --> 00:01:31,960 Remember, this was 18 years ago 35 00:01:31,960 --> 00:01:33,780 And this was Brian's response, 36 00:01:33,780 --> 00:01:35,110 and when I read it for the first time, 37 00:01:35,110 --> 00:01:36,960 I almost fell out of my seat. 38 00:01:36,960 --> 00:01:39,280 I think the real problem with C is that it doesn't 39 00:01:39,280 --> 00:01:41,070 give you enough mechanisms for structuring really 40 00:01:41,070 --> 00:01:44,300 big programs, for creating firewalls in that program, 41 00:01:44,300 --> 00:01:45,700 to keep the pieces apart. 42 00:01:45,700 --> 00:01:47,210 It's not that you can't do this, and it's not that 43 00:01:47,210 --> 00:01:48,210 you can't simulate it. 44 00:01:48,210 --> 00:01:50,420 You know you can simulate it OOP all you want, 45 00:01:50,420 --> 00:01:51,300 you can do that, 46 00:01:51,300 --> 00:01:53,130 but here's the key. 47 00:01:53,130 --> 00:01:56,040 You can simulate it, but the compiler and the language 48 00:01:56,040 --> 00:01:57,950 is not giving you any help. 49 00:01:57,950 --> 00:01:59,020 When I read this for the first time, 50 00:01:59,020 --> 00:02:01,690 I almost fell out of my seat. 51 00:02:01,690 --> 00:02:05,660 I mean, here's Brian saying that we have this language 52 00:02:05,660 --> 00:02:08,120 that we're using, but when programs get too large, 53 00:02:08,120 --> 00:02:11,090 we have big problems around encapsulation 54 00:02:11,090 --> 00:02:12,550 and mental models. 55 00:02:12,550 --> 00:02:15,200 And here it is, Go is saying, you know what, Brian, 56 00:02:15,200 --> 00:02:16,960 you're right, and we're going to fix this 57 00:02:16,960 --> 00:02:19,740 with the concept of packaging. 58 00:02:19,740 --> 00:02:23,080 Packaging is our basic unit of compilation in Go. 59 00:02:23,080 --> 00:02:26,010 And it's how we really structure 60 00:02:26,010 --> 00:02:27,570 and think about applications. 61 00:02:27,570 --> 00:02:29,950 And the promise is very, very different 62 00:02:29,950 --> 00:02:31,590 from Object Oriented Design. 63 00:02:31,590 --> 00:02:32,423 Very different. 64 00:02:32,423 --> 00:02:35,710 And so, all of us, me too for a long time, 65 00:02:35,710 --> 00:02:38,960 struggled with this idea of Package Oriented Design. 66 00:02:38,960 --> 00:02:40,720 So, I want to try and give you some guidelines 67 00:02:40,720 --> 00:02:43,970 and some philosophies so you can, hopefully, start thinking 68 00:02:43,970 --> 00:02:47,020 from an engineering standpoint, how to do this better. 69 00:02:47,020 --> 00:02:49,220 And there isn't just one way to do this, 70 00:02:49,220 --> 00:02:50,250 I want you to understand, 71 00:02:50,250 --> 00:02:51,990 this is the way that I've developed 72 00:02:51,990 --> 00:02:53,070 over the last five years. 73 00:02:53,070 --> 00:02:54,560 This is how I'm doing it. 74 00:02:54,560 --> 00:02:56,210 I am doing it successfully. 75 00:02:56,210 --> 00:02:57,320 But every project's different, 76 00:02:57,320 --> 00:02:58,610 every team is different. 77 00:02:58,610 --> 00:03:00,090 Dynamics are different. 78 00:03:00,090 --> 00:03:01,550 So I don't want you to feel like you're locked in. 79 00:03:01,550 --> 00:03:04,680 What I want to make sure is that you've got project 80 00:03:04,680 --> 00:03:07,400 structures and philosophies that are in line, 81 00:03:07,400 --> 00:03:08,490 and you've got policies 82 00:03:08,490 --> 00:03:11,660 and procedures that are in line with this. 83 00:03:11,660 --> 00:03:14,370 So I don't want to say this is an end all, be all. 84 00:03:14,370 --> 00:03:15,910 And what I'm mostly going to share with you, 85 00:03:15,910 --> 00:03:18,650 some of it is agreed upon by the Go community today. 86 00:03:18,650 --> 00:03:20,360 When we start talking about project structures, 87 00:03:20,360 --> 00:03:22,900 this is all me, these are all my opinions, 88 00:03:22,900 --> 00:03:24,610 my ways of doing it. 89 00:03:24,610 --> 00:03:26,650 Don't have to agree with it, at all. 90 00:03:26,650 --> 00:03:29,390 But I think that you'd want to at least find something 91 00:03:29,390 --> 00:03:30,610 you can agree with, 92 00:03:30,610 --> 00:03:32,350 so you can have consistency 93 00:03:32,350 --> 00:03:34,430 and make sure you're maintaining mental models 94 00:03:34,430 --> 00:03:35,740 of your code base. 95 00:03:35,740 --> 00:03:40,740 So here are the language mechanics behind packaging 96 00:03:40,840 --> 00:03:42,433 as it relates to Go. 97 00:03:43,480 --> 00:03:46,100 Now, the big problem here, that you're going to find, 98 00:03:46,100 --> 00:03:49,130 is packaging directly conflicts with how we've been 99 00:03:49,130 --> 00:03:51,600 taught to organize source code. 100 00:03:51,600 --> 00:03:53,720 You've been taught, just create a folder somewhere 101 00:03:53,720 --> 00:03:55,170 in your project source tree. 102 00:03:55,170 --> 00:03:57,530 Throw some code in there and encapsulate. 103 00:03:57,530 --> 00:03:59,820 You know, different parts of your code. 104 00:03:59,820 --> 00:04:02,083 And that is because projects like your C++, 105 00:04:02,083 --> 00:04:04,550 your C Sharp, your Java languages, 106 00:04:04,550 --> 00:04:07,420 you're really building a monolithic application 107 00:04:07,420 --> 00:04:09,380 as it relates to your source code. 108 00:04:09,380 --> 00:04:13,570 In Go, we don't really have a monolithic application. 109 00:04:13,570 --> 00:04:16,550 In Go, every folder in your source tree, 110 00:04:16,550 --> 00:04:20,130 represents a static library. 111 00:04:20,130 --> 00:04:22,280 I want you to think about this for a second. 112 00:04:22,280 --> 00:04:25,020 If we switch over to a project that I want to share, 113 00:04:25,020 --> 00:04:27,170 which is my service project, 114 00:04:27,170 --> 00:04:32,170 this service project can be found on github 115 00:04:32,840 --> 00:04:36,750 under ardanlabs, Go training service. 116 00:04:36,750 --> 00:04:37,720 So I want you to understand that 117 00:04:37,720 --> 00:04:41,390 github.com, ardanlabs, service, 118 00:04:41,390 --> 00:04:43,710 we're going to use this for some Package Oriented Design. 119 00:04:43,710 --> 00:04:46,420 This is a service project that we're developing 120 00:04:46,420 --> 00:04:49,080 and building training around to teach people 121 00:04:49,080 --> 00:04:51,030 how to write services in Go. 122 00:04:51,030 --> 00:04:52,850 This is what I want people to be learning next, 123 00:04:52,850 --> 00:04:54,400 after this class. 124 00:04:54,400 --> 00:04:58,020 So, what I want you to understand is, 125 00:04:58,020 --> 00:04:59,250 this is a project, 126 00:04:59,250 --> 00:05:00,320 it has a source tree. 127 00:05:00,320 --> 00:05:01,700 We'll talk about these folders, 128 00:05:01,700 --> 00:05:03,610 but every folder here 129 00:05:03,610 --> 00:05:05,220 like this one call mid, 130 00:05:05,220 --> 00:05:08,930 is really going to end up being a static library. 131 00:05:08,930 --> 00:05:12,220 This is really interesting, because what Go is saying 132 00:05:12,220 --> 00:05:16,240 is that we build software based on the idea that we 133 00:05:16,240 --> 00:05:19,320 build these packages, which are APIs, 134 00:05:19,320 --> 00:05:21,810 which are really static libraries. 135 00:05:21,810 --> 00:05:25,470 And the idea of building an application through 136 00:05:25,470 --> 00:05:26,880 the use of static libraries, 137 00:05:26,880 --> 00:05:28,380 is not necessarily unique. 138 00:05:28,380 --> 00:05:31,200 Languages allow us to do this, right? 139 00:05:31,200 --> 00:05:34,090 C allows us to create those A files, 140 00:05:34,090 --> 00:05:38,280 those SO files, C Sharp lets us do the DLLs, 141 00:05:38,280 --> 00:05:39,920 Java has jar files. 142 00:05:39,920 --> 00:05:41,870 This isn't new, right? 143 00:05:41,870 --> 00:05:43,630 And Ruby has gems, right? 144 00:05:43,630 --> 00:05:47,420 This isn't new, but you have a choice whether or not 145 00:05:47,420 --> 00:05:50,170 you want to build this monolithic app or build it 146 00:05:50,170 --> 00:05:52,170 in terms of these components. 147 00:05:52,170 --> 00:05:53,880 In Go, this is not a choice. 148 00:05:53,880 --> 00:05:55,370 You have no choice. 149 00:05:55,370 --> 00:05:58,760 Every folder ends up being a static library 150 00:05:58,760 --> 00:06:00,060 whether you like it or not. 151 00:06:00,060 --> 00:06:02,190 This really puts a constraint on us. 152 00:06:02,190 --> 00:06:04,170 So you can't just create a folder randomly 153 00:06:04,170 --> 00:06:05,470 and put some stuff in it, 154 00:06:05,470 --> 00:06:07,400 because you're really going to hurt yourself. 155 00:06:07,400 --> 00:06:10,140 You have to think about packaging your component level 156 00:06:10,140 --> 00:06:13,490 API design from the very beginning. 157 00:06:13,490 --> 00:06:15,670 What's kind of interesting to me though, 158 00:06:15,670 --> 00:06:19,640 is that this idea of packaging at the source code level, 159 00:06:19,640 --> 00:06:22,420 here our source tree, really makes me think about 160 00:06:22,420 --> 00:06:25,740 almost micro services at our source code. 161 00:06:25,740 --> 00:06:29,810 Where every folder represents it's own unique API, 162 00:06:29,810 --> 00:06:32,720 it's own kind of program boundary. 163 00:06:32,720 --> 00:06:35,380 Just like we would have with micro services. 164 00:06:35,380 --> 00:06:38,030 So we've got to find ways of decoupling 165 00:06:38,030 --> 00:06:39,450 these program boundaries 166 00:06:39,450 --> 00:06:42,840 and contracts these program boundaries so they can interact. 167 00:06:42,840 --> 00:06:45,250 Again, dealing with what change? 168 00:06:45,250 --> 00:06:47,610 So, it's a really interesting brand-new way 169 00:06:47,610 --> 00:06:49,920 to think of adding software development, design, 170 00:06:49,920 --> 00:06:51,140 and architecture. 171 00:06:51,140 --> 00:06:54,210 Now, understand something, that there is no real concept 172 00:06:54,210 --> 00:06:56,670 of sub packages, just because a folder sitting 173 00:06:56,670 --> 00:06:59,170 inside of another folder doesn't meant that this package 174 00:06:59,170 --> 00:07:00,290 is a sub package. 175 00:07:00,290 --> 00:07:04,680 All packages are built and compiled and then laid out. 176 00:07:04,680 --> 00:07:07,620 From the linkers point of view, all packages 177 00:07:07,620 --> 00:07:09,050 are at the same level. 178 00:07:09,050 --> 00:07:11,300 So, we want to leverage the hierarchy 179 00:07:11,300 --> 00:07:14,360 to give us some indications about relationships, 180 00:07:14,360 --> 00:07:16,150 but from the compilers point of view 181 00:07:16,150 --> 00:07:17,380 there are no sub packages, 182 00:07:17,380 --> 00:07:18,960 there are no relationships, 183 00:07:18,960 --> 00:07:21,120 all packages are at the same level. 184 00:07:21,120 --> 00:07:23,220 And we talked already, about exporting 185 00:07:23,220 --> 00:07:24,180 and unexporting. 186 00:07:24,180 --> 00:07:26,860 Exporting being a way of opening up a packages' API 187 00:07:26,860 --> 00:07:28,030 to be public. 188 00:07:28,030 --> 00:07:30,050 And another interesting thing is that, 189 00:07:30,050 --> 00:07:32,750 two packages cannot cross-import each other. 190 00:07:32,750 --> 00:07:34,850 And this is a really important decision. 191 00:07:34,850 --> 00:07:37,320 It's done to, kind of, simplify things 192 00:07:37,320 --> 00:07:41,120 and it helps to, also, to make sure the initialization 193 00:07:41,120 --> 00:07:42,140 is consistent. 194 00:07:42,140 --> 00:07:43,840 If you have two packages importing each other, 195 00:07:43,840 --> 00:07:46,040 which one gets to be initialized first? 196 00:07:46,040 --> 00:07:47,690 That's a very complicated problem. 197 00:07:47,690 --> 00:07:49,830 Especially, consistency over time. 198 00:07:49,830 --> 00:07:51,550 So, it also makes you slow down 199 00:07:51,550 --> 00:07:54,110 and start to think about, the relationships, 200 00:07:54,110 --> 00:07:56,890 or the importer coupling relationships you have 201 00:07:56,890 --> 00:07:58,090 between packages. 202 00:07:58,090 --> 00:08:01,250 So, the language mechanics are kind of few, 203 00:08:01,250 --> 00:08:04,600 but they do put some interesting constraints on how we 204 00:08:04,600 --> 00:08:08,620 define projects, lay out projects, how we code 205 00:08:08,620 --> 00:08:11,290 and architect and design our source code. 206 00:08:11,290 --> 00:08:14,810 It's no more a monolithic application with folders, 207 00:08:14,810 --> 00:08:19,810 it is a project with lots of individual static libraries 208 00:08:20,340 --> 00:08:21,340 that we call packages 209 00:08:21,340 --> 00:08:25,400 that eventually are going to import and be bound together. 210 00:08:25,400 --> 00:08:28,890 And the more decoupling we can think about in this case, 211 00:08:28,890 --> 00:08:31,653 the better and healthier our projects are going to be.