1 00:00:00,130 --> 00:00:03,320 Now let's see how this whole thing works in practice by 2 00:00:03,320 --> 00:00:06,800 using an example. We're going to consider a program that takes as 3 00:00:06,800 --> 00:00:10,450 input a text file and produce it as output, a filtered 4 00:00:10,450 --> 00:00:14,170 file. So basically it outputs a subset of the content of 5 00:00:14,170 --> 00:00:16,928 this text file based on some filter. And we're going to have 6 00:00:16,928 --> 00:00:19,440 four different types of filters. So the first one is 7 00:00:19,440 --> 00:00:21,680 not filtering which means that the whole content of the text 8 00:00:21,680 --> 00:00:25,320 file will be produced on the output. The second filter will output 9 00:00:25,320 --> 00:00:27,990 only words that starts with t. So you'll take the text file 10 00:00:27,990 --> 00:00:30,540 and simply ignore all of the words that do not start with 11 00:00:30,540 --> 00:00:33,130 t. So in the output we'll have only those words that starts 12 00:00:33,130 --> 00:00:36,030 with letter t. The third filter will produce in the output only 13 00:00:36,030 --> 00:00:39,180 words that are longer than five characters. So all the other words 14 00:00:39,180 --> 00:00:43,740 will be simply disregarded. And finally, the four filter will produce as 15 00:00:43,740 --> 00:00:47,630 output only words in the text file that are palindromes, and in 16 00:00:47,630 --> 00:00:50,590 case you don't know what a palindrome is, a palindrome is a word 17 00:00:50,590 --> 00:00:52,700 that is the same whether you read it from left 18 00:00:52,700 --> 00:00:55,800 to right or from right to left. For example, the 19 00:00:55,800 --> 00:00:58,480 word kayak, you can read it in this direction, or 20 00:00:58,480 --> 00:01:00,740 in this direction, and it's exactly the same word. So 21 00:01:00,740 --> 00:01:03,560 let's see how this program could be implemented using a 22 00:01:03,560 --> 00:01:05,980 strategy pattern. And let's do it for real as a 23 00:01:05,980 --> 00:01:10,100 demo. What we're looking at here is the editor page 24 00:01:10,100 --> 00:01:15,520 for Eclipse, open with the strategy pattern implementation for our example. 25 00:01:15,520 --> 00:01:17,130 So what I'm going to do is that, I'm going to look at a 26 00:01:17,130 --> 00:01:20,310 different part of implementation. And you will see that, you know, despite 27 00:01:20,310 --> 00:01:23,420 the fact that it's slightly longer, it's really fairly simple, it's kind 28 00:01:23,420 --> 00:01:26,230 of a straightforward implementation of what we just saw. As I just 29 00:01:26,230 --> 00:01:29,820 said, what we are doing is basically building the strategy patterns that 30 00:01:29,820 --> 00:01:34,330 allows for changing the strategies with which we're filtering an input file. 31 00:01:34,330 --> 00:01:37,380 And we have different strategies, we'll look at those in detail, and 32 00:01:37,380 --> 00:01:41,050 we said that the three participants for this pattern are the context, 33 00:01:41,050 --> 00:01:43,650 the algorithm, which is the general interface and then the concrete 34 00:01:43,650 --> 00:01:47,270 strategies, which are the concrete implementations of this algorithm. So let's 35 00:01:47,270 --> 00:01:49,790 start by looking at the context. Which is this class here. 36 00:01:49,790 --> 00:01:52,960 And as you can see it contains a reference at the current 37 00:01:52,960 --> 00:01:56,240 strategy. We call this the check strategy, which is basically our 38 00:01:56,240 --> 00:01:59,910 filter, and when the context is created by default it sets a 39 00:01:59,910 --> 00:02:02,890 strategy to the old strategy. The old strategy is the one 40 00:02:02,890 --> 00:02:06,380 that accepts all the input, so basically it doesn't filter out anything. 41 00:02:06,380 --> 00:02:08,320 And we said that the context is the interface to the 42 00:02:08,320 --> 00:02:10,889 outside world, right? So it has to provide the outside world 43 00:02:10,889 --> 00:02:14,140 with a way of selecting the strategy, the specific algorithm to 44 00:02:14,140 --> 00:02:16,850 be used, and it does that in this case by providing 45 00:02:16,850 --> 00:02:21,360 this change strategy method. This method takes a strategy as input, 46 00:02:21,360 --> 00:02:24,930 and simply replaces the current strategy with the one specified as 47 00:02:24,930 --> 00:02:28,035 a parameter. And at this point, the context also will perform 48 00:02:28,035 --> 00:02:31,830 the filtering. The filtering is pretty straightforward, so what it does is 49 00:02:31,830 --> 00:02:34,620 that it opens a file that is passed as a parameter 50 00:02:34,620 --> 00:02:37,450 so that this the file, the input file to be filtered. And 51 00:02:37,450 --> 00:02:40,560 then it reads the file line by line and then splits 52 00:02:40,560 --> 00:02:43,620 the lines into its composing words and then for each word in 53 00:02:43,620 --> 00:02:46,480 each line, what it will do, it will basically invoke the 54 00:02:46,480 --> 00:02:50,270 check method in the current strategy, which is basically the filtering method 55 00:02:50,270 --> 00:02:53,580 and if the check method returns true, which basically means that 56 00:02:53,580 --> 00:02:57,150 the word should be printed, it prints the word. Otherwise, it'll just 57 00:02:57,150 --> 00:03:00,480 skip it. So basically the filter will return false for all the 58 00:03:00,480 --> 00:03:03,470 words that have to be filtered out. Okay? This is the basic 59 00:03:03,470 --> 00:03:06,770 way in which context works. Let's see how this is used in 60 00:03:06,770 --> 00:03:10,660 our main method. The main method simply creates the context, reads the input file 61 00:03:10,660 --> 00:03:12,910 from the arguments, and then what he does is simply as a 62 00:03:12,910 --> 00:03:16,720 demonstration, it will perform the filtering using all the different filters. So 63 00:03:16,720 --> 00:03:19,310 starting from the default one, which is the one that basically doesn't 64 00:03:19,310 --> 00:03:22,150 do any filtering that reports all words, then it will switch to the 65 00:03:22,150 --> 00:03:25,400 algorithm, that only considers the words that start with t, and 66 00:03:25,400 --> 00:03:28,880 it will do that by invoking a change strategy and passing this 67 00:03:28,880 --> 00:03:30,890 strategy as the argument, and then 68 00:03:30,890 --> 00:03:32,760 performing the actual filtering through context. 69 00:03:32,760 --> 00:03:35,040 And it will do exactly the same for the strategy that only 70 00:03:35,040 --> 00:03:37,540 prints words that are longer than five and the one that 71 00:03:37,540 --> 00:03:40,460 only prints words that are palindromes. So now let's look at the 72 00:03:40,460 --> 00:03:44,090 actual algorithm. This is the interface, the algorithm interface. And you can 73 00:03:44,090 --> 00:03:47,080 see that the only thing that the interface provides is this method, 74 00:03:47,080 --> 00:03:49,760 which is the check method, that takes a string as input and will 75 00:03:49,760 --> 00:03:52,470 return a boolean. So, basically, it's the boolean that we were seeing before. 76 00:03:52,470 --> 00:03:55,010 The one that is true for the words that have to be printed 77 00:03:55,010 --> 00:03:57,490 and false for the ones that have to be filtered out. Now, we have 78 00:03:57,490 --> 00:04:01,250 all the different implementations of the algorithm, the simplest one is the all 79 00:04:01,250 --> 00:04:05,110 algorithm, the simple return is always true, so all the words will be printed. 80 00:04:05,110 --> 00:04:08,740 The second one starts with t, and again, without looking at the details 81 00:04:08,740 --> 00:04:10,660 of implementations that don't really matter, what 82 00:04:10,660 --> 00:04:12,390 it does is basically check that 83 00:04:12,390 --> 00:04:15,111 the first character is t, and returns true in that case and 84 00:04:15,111 --> 00:04:17,720 false otherwise. Similarly, for the LongerThan5 85 00:04:17,720 --> 00:04:19,380 algorithm, also in this case, this 86 00:04:19,380 --> 00:04:23,000 will implement the check strategy interface, and the check will be performed 87 00:04:23,000 --> 00:04:25,980 by checking that the word is longer than five characters and returning 88 00:04:25,980 --> 00:04:29,440 true in that case and false otherwise. And finally the Palindrome check 89 00:04:29,440 --> 00:04:32,240 is a little more complicated, but basically it just checks whether the 90 00:04:32,240 --> 00:04:35,190 word is a Palindrome and returns true in that case. Okay, so 91 00:04:35,190 --> 00:04:37,950 as I said, it doesn't really matter too much what is the specific 92 00:04:37,950 --> 00:04:40,630 implementations of these matters. What matters is that we have 93 00:04:40,630 --> 00:04:44,150 a general interface for the algorithm and then any different concrete 94 00:04:44,150 --> 00:04:48,130 implementations of the algorithm that implement different strategies. So again, 95 00:04:48,130 --> 00:04:50,730 this allows you to change the behavior of your class without 96 00:04:50,730 --> 00:04:53,420 changing class. So we have this context class that does 97 00:04:53,420 --> 00:04:57,015 different things when the filter method in invoked, depending on what 98 00:04:57,015 --> 00:04:59,930 is the current strategy. So the behavior of the class can 99 00:04:59,930 --> 00:05:03,310 change dynamically, and it changes dynamically every time that we change 100 00:05:03,310 --> 00:05:06,300 the strategy. At this point, the way this whole thing works should 101 00:05:06,300 --> 00:05:08,430 be clear, so what we're going to do is that we're going to go to 102 00:05:08,430 --> 00:05:12,010 our console, and we're actually going to run the strategy pattern and see 103 00:05:12,010 --> 00:05:15,710 what happens. So here I have a file, it's called foo.txt. And if 104 00:05:15,710 --> 00:05:18,290 we look at the content of foo, you can see that it 105 00:05:18,290 --> 00:05:21,190 says that this is just a test to assess how well this program 106 00:05:21,190 --> 00:05:24,430 performs when used on files of text. And since it checks for 107 00:05:24,430 --> 00:05:28,560 palindromes, we will also insert one such word, level. Level is a palindrome, 108 00:05:28,560 --> 00:05:31,042 because you can read it from both sides. Okay, so let's 109 00:05:31,042 --> 00:05:33,657 see what happens when we run our code. So we're going to 110 00:05:33,657 --> 00:05:36,900 run java pattern.strategy.StrategyPattern which is 111 00:05:36,900 --> 00:05:38,550 our class, and we going to fetch 112 00:05:38,550 --> 00:05:41,460 foo.txt as an input, and let's go back to the beginning 113 00:05:41,460 --> 00:05:43,980 of the output to see what happened exactly. You can see 114 00:05:43,980 --> 00:05:48,040 here that for the default strategy, which was the old strategy, 115 00:05:48,040 --> 00:05:50,810 the whole file is printed, so every word is printed. This 116 00:05:50,810 --> 00:05:53,485 is just a test to assess and so on and so forth, 117 00:05:53,485 --> 00:05:57,290 as expected. For the filter that only prints words that 118 00:05:57,290 --> 00:06:00,230 start with t, only words that start with t are printed, 119 00:06:00,230 --> 00:06:04,180 again, as expected. Similarly, for the filter that only prints words 120 00:06:04,180 --> 00:06:06,970 that are longer than 5, and finally for the one that prints 121 00:06:06,970 --> 00:06:09,540 palindromes. And here you can see that we actually have two 122 00:06:09,540 --> 00:06:12,410 because the way in which this is implemented we'll also consider 123 00:06:12,410 --> 00:06:15,300 single letter words as palindromes because you can read them from 124 00:06:15,300 --> 00:06:18,450 both sides. But you definitely will also have level in the output. 125 00:06:18,450 --> 00:06:21,040 And in case you want to play with this code yourself, I 126 00:06:21,040 --> 00:06:24,600 have made this code and also the implementation for examples of other 127 00:06:24,600 --> 00:06:28,440 design partners available as a compressed archive. And the archive is accessible 128 00:06:28,440 --> 00:06:31,120 through a URL that is provided in the notes for the cost.