WEBVTT 00:00.480 --> 00:01.060 Hello. 00:01.140 --> 00:07.890 Welcome to the first section of our video course strategy chain of responsibility and command design 00:07.890 --> 00:10.110 patterns in this section. 00:10.170 --> 00:15.750 We will first start with the strategy design pattern and then move on to the chain of responsibility 00:15.750 --> 00:17.220 design pattern. 00:17.220 --> 00:21.180 At the end we will dive into the command design pattern. 00:21.180 --> 00:27.150 Now let's move on to the first video of this section that deals with strategy design pattern. 00:27.360 --> 00:33.840 In this video we're going to paint objects on a file instead of only printing text on the console. 00:33.840 --> 00:39.660 We will have two strategies console and file but the user of the library won't have to deal with the 00:39.660 --> 00:41.760 complexity behind them. 00:41.790 --> 00:47.970 Now we aren't going to define structures or encapsulate object creation but we are going to deal with 00:47.970 --> 00:51.930 behaviors wants to deal with in behavior patterns. 00:51.930 --> 00:59.010 Well now we will encapsulate behaviors for example algorithms in the strategy pattern or executions 00:59.010 --> 01:03.390 in the Command pattern correct behavior design is the last step. 01:03.480 --> 01:09.840 After knowing how to deal with object creation and structures defining the behavior correctly is the 01:09.840 --> 01:15.720 last step of good software design because all in all good software design lets us improve algorithms 01:15.900 --> 01:23.370 and fix errors easily while the best algorithm implementation will not save us from bad software design. 01:23.370 --> 01:26.430 Now let's talk about strategy design pattern. 01:26.430 --> 01:32.240 So the strategy design pattern is probably the easiest to understand of the behavioral patterns. 01:32.320 --> 01:37.470 We've used it a few times while developing the previous patterns but without stopping to talk about 01:37.470 --> 01:44.720 it now we will the strategy pattern uses different algorithms to achieve some specific functionality. 01:44.760 --> 01:50.350 Those algorithms are hidden behind an interface and of course they must be interchangeable. 01:50.760 --> 01:54.540 All algorithms achieve the same functionality in a different way. 01:54.540 --> 01:59.310 For example we could have a sort interface and a few sorting algorithms. 01:59.310 --> 02:00.610 The result is the same. 02:00.720 --> 02:05.120 Some list is sorted but we could have used quick sort merge sort. 02:05.190 --> 02:06.290 And so on. 02:06.600 --> 02:12.920 The IO dot writer interface defines a strategy to write and the functionality is always the same. 02:12.990 --> 02:19.740 To write something we could write it to the standard out to some file or to a user defined type but 02:19.740 --> 02:22.770 we do the same thing at the end to write. 02:22.770 --> 02:24.640 We just changed the strategy to write. 02:24.690 --> 02:30.690 And in this case we changed the place where we write now the object of the strategy pattern is really 02:30.690 --> 02:37.740 clear the pattern should do these two tasks it should provide a few algorithms to achieve some specific 02:37.740 --> 02:38.960 functionality. 02:38.970 --> 02:44.850 Secondly all types must achieve the same functionality in a different way but the client of the strategy 02:44.850 --> 02:46.400 shouldn't be affected. 02:46.410 --> 02:51.330 The problem is that this definition covers a huge spectrum of possibilities. 02:51.330 --> 02:57.120 This is because Strategy Pattern is actually used for a variety of scenarios and many software engineering 02:57.120 --> 03:00.580 solutions come with some kind of strategy within. 03:00.630 --> 03:04.640 Therefore it's better to see it in action with a real example. 03:04.740 --> 03:07.460 As I said earlier we are going to do something different. 03:07.500 --> 03:13.800 For this example instead of printing text on the console only We are also going to paint objects on 03:13.800 --> 03:14.850 a file. 03:14.940 --> 03:21.000 In this case we will have two strategies console and file but the user of the library won't have to 03:21.000 --> 03:23.500 deal with the complexity behind them. 03:23.520 --> 03:29.490 The key feature is that the caller doesn't know how the underlying library is working and he just knows 03:29.490 --> 03:33.010 the information available on the defined strategy. 03:33.030 --> 03:36.530 This is nicely seen on the diagram which you see on your screen. 03:37.590 --> 03:42.810 In this diagram we have chosen to print the console but we won't deal with the console strategy type 03:42.810 --> 03:46.870 directly will always use an interface that represents it. 03:47.070 --> 03:52.530 The console strategy type will hide the implementation details of printing the console to color in main 03:52.530 --> 03:59.040 function bios strategy hides its implementation details as well as any future strategy. 03:59.220 --> 04:06.370 Now before getting our hands on some code let's understand the acceptance criteria a strategy must have 04:06.370 --> 04:10.300 a very clear objective and we will have two ways to achieve it. 04:10.300 --> 04:13.140 Our objectives are as listed on your screen. 04:13.390 --> 04:20.140 The first one is provide a way to show the user an object that is square in text or image. 04:20.140 --> 04:26.170 Next the user must choose between image or text when launching the app and then the app must be able 04:26.170 --> 04:31.000 to add more visualization strategies like an audio for example. 04:31.000 --> 04:35.920 And if the user selects text the word square must be printed on the console. 04:36.850 --> 04:43.360 Lastly if the user selects image an image of a white square on a black background will be printed on 04:43.360 --> 04:47.190 a file now let's move into the implementation. 04:47.300 --> 04:52.370 We aren't going to write tests for this example as it will be quite complicated to check that an image 04:52.370 --> 04:59.210 has appeared on the screen although not impossible by using open CV unimpressive library for computer 04:59.210 --> 05:00.390 vision. 05:00.440 --> 05:07.070 We will start directly by defining our strategy interface that each printing strategy must implement. 05:07.250 --> 05:13.040 In our case the file and console types I have already written all the codes which we are going to use 05:13.220 --> 05:16.340 and I am going to explain step by step. 05:16.580 --> 05:18.830 So let's open the file image. 05:18.830 --> 05:20.030 Dot go. 05:20.060 --> 05:26.330 You can see that we have the type print strategy interface that's all our strategy defines a simple 05:26.330 --> 05:28.340 print method that returns an error. 05:28.460 --> 05:34.520 The error returning type is mandatory when dealing with files the types that need to implement print 05:34.520 --> 05:39.520 strategy will be called console square and image Square type. 05:39.560 --> 05:44.180 So we have named these types as console square and image square. 05:44.210 --> 05:49.840 Now the console square struct doesn't need any in our field because it will always print the word square 05:49.850 --> 05:55.850 to the console the image square struct will store a field for the destination of the image file where 05:55.850 --> 05:57.650 we will print the square. 05:57.800 --> 06:03.610 We start with the implementation of the console Square type as it is the simplest. 06:03.690 --> 06:09.900 Next we have defined function C very easy but the image is more complex. 06:09.900 --> 06:14.880 We won't spend too much time and explaining in detail how the image package works because the code is 06:14.970 --> 06:17.090 easily understandable. 06:17.130 --> 06:19.680 However here is a short explanation. 06:19.830 --> 06:22.890 We define a size for the image width and height. 06:22.890 --> 06:28.360 Variables of 800 pixels of width and 600 pixels of height. 06:28.410 --> 06:30.980 Those are going to be the size limits of our image. 06:31.020 --> 06:35.040 And anything we write outside of that size won't be visible. 06:35.040 --> 06:41.940 The origin variables stores an image dot point a type to represent a position in any two dimensional 06:41.940 --> 06:42.860 space. 06:42.930 --> 06:49.000 We set the position of this point at zero comma zero the upper left corner of the image. 06:49.140 --> 06:52.530 We need a bitmap that will represent our background. 06:52.530 --> 06:55.370 Here we call it B G image. 06:55.620 --> 06:59.130 We have a very handy function in the image package to create the image. 06:59.130 --> 07:05.200 Dot are GBI types called Image dot new R GPA. 07:05.220 --> 07:11.220 We need to pass a rectangle to this function so that it knows the bounds of the image a rectangle is 07:11.220 --> 07:13.940 represented by two image dot point types. 07:13.980 --> 07:19.590 It's upper left corner point which is the main field and it's lower right corner point. 07:19.650 --> 07:27.360 That is the max field we use origins the upper left and new point with the values of width and height 07:27.570 --> 07:29.780 as the lower right point. 07:29.910 --> 07:33.860 The image will have a gray background color that is B G color. 07:33.900 --> 07:40.380 This is done by instances a type of image dot uniform which represents a uniform color hence the name 07:41.010 --> 07:47.460 the image dot the uniform type needs an instance of a color dot color interface a color dot color type 07:47.640 --> 07:57.900 is any type that implements the RGA method that is our GP a u i n t 32 method to return a u i n t 32 07:57.900 --> 08:05.730 value for red green blue and Alpha colors Alpha is a value for the transparency of a pixel the color 08:05.730 --> 08:13.320 package conveniently provides a type called Color dot R GPA for this purpose when storing an image in 08:13.320 --> 08:19.020 certain formats we have to specify the quality of the image it will affect not only the quality but 08:19.020 --> 08:21.310 the size of the file of course. 08:21.510 --> 08:27.500 Here it is defined as seventy five hundred is the maximum quality possible that we can set. 08:27.750 --> 08:33.960 As you can see we are using the j peg package here to set the value of a type called options that simply 08:33.960 --> 08:35.860 stores the value of the quality. 08:35.910 --> 08:38.720 It doesn't have more values to apply. 08:38.730 --> 08:46.290 Finally the draw dot print function writes the pixels on the supplied image that is g image with the 08:46.290 --> 08:50.880 characteristics that we have defined on the bounds defined by the same image. 08:50.970 --> 08:57.550 The first argument of the draw dot print method takes the destination image where we use BGP image. 08:57.600 --> 09:02.730 The second argument is the bounds of the object to draw in the destination image. 09:02.730 --> 09:08.720 We use the same bounds of the image but we could use any other if we wanted a smaller rectangle. 09:08.730 --> 09:15.390 The third argument is the color to use to colorized the bounds the origin variable is used to tell where 09:15.390 --> 09:18.660 the upper left corner of the bounds must be placed. 09:18.660 --> 09:21.990 In this case the bounds of the same size as the image. 09:22.020 --> 09:24.630 So we need to set it to the origin. 09:24.630 --> 09:28.370 The last argument specified is the operation type. 09:28.410 --> 09:34.720 Just leave it in the draw dot as RC argument now we have to draw the square. 09:34.720 --> 09:37.820 The operation is essentially the same as to draw the background. 09:37.870 --> 09:43.760 But in this case we are drawing a square over the previously drawn P.G. image. 09:43.870 --> 09:45.590 So here's the code for it. 09:46.200 --> 09:50.900 The square is of 200 into 200 pixels of red color. 09:51.150 --> 09:54.020 When using the method add the rect type. 09:54.060 --> 09:57.120 Origin is translated to the supplied point. 09:57.150 --> 09:59.760 This is the center of the square on the image. 09:59.760 --> 10:06.180 We create an image with the square rect and call the print function on the P.G. image again to draw 10:06.180 --> 10:08.330 the red square over it. 10:08.340 --> 10:12.020 Finally we create a file to store the contents of the image. 10:12.120 --> 10:17.820 The file will be stored in the path supplied in the destination file path field of the image square 10:17.820 --> 10:19.980 struct to create a file. 10:19.980 --> 10:24.930 We use OS dot create that returns the OS dot file. 10:24.930 --> 10:27.920 As with every file it must be closed after using it. 10:27.990 --> 10:34.340 So don't forget to use the deferred keyword to ensure that you close it when the method finishes. 10:34.350 --> 10:36.190 Let's save this file. 10:36.210 --> 10:37.150 Cool. 10:37.320 --> 10:44.660 Now before we proceed let's try to find an answer to this question to defer or not to defer. 10:44.850 --> 10:51.240 Some people ask why the use of defer a tool wouldn't it be the same to simply write it without defer 10:51.300 --> 10:52.750 the end of the function. 10:52.770 --> 10:59.300 Well actually not if any error occurs during the method execution and you return this error. 10:59.400 --> 11:03.620 The close method won't be executed if it's at the end of the function. 11:03.840 --> 11:10.170 You can close the file before returning but you'll have to do it in every error check with defer. 11:10.170 --> 11:15.900 You don't have to worry about this because the deferred function is executed always with or without 11:15.960 --> 11:16.980 error. 11:16.980 --> 11:20.040 This way we ensure that the file is closed. 11:20.040 --> 11:25.290 Let's move on to the main dot go file which I have placed in the C L AI folder 11:28.210 --> 11:34.460 to parse the arguments we use the flag package we have used it before but let's recall its usage. 11:34.570 --> 11:39.220 A flag is a command that the user can pass when executing our app. 11:39.280 --> 11:45.260 We can define a flag by using the flag dot type methods defined in the flag package. 11:45.460 --> 11:49.180 We want to read the output that the user wants to use from the console. 11:49.180 --> 11:51.630 This flag will be called output. 11:51.760 --> 11:53.780 A flag can have a default value. 11:53.800 --> 11:58.660 In this case it will have the value console that will be used when printing to console. 11:58.690 --> 12:06.370 So if the user executes the program without arguments it prints to console our final step is to write 12:06.430 --> 12:07.870 the main function. 12:07.870 --> 12:13.360 Remember that the first thing to do in the main when using flags is to pass them using the flag dot 12:13.390 --> 12:14.760 pass method. 12:14.770 --> 12:17.530 It's very common to forget this step. 12:17.530 --> 12:23.300 Here we define a variable for the strategy that the user has chosen called active strategy. 12:23.410 --> 12:29.290 But check that the active strategy variable has the print strategy type so it can be populated with 12:29.440 --> 12:32.520 any implementation of the print strategy variable. 12:32.560 --> 12:39.580 We will set active strategy to new instance of text square when the user writes The hyphen hyphen output 12:39.700 --> 12:42.860 equal to console command and an image square. 12:42.910 --> 12:47.860 When we write the hyphen hyphen output equal to image command. 12:47.860 --> 12:51.580 Finally here is the design pattern execution. 12:51.580 --> 12:58.510 Our active strategy variable is a type implementing print strategy and either the text square or image 12:58.510 --> 13:00.040 square classes. 13:00.040 --> 13:05.600 The user will choose at runtime which strategy he wants to use for each particular case. 13:05.620 --> 13:11.470 Also we could have written a factory method pattern to create strategies so that the strategy creation 13:11.680 --> 13:18.880 will also be uncoupled from the main function and abstracted in a different independent package. 13:18.880 --> 13:19.810 Think about it. 13:19.810 --> 13:25.120 If we have the strategy creation in a different package it will also allow us to use this project as 13:25.120 --> 13:29.240 a library and not only as a standalone app. 13:29.290 --> 13:31.570 Now let's execute both strategies. 13:31.600 --> 13:37.210 The text Square incident will give us a square by printing the words square on the console. 13:37.330 --> 13:46.120 Save this file and navigate to the terminal type with the command go run main dot go hyphen hyphen output 13:46.210 --> 13:48.110 equal to text. 13:48.100 --> 13:51.920 So here's the output printed as square. 13:52.210 --> 13:55.930 It has worked as expected recalling how flags work. 13:55.930 --> 14:00.050 We have to use the double dash and the defined flag output. 14:00.100 --> 14:06.040 In our case when you have two options using equals and immediately writing the value for the flag or 14:06.040 --> 14:13.420 writing space and the value for the flag in this case we have defined the default value of output to 14:13.420 --> 14:14.380 the console. 14:14.380 --> 14:22.070 So the next three executions are equivalent which I am about to show let us execute the command go run 14:22.190 --> 14:31.490 main dot go hyphen Ivan output space text enter so it gives the same output as the previous command 14:32.000 --> 14:40.910 now run the third command go run main dot go again we have the same output now we have to try the file 14:40.910 --> 14:47.330 strategy as defined before the file strategy will print a red square to a file as an image with dark 14:47.360 --> 14:54.560 gray background so the next command which I'm about to execute accomplishes this task let's write go 14:54.650 --> 15:00.510 run main dot go hyphen hyphen output image. 15:00.750 --> 15:04.460 Nothing happened but everything worked correctly. 15:04.830 --> 15:06.900 This is actually bad practice. 15:06.900 --> 15:11.380 Users must always have some sort of feedback when using your app or your library. 15:11.430 --> 15:18.150 Also if they are using your code as a library maybe they have a specific format for output so it won't 15:18.150 --> 15:21.140 be nice to directly print to the console. 15:21.140 --> 15:22.830 We will solve this issue later. 15:22.920 --> 15:29.670 Right now so let's move to the temp folder and open the file image dot J P G. 15:29.790 --> 15:33.710 You can see the output with a red square and a dog gray background. 15:33.750 --> 15:34.780 Awesome. 15:34.800 --> 15:38.880 Now let's try to solve some small issues in our library. 15:38.880 --> 15:41.070 We have a few issues in our code. 15:41.070 --> 15:45.540 The first one which we need to address is it cannot be used as a library. 15:45.570 --> 15:51.030 We have critical code written in the main package that is strategy creation. 15:51.030 --> 15:55.050 Now the solution for this issue is we need to abstract the two different packages. 15:55.080 --> 15:59.030 The strategy creation from the command line application. 15:59.130 --> 16:03.820 Secondly none of the strategies are doing any logging to file or console. 16:03.840 --> 16:09.480 We must provide a way to read some logs that an external user can integrate in their logging strategies 16:09.480 --> 16:11.010 or formats. 16:11.010 --> 16:18.360 The solution to this one is inject an IO dot writer interface as dependency to act as a logging sink 16:19.110 --> 16:25.230 and the last issue is that our text square class is always writing to the console and the image Square 16:25.230 --> 16:27.510 is always writing to file. 16:27.510 --> 16:34.710 This is to coupled for this we can inject an IO dot writer interface so that the text square and image 16:34.710 --> 16:41.700 square can write to any of the IO dot writer implementations that are available like file and console 16:41.910 --> 16:48.440 but also bytes buffer binary encoders Jason handlers dozens of packages. 16:48.720 --> 16:54.750 So to use it as a library and solve the first issue we will follow a common approach in Go file structures 16:54.750 --> 16:56.720 for apps and libraries. 16:56.790 --> 17:01.690 First we will place our main package and function outside of the root package. 17:01.710 --> 17:09.120 In this case in a folder called CLIA It is also common to call this folder see M.D. or even app. 17:09.120 --> 17:12.690 So we have our main dot go file over here. 17:12.690 --> 17:18.150 Then we have placed our print strategy interface in the root package which is now called the strategy 17:18.150 --> 17:19.200 package. 17:19.200 --> 17:25.320 Finally we create a shapes package in a folder with the same name where we will put both text and image 17:25.320 --> 17:26.540 strategies. 17:26.730 --> 17:29.470 So our file structure will be like this. 17:29.640 --> 17:33.270 First is the root package which we have named as strategy. 17:33.270 --> 17:41.160 It contains the file print strategy dot go and the sub package shapes within this contains files factory 17:41.160 --> 17:50.150 dot go image dot go and text dot go and the next sub package that is CLIA contains the file main dot 17:50.160 --> 17:51.050 go. 17:51.180 --> 17:56.500 Now we are going to modify our interface a bit to fit the needs we have written previously. 17:56.520 --> 18:05.550 Let's open the print strategy dot go we have added the set log Io dot right a method to add a logger 18:05.550 --> 18:07.470 strategy to our types. 18:07.500 --> 18:09.950 This is to provide feedback to users. 18:09.990 --> 18:15.540 Also it has a set writer method to set the IO dot writer strategy. 18:15.540 --> 18:21.180 This interface is going to be located on the route package in the print strategy dot go file so the 18:21.180 --> 18:23.760 final schema looks like this. 18:23.760 --> 18:30.480 Both the text square and image square strategies have to satisfy the set log and set writer methods 18:30.480 --> 18:36.900 which simply store some object on their fields so instead of implementing the same twice we can create 18:36.900 --> 18:41.160 a struct that implements them and embed this struct in the strategies. 18:41.160 --> 18:45.390 By the way this would be the composite pattern we have seen previously. 18:45.390 --> 18:50.430 Thus we have created a struct that includes writer and log writer both. 18:50.430 --> 18:56.310 So now each strategy must have the print output struct embedded if we want to modify their writer and 18:56.310 --> 18:57.660 logger fields. 18:57.720 --> 19:00.940 We also need to modify our strategy implementation. 19:01.080 --> 19:07.380 The text square struct now needs a field to store the output Io dot writer which is the place where 19:07.380 --> 19:08.460 it is going to write. 19:08.460 --> 19:14.520 Instead of writing always to the console and the log writer these two fields can be provided by embedding 19:14.520 --> 19:20.340 the print output struct the text square struct is also stored in the file text. 19:20.370 --> 19:28.200 Dot go within the shapes package lets open the text dot go file so the struct is now like this. 19:28.230 --> 19:33.780 So now the print method is slightly different because instead of writing directly to the console by 19:33.780 --> 19:40.140 using the print l end function we have to write whichever Io dot writer is stored in the writer field 19:41.260 --> 19:48.520 let me explain to you the next part of the code the bytes dot new reader is a very useful function that 19:48.520 --> 19:53.530 takes an array of bytes and converts them to an IO dot reader interface. 19:53.530 --> 20:00.580 We need an IO dot reader interface to use the IO dot copy function the IO dot copy function is also 20:00.580 --> 20:07.720 incredibly useful as it takes an IO dot reader as the second parameter and pipes it to an IO dot writer 20:07.900 --> 20:14.620 which is its first parameter so we won't return an error in any case however it's easier to do so using 20:14.620 --> 20:18.910 directly the right method of T dot writer. 20:19.000 --> 20:21.150 Now let's have a look at the next lines of code. 20:21.220 --> 20:26.980 What we have written the same function t in a little different way you can use whichever method you 20:26.980 --> 20:33.420 like more usually you will use the right method but it's nice to know the bytes dot new reader function 20:33.420 --> 20:34.440 too. 20:34.540 --> 20:40.830 Did you realize that when we used t dot writer we were actually accessing print output. 20:40.840 --> 20:47.530 Dot writer the text Square type has a right to field because the print output struct has it and it's 20:47.530 --> 20:50.290 embedded on the text square struct. 20:50.320 --> 20:51.960 Here's an important note for you. 20:52.030 --> 20:55.090 Remember embedding is not inheritance. 20:55.180 --> 20:59.980 We have embedded the print output struct on the text square struct. 20:59.980 --> 21:04.780 Now we can access print output fields as if they were in the text square fields. 21:04.780 --> 21:10.030 This feels a bit like inheritance but there is a very important difference here. 21:10.030 --> 21:17.110 Text square is not a print output value but it has a print output in its composition. 21:17.110 --> 21:23.620 What does it mean that if you have a function that expects a print output you cannot pass text square 21:23.860 --> 21:26.650 just because it has a print output embedded. 21:26.650 --> 21:32.860 But if you have a function that accepts an interface that the print output implements you can pass text 21:32.860 --> 21:33.520 square. 21:33.580 --> 21:38.960 If it has a print output embedded this is what we are doing in our example. 21:39.040 --> 21:40.410 Let's move on to the image. 21:40.420 --> 21:48.280 Dot go file the image square struct is now like the text square with a print output embedded the print 21:48.280 --> 21:50.770 method also needs to be modified. 21:50.800 --> 21:56.200 Now we aren't creating a file from the print method as it was breaking the Single Responsibility Principle 21:56.860 --> 21:59.440 of file implements an IO dot writer. 21:59.440 --> 22:06.160 So we will open the file outside of the image square struct and inject it on the right a field. 22:06.160 --> 22:10.390 So we just need to modify the end of the print method where we wrote to the file. 22:10.460 --> 22:15.010 Let's scroll down to the end of the file and here we are. 22:15.040 --> 22:17.760 So we need to modify this part of code. 22:17.840 --> 22:18.550 Let's do it. 22:19.120 --> 22:21.690 Let me align the code properly. 22:21.690 --> 22:22.650 Cool. 22:22.990 --> 22:29.310 If you check our previous implementation after using draw you can see that we used the print method. 22:29.440 --> 22:33.920 We created a file with OS dot to create and passed it to the JPEG dot. 22:33.980 --> 22:35.460 Encode function. 22:35.660 --> 22:40.270 We have deleted this part about creating the file and we have replaced it with a check. 22:40.270 --> 22:42.190 Looking for a writer in the fields. 22:42.520 --> 22:50.950 If I dot writer not equal to nil then on J Peg dotting code we can replace the file value we were using 22:50.950 --> 22:55.250 previously with the content of the I dot writer field. 22:55.300 --> 23:00.520 Finally we use Io dot copy again to log some message to the log writer. 23:00.520 --> 23:06.820 If a logging strategy is provided we also have to abstract the knowledge needed from the user to create 23:06.910 --> 23:13.460 instances of implementers of the print strategy for which we are going to use a factory method. 23:13.480 --> 23:16.750 Now let us navigate to the factory dot go file. 23:16.850 --> 23:18.640 Have a look at this code. 23:18.820 --> 23:22.270 We have two constants one of each of our strategies. 23:22.330 --> 23:25.670 Text strategy and image strategy. 23:25.720 --> 23:32.030 Those are the constants that must be provided to the factory to retrieve each square drawer strategy. 23:32.170 --> 23:39.110 Our factory method receives an argument s which is a string with one of the previous constants. 23:39.190 --> 23:46.600 Each strategy has a print output type embedded with a default logger to s.t. these out but you can override 23:46.600 --> 23:51.160 it later by using the set log Io dot right writer methods. 23:51.160 --> 23:56.710 This approach could be considered a factory of prototypes if it is not a recognized strategy. 23:56.710 --> 24:02.180 A proper message error will be returned what we have now is a library. 24:02.210 --> 24:06.680 We have all the functionality we need between the strategy and shaped packages. 24:06.680 --> 24:12.420 Now we will write the main package and function in a new folder called C ally. 24:12.440 --> 24:18.460 So let's save this file and move to the CLIA folder and open the main dot go file. 24:18.500 --> 24:21.800 You can see that we have defined the variable output. 24:21.800 --> 24:28.640 Let me modify this code again like before the main function starts by passing the input arguments on 24:28.640 --> 24:29.400 the console. 24:29.450 --> 24:31.640 Together the chosen strategy. 24:31.640 --> 24:37.160 Here we can use the variable output now to create a strategy without factory. 24:37.160 --> 24:42.290 With this snippet we have our strategy or we stop program execution in the log. 24:42.290 --> 24:48.060 Dot fatal method if any error is found such as an unrecognized strategy. 24:48.230 --> 24:55.250 Now we step ahead to implement the business needs by using our library for the purpose of the text strategy. 24:55.250 --> 25:02.450 We want to write for example to esti d out for the purpose of the image we write to image dot J peg 25:02.600 --> 25:04.050 in the temp folder. 25:04.190 --> 25:07.500 Just like before so we can write the code. 25:07.610 --> 25:16.390 As I added here in the case of text strategy we use set writer to set the IO dot writer to OS dot s 25:16.400 --> 25:19.780 t d out in the case of image strategy. 25:19.840 --> 25:26.140 We create an image in any of our folders and pass the file variable to the set writer method. 25:26.170 --> 25:32.680 Remember that OS dot file implements the IO dot reader and Io dot writer interfaces. 25:32.800 --> 25:37.910 So it's perfectly legal to pass it as an IO dot writer to the set writer method. 25:37.940 --> 25:39.520 There is something left. 25:39.520 --> 25:42.660 Let me add the code and show you what it is. 25:42.670 --> 25:48.370 Finally we call the print method of whichever strategy was chosen by the user and check for possible 25:48.460 --> 25:49.350 errors. 25:49.350 --> 25:55.080 Let's try the program now save the file and navigate to the command prompt. 25:55.200 --> 26:03.720 Type the command go run main dot go hyphen hyphen output text it is worked as expected you can see the 26:03.720 --> 26:13.080 output as circle what about the image strategy let's execute the command check it go run main dot go 26:13.320 --> 26:22.490 hyphen hyphen output space image enter as you can see it returns the image is written in provided writer. 26:22.670 --> 26:29.040 Now if you check in image dot JPEG file within the temp folder we can find our red square on the dark 26:29.040 --> 26:36.150 background so let's move on to the temp folder and open the image dotted JPEG file and here's the output 26:36.570 --> 26:37.920 wonderful. 26:37.920 --> 26:43.800 In this video we have learned a powerful way to encapsulate algorithms in different struct. 26:43.800 --> 26:49.830 We have also used embedding instead of inheritance to provide cross functionality between types which 26:49.830 --> 26:52.760 will come in handy very often in our apps. 26:52.800 --> 26:58.050 You'll find yourself combining strategies here and there as we have seen in the second example where 26:58.050 --> 27:04.200 we have strategies for logging and writing by using the IO dot writer interface a strategy for byte 27:04.200 --> 27:07.440 streaming operations in the next video. 27:07.500 --> 27:11.190 We will explore about the chain of responsibility design pattern.