1 00:00:06,570 --> 00:00:09,060 - Refactoring is an important aspect 2 00:00:09,060 --> 00:00:10,290 of test room development, 3 00:00:10,290 --> 00:00:12,750 but it's often overlooked by developers. 4 00:00:12,750 --> 00:00:14,490 Developers get carried away. 5 00:00:14,490 --> 00:00:16,923 We write our tests, then we write our code, 6 00:00:16,923 --> 00:00:18,690 then we write the next test, 7 00:00:18,690 --> 00:00:20,460 then the next piece of code. 8 00:00:20,460 --> 00:00:22,110 After writing a piece of code, 9 00:00:22,110 --> 00:00:23,850 you could pause and consider 10 00:00:23,850 --> 00:00:26,373 whether you can refactor your code to improve it. 11 00:00:27,420 --> 00:00:31,455 So after each iteration of a test, 12 00:00:31,455 --> 00:00:33,450 I ran the test, it failed. 13 00:00:33,450 --> 00:00:34,830 I added the code. 14 00:00:34,830 --> 00:00:35,880 I ran the test again. 15 00:00:35,880 --> 00:00:36,713 It passed. 16 00:00:36,713 --> 00:00:39,210 After each of those iterations, you should pause 17 00:00:39,210 --> 00:00:41,430 and take a step back, review the code 18 00:00:41,430 --> 00:00:44,190 to see if you can improve it, reorganize it 19 00:00:44,190 --> 00:00:45,960 to make it better. 20 00:00:45,960 --> 00:00:48,570 So some examples common refactorings 21 00:00:48,570 --> 00:00:50,610 to eliminate duplication. 22 00:00:50,610 --> 00:00:52,110 You might after awhile realize 23 00:00:52,110 --> 00:00:54,337 that you've got the same code happening 24 00:00:54,337 --> 00:00:55,200 here, there, and everywhere. 25 00:00:55,200 --> 00:00:56,070 That's bad. 26 00:00:56,070 --> 00:00:58,980 Refactor it into a common shared method 27 00:00:58,980 --> 00:01:02,070 so that you don't have to maintain the code 28 00:01:02,070 --> 00:01:03,480 in separate places. 29 00:01:03,480 --> 00:01:04,680 Kind of obvious, really, 30 00:01:05,534 --> 00:01:07,050 but you need to be disciplined to do it. 31 00:01:07,050 --> 00:01:08,880 To restructure inheritance, 32 00:01:08,880 --> 00:01:10,800 you might find that two classes, for example 33 00:01:10,800 --> 00:01:11,880 are quite similar. 34 00:01:11,880 --> 00:01:15,480 So instead of having two classes which overlap each other, 35 00:01:15,480 --> 00:01:19,650 extract the common methods and properties into a super class 36 00:01:19,650 --> 00:01:22,710 and use inheritance to avoid duplication. 37 00:01:22,710 --> 00:01:27,710 And renaming variables is a common refactoring exercise. 38 00:01:27,870 --> 00:01:29,370 So what we'll do in this section 39 00:01:29,370 --> 00:01:31,380 is we're gonna go through the process 40 00:01:31,380 --> 00:01:33,360 of refactoring some code. 41 00:01:33,360 --> 00:01:35,641 So if you look in the refactoring folder, 42 00:01:35,641 --> 00:01:37,860 here it is. 43 00:01:37,860 --> 00:01:39,060 So in lesson seven 44 00:01:39,060 --> 00:01:42,870 if you open the refactoring folder in the code editor 45 00:01:42,870 --> 00:01:44,790 what you'll find is there are two folders. 46 00:01:44,790 --> 00:01:46,290 There's an original folder 47 00:01:46,290 --> 00:01:48,600 that contains some code that I've written. 48 00:01:48,600 --> 00:01:50,460 And then there's a refactored folder, 49 00:01:50,460 --> 00:01:52,830 which is kind of like before and after. 50 00:01:52,830 --> 00:01:54,600 The code that I wrote initially 51 00:01:54,600 --> 00:01:57,630 and then the improved code after refactoring. 52 00:01:57,630 --> 00:01:59,070 So we are gonna look at, 53 00:01:59,070 --> 00:02:02,340 I'm gonna use Visual Studio as well to help me 54 00:02:02,340 --> 00:02:04,590 refactor certain things from that code 55 00:02:04,590 --> 00:02:06,750 until it looks more like that code there. 56 00:02:06,750 --> 00:02:09,690 So the original code and the improved code. 57 00:02:09,690 --> 00:02:10,770 So there we go. 58 00:02:10,770 --> 00:02:14,790 The original folder is my original product class. 59 00:02:14,790 --> 00:02:17,070 And after the next five minutes or so, 60 00:02:17,070 --> 00:02:20,043 we'll have an improved version in the refactored folder, 61 00:02:21,150 --> 00:02:23,700 and I'm going to use, I'm using Visual Studio Code 62 00:02:23,700 --> 00:02:24,900 as my editor. 63 00:02:24,900 --> 00:02:28,620 Most editors have some, you know, at least some support 64 00:02:28,620 --> 00:02:30,100 to help you refactor 65 00:02:31,081 --> 00:02:33,090 so that you don't have to kind of rename things manually. 66 00:02:33,090 --> 00:02:35,190 You can use tools in your editor 67 00:02:35,190 --> 00:02:38,610 to do it more consistently and thoroughly. 68 00:02:38,610 --> 00:02:41,970 It's good to use the refactoring capabilities of an editor 69 00:02:41,970 --> 00:02:44,370 rather than doing like a global search and replace 70 00:02:44,370 --> 00:02:46,470 which is more error prone. 71 00:02:46,470 --> 00:02:48,900 So you can rename most things: 72 00:02:48,900 --> 00:02:51,545 variables, functions and classes. 73 00:02:51,545 --> 00:02:54,803 In my product class, I've got a variable, 74 00:02:54,803 --> 00:02:56,940 but I'm going to rename. 75 00:02:56,940 --> 00:02:59,559 You select the variable in Visual Studio Code, 76 00:02:59,559 --> 00:03:02,940 right click and then select rename simple. 77 00:03:02,940 --> 00:03:04,200 I'll do this in a moment, 78 00:03:04,200 --> 00:03:07,410 and then you basically give it the new name and press enter. 79 00:03:07,410 --> 00:03:09,990 So if you looked in my original product class, 80 00:03:09,990 --> 00:03:11,040 you'd find that the product 81 00:03:11,040 --> 00:03:14,010 has a property called description. 82 00:03:14,010 --> 00:03:17,490 I'm going to refactor the description property 83 00:03:17,490 --> 00:03:20,760 to be called name instead. 84 00:03:20,760 --> 00:03:23,760 Okay, so a product property description 85 00:03:23,760 --> 00:03:26,010 I decided wasn't a great name for it. 86 00:03:26,010 --> 00:03:28,470 I decided name was a better name. 87 00:03:28,470 --> 00:03:30,600 So let's do that refactoring. 88 00:03:30,600 --> 00:03:33,540 So I'm gonna go into my original folder, 89 00:03:33,540 --> 00:03:37,053 and I'm going to select the description property here. 90 00:03:37,890 --> 00:03:41,700 Right click, and then I'm going to rename symbol. 91 00:03:41,700 --> 00:03:43,713 I'm going to rename it to name. 92 00:03:45,022 --> 00:03:45,855 There we go. 93 00:03:45,855 --> 00:03:49,080 And it changes it everywhere that property occurred 94 00:03:49,080 --> 00:03:51,063 then it's changed it in the code. 95 00:03:52,380 --> 00:03:54,603 Okay, so it changed it here as well. 96 00:03:55,560 --> 00:03:56,520 So that's good. 97 00:03:56,520 --> 00:03:57,780 That was easy enough. 98 00:03:57,780 --> 00:04:00,460 And you can rename, you know, everything. 99 00:04:00,460 --> 00:04:03,300 You can rename variables, classes, functions, and so on. 100 00:04:03,300 --> 00:04:05,850 By the way, in the refactored version, 101 00:04:05,850 --> 00:04:07,950 it contains all of these refactorings, 102 00:04:07,950 --> 00:04:09,330 like in the final version. 103 00:04:09,330 --> 00:04:12,930 So in the refactored folder, it contains all of those, 104 00:04:12,930 --> 00:04:14,010 all of the things we're gonna look at 105 00:04:14,010 --> 00:04:16,233 have already been done in this version. 106 00:04:17,610 --> 00:04:19,110 Okay, so renaming things 107 00:04:19,110 --> 00:04:22,680 is almost like a trivial refactoring, but it is important. 108 00:04:22,680 --> 00:04:24,990 Often when you start coding, 109 00:04:24,990 --> 00:04:28,620 you don't really understand the problem thoroughly. 110 00:04:28,620 --> 00:04:31,020 And after two or three days working with a problem, 111 00:04:31,020 --> 00:04:32,640 you get a better understanding, 112 00:04:32,640 --> 00:04:35,763 or a better name would be X. 113 00:04:35,763 --> 00:04:37,680 So rename it. 114 00:04:37,680 --> 00:04:40,899 Every time you visit the code you could rename things. 115 00:04:40,899 --> 00:04:43,530 You've also got the tests as well, hopefully, 116 00:04:43,530 --> 00:04:46,380 so that you can guarantee, just run the tests again 117 00:04:46,380 --> 00:04:48,390 to make sure that you haven't broken anything 118 00:04:48,390 --> 00:04:49,653 by doing this rename. 119 00:04:50,982 --> 00:04:52,440 Okay, extracting a constant. 120 00:04:52,440 --> 00:04:56,040 Magic numbers in your code are nearly always a bad idea. 121 00:04:56,040 --> 00:04:58,620 I could, again, I could tell you a horror story 122 00:04:58,620 --> 00:05:02,160 about an experience I had when I was about 25 123 00:05:02,160 --> 00:05:04,500 where involving magic numbers in the code. 124 00:05:04,500 --> 00:05:05,670 It was a very painful experience. 125 00:05:05,670 --> 00:05:07,860 I'll never make that mistake again. 126 00:05:07,860 --> 00:05:12,450 There was magic number 42 cropped up in the code, 127 00:05:12,450 --> 00:05:15,510 and the number on its own doesn't have any meaning. 128 00:05:15,510 --> 00:05:17,790 So what you should do is you should, 129 00:05:17,790 --> 00:05:19,680 is you should extract the magic number 130 00:05:19,680 --> 00:05:23,130 into a constant variable, and variables have a name. 131 00:05:23,130 --> 00:05:27,000 And the name is like a comment that describes the intent. 132 00:05:27,000 --> 00:05:29,820 So as an example, we're gonna take a variable. 133 00:05:29,820 --> 00:05:32,998 You right click on the magic number, 134 00:05:32,998 --> 00:05:35,580 and then you extract into a constant. 135 00:05:35,580 --> 00:05:37,300 This is in Visual Studio Code. 136 00:05:37,300 --> 00:05:40,233 Okay, refactor extract the constant. 137 00:05:41,539 --> 00:05:44,310 And then you give the constant a name and press enter. 138 00:05:44,310 --> 00:05:48,330 Okay, so I'll just go back to the previous slide. 139 00:05:48,330 --> 00:05:49,200 There we go. 140 00:05:49,200 --> 00:05:50,343 Let's do that. 141 00:05:51,997 --> 00:05:53,370 If you go into the product class, 142 00:05:53,370 --> 00:05:56,040 here, the tax payable. 143 00:05:56,040 --> 00:06:00,540 I live in the UK, and in the UK sales tax is 20%. 144 00:06:00,540 --> 00:06:05,280 This is meant to calculate the sales tax on a product. 145 00:06:05,280 --> 00:06:07,290 I've got a magic number here. 146 00:06:07,290 --> 00:06:11,010 In the UK, you'd know that 0.2 is the sales tax, 147 00:06:11,010 --> 00:06:14,940 but if you live in the US or in France or Singapore 148 00:06:14,940 --> 00:06:17,000 or some other country you might think 149 00:06:17,000 --> 00:06:18,630 what on earth is this is this number here? 150 00:06:18,630 --> 00:06:21,615 So let's extract that constant. 151 00:06:21,615 --> 00:06:25,083 So we're gonna select an option here and refactor. 152 00:06:26,040 --> 00:06:28,230 Extract to constant. 153 00:06:28,230 --> 00:06:31,530 You can extract it to a constant in the enclosing scope 154 00:06:31,530 --> 00:06:32,700 within the function 155 00:06:32,700 --> 00:06:35,250 or you can extract it into other places. 156 00:06:35,250 --> 00:06:37,743 I'm just gonna extract it into local scope, 157 00:06:39,001 --> 00:06:42,993 and I'm gonna call the new variable sales tax rate. 158 00:06:47,970 --> 00:06:52,140 Okay, so that makes it clearer, doesn't it? 159 00:06:52,140 --> 00:06:55,020 Generally, it's better to have named variables 160 00:06:55,020 --> 00:06:58,380 than to have a comment because comments can lie. 161 00:06:58,380 --> 00:07:01,920 Whereas names of variables are hopefully more stable. 162 00:07:01,920 --> 00:07:03,840 Okay, so I think that's more readable. 163 00:07:03,840 --> 00:07:04,800 What is 0.2? 164 00:07:04,800 --> 00:07:06,300 Oh, it's the sales tax rate. 165 00:07:06,300 --> 00:07:07,530 It's clearer. 166 00:07:07,530 --> 00:07:11,910 Okay, if you have a class, you can extract the constant 167 00:07:11,910 --> 00:07:15,339 as a static class member instead. 168 00:07:15,339 --> 00:07:16,517 Have a look at this. 169 00:07:16,517 --> 00:07:17,970 Imagine that's where I started with. 170 00:07:17,970 --> 00:07:21,120 Instead of declaring a constant inside the function 171 00:07:21,120 --> 00:07:22,380 like I've just done, 172 00:07:22,380 --> 00:07:24,930 maybe that number crops up in several functions. 173 00:07:24,930 --> 00:07:27,330 So you can define it as a class variable instead 174 00:07:27,330 --> 00:07:29,703 to give it a wider scope like this. 175 00:07:30,540 --> 00:07:31,936 Give it a class. 176 00:07:31,936 --> 00:07:34,800 You can basically define a static variable sales tax rate. 177 00:07:34,800 --> 00:07:36,300 And that variable there 178 00:07:36,300 --> 00:07:38,610 basically belongs to the whole product class, 179 00:07:38,610 --> 00:07:40,920 product.sales_tax_rate. 180 00:07:40,920 --> 00:07:42,720 You can then use this variable, 181 00:07:42,720 --> 00:07:46,080 this constant I should say, any way you like in your code. 182 00:07:46,080 --> 00:07:47,190 And I've done that. 183 00:07:47,190 --> 00:07:48,240 If you look at the, 184 00:07:48,240 --> 00:07:50,883 look at the kind of refactored version of my code, 185 00:07:51,811 --> 00:07:54,840 I've defined a static here for sales tax rate. 186 00:07:54,840 --> 00:07:56,820 So I could use it here, 187 00:07:56,820 --> 00:07:58,500 and I could use it in any other methods 188 00:07:58,500 --> 00:08:00,030 where that might crop up. 189 00:08:00,030 --> 00:08:01,800 So I would prefer this approach 190 00:08:01,800 --> 00:08:03,870 because it kind of makes it more visible 191 00:08:03,870 --> 00:08:05,730 that it's a useful constant 192 00:08:05,730 --> 00:08:08,160 that applies for the whole class. 193 00:08:08,160 --> 00:08:11,610 Remember in JavaScript that everything's public. 194 00:08:11,610 --> 00:08:14,130 So if you define this field here, 195 00:08:14,130 --> 00:08:16,260 you can access it in your external code. 196 00:08:16,260 --> 00:08:18,870 You could say product.sales_tax_rate, 197 00:08:18,870 --> 00:08:21,600 and you get the value back, 0.2. 198 00:08:21,600 --> 00:08:24,630 Okay, extracting code into a method. 199 00:08:24,630 --> 00:08:26,820 If you have a method that's getting a bit too long, 200 00:08:26,820 --> 00:08:30,180 you can select some of the code that you want to extract, 201 00:08:30,180 --> 00:08:32,040 and then you can click refactor. 202 00:08:32,040 --> 00:08:35,490 And then in the refactor menu, you can say extract method, 203 00:08:35,490 --> 00:08:37,800 and you can move that code into a separate method. 204 00:08:37,800 --> 00:08:40,440 The motivation is to keep methods short. 205 00:08:40,440 --> 00:08:42,660 Methods should be as short as possible 206 00:08:42,660 --> 00:08:44,733 with one single purpose. 207 00:08:45,570 --> 00:08:48,240 Give the method a name and then press enter. 208 00:08:48,240 --> 00:08:50,490 So let's see an example of that. 209 00:08:50,490 --> 00:08:52,391 Have a look at this code here. 210 00:08:52,391 --> 00:08:53,760 It's a two string function for product. 211 00:08:53,760 --> 00:08:55,920 I'm just gonna go back into the product class 212 00:08:55,920 --> 00:08:57,870 to explain a few things first. 213 00:08:57,870 --> 00:09:00,390 So in my original product class, 214 00:09:00,390 --> 00:09:01,980 a product has ratings. 215 00:09:01,980 --> 00:09:03,960 This here is a variated parameter. 216 00:09:03,960 --> 00:09:05,760 It's an array basically. 217 00:09:05,760 --> 00:09:08,550 When you buy a product a product might have ratings. 218 00:09:08,550 --> 00:09:10,050 Like somebody might give it a five. 219 00:09:10,050 --> 00:09:11,520 Somebody might give it a four. 220 00:09:11,520 --> 00:09:12,900 Somebody might give it a zero. 221 00:09:12,900 --> 00:09:13,830 So it has an array. 222 00:09:13,830 --> 00:09:16,380 That's an array of ratings. 223 00:09:16,380 --> 00:09:18,330 And in my two string function, 224 00:09:18,330 --> 00:09:21,360 it builds up a string that has the name of the product 225 00:09:21,360 --> 00:09:25,560 and the price and a comma separated list of ratings. 226 00:09:25,560 --> 00:09:29,040 So down here, here's my two string function. 227 00:09:29,040 --> 00:09:32,010 It builds up a string of ratings. 228 00:09:32,010 --> 00:09:35,250 First of all, this bit of code here, it has a string. 229 00:09:35,250 --> 00:09:38,832 It says basically, ratings.length. 230 00:09:38,832 --> 00:09:39,930 Imagine there were five ratings. 231 00:09:39,930 --> 00:09:42,900 So it would say five ratings colon. 232 00:09:42,900 --> 00:09:46,500 And then it basically adds each rating in to the string, 233 00:09:46,500 --> 00:09:48,930 actually separated by a space. 234 00:09:48,930 --> 00:09:50,790 Okay, so, and then after that 235 00:09:50,790 --> 00:09:54,120 it'll take the person's, the product's name, 236 00:09:54,120 --> 00:09:57,420 the price of the product in great British pounds, 237 00:09:57,420 --> 00:10:01,320 and the rating string that we just accumulated up here. 238 00:10:01,320 --> 00:10:03,690 So, I mean, it's not that complicated, 239 00:10:03,690 --> 00:10:08,160 but this code here could potentially be getting tricky. 240 00:10:08,160 --> 00:10:09,960 So what I would do is I'd say, right, 241 00:10:09,960 --> 00:10:13,170 that code is doing something distinct. 242 00:10:13,170 --> 00:10:15,520 Why don't I move that code into another method 243 00:10:16,470 --> 00:10:18,480 to simplify this method? 244 00:10:18,480 --> 00:10:20,637 So right click, select the code, 245 00:10:20,637 --> 00:10:23,880 and right click and then select refactor, 246 00:10:23,880 --> 00:10:28,500 and then extract to method in class product. 247 00:10:28,500 --> 00:10:31,620 Okay, you can have inner functions in JavaScript, 248 00:10:31,620 --> 00:10:34,590 one function declared inside another, 249 00:10:34,590 --> 00:10:37,350 but I think having a top level method in product 250 00:10:37,350 --> 00:10:38,673 probably makes more sense. 251 00:10:39,690 --> 00:10:44,653 Okay, so then I give it a name ratings, two string, 252 00:10:45,835 --> 00:10:47,613 something like that. 253 00:10:49,290 --> 00:10:51,780 So the benefits are twofold. 254 00:10:51,780 --> 00:10:55,712 First of all, my original method is simpler and clearer 255 00:10:55,712 --> 00:10:57,750 because it's fewer lines of code. 256 00:10:57,750 --> 00:11:02,750 The complexity of this calculation has been absorbed now 257 00:11:02,910 --> 00:11:04,290 by this function. 258 00:11:04,290 --> 00:11:07,770 So this function can, if the complexity grows, 259 00:11:07,770 --> 00:11:10,530 I can encapsulate that in this function. 260 00:11:10,530 --> 00:11:13,251 The name of that function is effectively a comment. 261 00:11:13,251 --> 00:11:15,540 It describes what the method does. 262 00:11:15,540 --> 00:11:17,520 When I'm reading this code, 263 00:11:17,520 --> 00:11:20,730 I don't really need to care how it's implemented. 264 00:11:20,730 --> 00:11:23,094 I can look at it if I need to, but I don't have to. 265 00:11:23,094 --> 00:11:27,510 I can just say the name of the method tells me what it does. 266 00:11:27,510 --> 00:11:28,343 That's enough. 267 00:11:28,343 --> 00:11:29,460 I don't need to know how. 268 00:11:29,460 --> 00:11:31,410 I just need to know what it does. 269 00:11:31,410 --> 00:11:33,900 It gives you back the ratings as a string, 270 00:11:33,900 --> 00:11:35,850 and then I can use it here. 271 00:11:35,850 --> 00:11:36,960 And in fact, what I could do 272 00:11:36,960 --> 00:11:39,574 is I could probably just get rid of that variable altogether 273 00:11:39,574 --> 00:11:44,313 and then just put that calculation in line here, maybe. 274 00:11:45,275 --> 00:11:47,940 I actually think I preferred it the way it was. 275 00:11:47,940 --> 00:11:49,860 I think that's clearer. 276 00:11:49,860 --> 00:11:51,330 Clarity is the main thing. 277 00:11:51,330 --> 00:11:53,550 So by extracting code into methods, 278 00:11:53,550 --> 00:11:57,333 each method becomes smaller and more focused. 279 00:11:57,333 --> 00:11:58,680 So it's easier to implement correctly. 280 00:11:58,680 --> 00:12:00,933 You can test it in isolation as well. 281 00:12:02,175 --> 00:12:03,690 I could test that method on its own, 282 00:12:03,690 --> 00:12:06,032 and this method becomes simpler. 283 00:12:06,032 --> 00:12:08,371 So it's easier to write, easier to maintain, easier to test. 284 00:12:08,371 --> 00:12:12,090 And the intent is clearer as well. 285 00:12:12,090 --> 00:12:14,340 Okay, so that's basically what I've done. 286 00:12:14,340 --> 00:12:16,830 I called the method format maintenance there. 287 00:12:16,830 --> 00:12:18,840 So the code that was in here, 288 00:12:18,840 --> 00:12:21,210 my two string function now looks simpler. 289 00:12:21,210 --> 00:12:22,043 And this code 290 00:12:22,043 --> 00:12:24,180 which could eventually become quite complicated 291 00:12:24,180 --> 00:12:26,910 has been shoveled off into another function, 292 00:12:26,910 --> 00:12:30,900 like putting stuff in your cupboard under the stairs, 293 00:12:30,900 --> 00:12:31,980 hiding it away. 294 00:12:31,980 --> 00:12:34,630 You don't have to look in there if you don't want to. 295 00:12:36,090 --> 00:12:37,893 Right, avoiding duplication. 296 00:12:38,790 --> 00:12:40,620 Code duplication is not great. 297 00:12:40,620 --> 00:12:42,090 You end up with two lumps of code 298 00:12:42,090 --> 00:12:44,310 that you have to maintain separately. 299 00:12:44,310 --> 00:12:45,570 Have a look. 300 00:12:45,570 --> 00:12:48,816 In my product class, I've got a method, 301 00:12:48,816 --> 00:12:52,530 it displays the count of low ratings. 302 00:12:52,530 --> 00:12:54,990 A low rating is basically a one. 303 00:12:54,990 --> 00:12:57,254 If somebody rates my product as a one, 304 00:12:57,254 --> 00:13:00,480 this function will count how many people 305 00:13:00,480 --> 00:13:02,393 have rated my product as a one. 306 00:13:02,393 --> 00:13:05,850 So it loops through the ratings for the product. 307 00:13:05,850 --> 00:13:07,080 If the rating is a one, 308 00:13:07,080 --> 00:13:09,270 it increments the counter zero initially, 309 00:13:09,270 --> 00:13:14,010 and then it says the number of low ratings was the count. 310 00:13:14,010 --> 00:13:15,870 I also display the number of times 311 00:13:15,870 --> 00:13:18,270 that people gave me a high rating of five. 312 00:13:18,270 --> 00:13:21,216 The code in here is very similar. 313 00:13:21,216 --> 00:13:23,890 Basically the code in there and the code in there 314 00:13:25,472 --> 00:13:26,305 is pretty much identical 315 00:13:26,305 --> 00:13:29,595 apart from the fact that in one case I'm counting ones 316 00:13:29,595 --> 00:13:31,350 and in another case, I'm counting five. 317 00:13:31,350 --> 00:13:35,040 Now, it's not common for code to be that similar 318 00:13:35,040 --> 00:13:37,680 but you know, sometimes you've gotta massage it a bit, 319 00:13:37,680 --> 00:13:38,940 but you will eventually find 320 00:13:38,940 --> 00:13:40,470 that those two functions 321 00:13:40,470 --> 00:13:44,310 are effectively largely duplicating themselves. 322 00:13:44,310 --> 00:13:45,540 Not good. 323 00:13:45,540 --> 00:13:46,980 So what I'm gonna do is 324 00:13:46,980 --> 00:13:49,616 I'm going to rearrange that code slightly 325 00:13:49,616 --> 00:13:53,640 to extract, you know the one or the five into a variable. 326 00:13:53,640 --> 00:13:56,430 Take that one there and basically put it 327 00:13:56,430 --> 00:13:57,610 into a variable here 328 00:13:58,518 --> 00:14:00,018 const targetrating equals one. 329 00:14:01,213 --> 00:14:02,895 I'm gonna do that in my code. 330 00:14:02,895 --> 00:14:03,728 I'm gonna do that twice. 331 00:14:03,728 --> 00:14:05,820 I've got the count of low ratings. 332 00:14:05,820 --> 00:14:07,380 So I'm gonna basically declare, 333 00:14:07,380 --> 00:14:12,330 I'm gonna extract this constant here. 334 00:14:12,330 --> 00:14:14,191 I'm gonna extract that constant. 335 00:14:14,191 --> 00:14:15,473 I wonder if I can actually do that. 336 00:14:16,380 --> 00:14:21,380 Refactor, extract to constant in closing scope 337 00:14:21,630 --> 00:14:24,543 I'm gonna call it target rating. 338 00:14:26,850 --> 00:14:29,580 Okay, and because I know how this demo is going to evolve 339 00:14:29,580 --> 00:14:32,580 in a moment I'm just gonna move that from there up to there. 340 00:14:34,428 --> 00:14:38,040 And I could do the same thing down here as well. 341 00:14:38,040 --> 00:14:41,910 I can extract this number five from there 342 00:14:41,910 --> 00:14:45,930 into a, and refactor and extract to constant 343 00:14:45,930 --> 00:14:47,760 in explosion scope. 344 00:14:47,760 --> 00:14:50,274 I'm gonna call that target rating as well, 345 00:14:50,274 --> 00:14:52,800 targetRating, like that. 346 00:14:52,800 --> 00:14:56,763 And also I'm gonna move that code up here. 347 00:14:57,780 --> 00:14:59,820 So have a look what I've got. 348 00:14:59,820 --> 00:15:03,330 These functions now, and the code in the first function 349 00:15:03,330 --> 00:15:08,330 that code is identical to this code. 350 00:15:08,790 --> 00:15:11,040 That's the same code now, isn't it? 351 00:15:11,040 --> 00:15:12,000 Duplication. 352 00:15:12,000 --> 00:15:14,580 I had to work a little bit to get them identical, 353 00:15:14,580 --> 00:15:16,230 but they are identical now. 354 00:15:16,230 --> 00:15:21,120 So let's extract one of those into a method, 355 00:15:21,120 --> 00:15:23,793 extract to a method in class product. 356 00:15:24,660 --> 00:15:29,433 How about count rating, something like that. 357 00:15:30,390 --> 00:15:32,220 It's intelligent enough to know 358 00:15:32,220 --> 00:15:35,850 that the count rating function needs to have a parameter. 359 00:15:35,850 --> 00:15:38,580 Haven't declared this target rate in here. 360 00:15:38,580 --> 00:15:39,810 It's intelligent enough to know 361 00:15:39,810 --> 00:15:42,720 that it needs to pass that parameter into here. 362 00:15:42,720 --> 00:15:44,700 So it knows what rating it's counting. 363 00:15:44,700 --> 00:15:48,120 It's counting a rating of five in this case. 364 00:15:48,120 --> 00:15:50,220 Now unfortunately, VS Code, 365 00:15:50,220 --> 00:15:52,775 it isn't quite smart enough to realize 366 00:15:52,775 --> 00:15:54,480 that this method was also basically the same. 367 00:15:54,480 --> 00:15:55,380 It didn't realize 368 00:15:55,380 --> 00:15:59,040 that it can also basically do the same function call there 369 00:15:59,040 --> 00:15:59,880 up here as well. 370 00:15:59,880 --> 00:16:01,830 So I'm gonna have to manually do that. 371 00:16:01,830 --> 00:16:04,770 So a little bit of manual effort, but it's not too bad, 372 00:16:04,770 --> 00:16:06,960 not too bad really is it? 373 00:16:06,960 --> 00:16:09,270 So my count low rating, 374 00:16:09,270 --> 00:16:12,600 and my count high rating have been reduced, 375 00:16:12,600 --> 00:16:15,990 and the commonality has been extracted into a shared place. 376 00:16:15,990 --> 00:16:17,760 And I could take it a step further. 377 00:16:17,760 --> 00:16:19,800 I could make this function even more generic 378 00:16:19,800 --> 00:16:22,680 by passing some kind of string into there. 379 00:16:22,680 --> 00:16:24,960 So I'd leave that as an exercise for you to do. 380 00:16:24,960 --> 00:16:26,686 What I will do though is, 381 00:16:26,686 --> 00:16:31,260 is it worthwhile just getting rid of that variable 382 00:16:31,260 --> 00:16:33,900 and just putting the number one here? 383 00:16:33,900 --> 00:16:35,280 Maybe actually. 384 00:16:35,280 --> 00:16:38,943 Sometimes less is more, so I could put five in there, 385 00:16:40,650 --> 00:16:42,600 and then leave it like that. 386 00:16:42,600 --> 00:16:45,870 So I'm not sure whether I'd prefer that 387 00:16:45,870 --> 00:16:47,460 or whether I prefer this. 388 00:16:47,460 --> 00:16:52,050 Having name variables sometimes can make it more explicit. 389 00:16:52,050 --> 00:16:55,410 So, you know, it's a decision to make, 390 00:16:55,410 --> 00:16:57,607 but anyway, it is an improvement, isn't it? 391 00:16:57,607 --> 00:17:00,205 You can see that we definitely have reduced duplication, 392 00:17:00,205 --> 00:17:02,460 and it means I've gotta, 393 00:17:02,460 --> 00:17:05,940 I can test that function once in isolation. 394 00:17:05,940 --> 00:17:07,540 And that's a good thing as well.