WEBVTT 00:00.480 --> 00:01.080 Hello. 00:01.170 --> 00:07.220 We are now at the last video of this section observe a design pattern in the previous video. 00:07.260 --> 00:10.790 We looked at mediator design pattern in this video. 00:10.830 --> 00:16.660 We will develop the simplest possible application to fully understand the roots of the observer pattern. 00:16.710 --> 00:21.960 We are going to make a publisher struct which is one that triggers an event so it must accept new observers 00:22.260 --> 00:24.210 and remove them if necessary. 00:24.360 --> 00:29.670 When the publisher struct is triggered it must notify all its observers of the new event with the data 00:29.700 --> 00:31.390 associated. 00:31.470 --> 00:38.280 We will finish the common gang of four design patterns with my favorite the observer pattern also known 00:38.280 --> 00:42.780 as publish subscriber or publish listener with the state pattern. 00:42.780 --> 00:48.360 We defined our first event driven architecture but with the observer pattern we will really reach a 00:48.360 --> 00:50.340 new level of abstraction. 00:50.520 --> 00:56.130 So the idea behind the observer pattern is simple to subscribe to some events that will trigger some 00:56.130 --> 00:59.480 behavior on many subscribed types. 00:59.490 --> 01:01.140 Why is this so interesting. 01:01.140 --> 01:07.850 Because we uncouple an event from its possible handlers for example imagine a log in button. 01:08.130 --> 01:14.770 We could code that when the user clicks the button the button color changes and action is executed and 01:14.770 --> 01:17.090 the form check is performed in the background. 01:17.340 --> 01:23.190 But with the observer pattern the type that changes the color will subscribe to the event of the clicking 01:23.190 --> 01:24.120 of the button. 01:24.300 --> 01:30.450 The type that checks the form and the type that performs an action will subscribe to this event to the 01:30.450 --> 01:35.430 observer pattern is especially useful to achieve many actions that are triggered on one event. 01:35.430 --> 01:40.890 It is also especially useful when you don't know how many actions are performed after an event in advance 01:41.100 --> 01:47.010 or there is a possibility that the number of actions is going to grow in the near future to resume. 01:47.010 --> 01:53.640 Do these steps First provide an event driven architecture where one event can trigger one or more actions 01:54.210 --> 01:58.160 and uncoupled the actions that are performed from the events that triggers them. 01:58.230 --> 02:05.050 Provide more than one event that triggers the same action the requirements must tell us to have some 02:05.050 --> 02:08.440 type that trigger some method in one or more actions. 02:08.440 --> 02:14.260 So we must have a publisher with a notify observer's method that accepts a message as an argument and 02:14.260 --> 02:18.650 triggers a notify me method on every observer subscribed. 02:18.670 --> 02:22.720 Next we must have a method to add new subscribers to the publisher. 02:22.720 --> 02:27.840 Lastly we must have a method to remove new subscribers from the publisher. 02:27.840 --> 02:30.570 Now let's move on to the unit tests. 02:30.570 --> 02:36.560 Maybe you have realized that our requirements defined almost exclusively the publisher type. 02:36.570 --> 02:41.370 This is because the action performed by The Observer is irrelevant for the observer pattern. 02:41.430 --> 02:43.770 It should simply execute an action. 02:43.770 --> 02:47.940 In this case the notify method that one or many types will implement. 02:48.000 --> 02:51.560 So let's define this only interface for this pattern. 02:51.570 --> 02:55.790 Open the observer dot go file and add these lines of code. 02:55.980 --> 02:59.180 I have declared the package name and the observer interface. 02:59.370 --> 03:04.530 The Observer interface has a notify method that accepts a string type that will contain the message 03:04.530 --> 03:05.670 to spread. 03:05.670 --> 03:11.100 It does not need to return anything but we could return an error if we want to check if all observers 03:11.100 --> 03:16.980 have been reached when calling the publish method of the publisher structure to test all the acceptance 03:16.980 --> 03:17.910 criteria. 03:17.910 --> 03:21.870 We just need a structure called publisher with three methods. 03:21.870 --> 03:24.250 So let's create these three methods. 03:24.420 --> 03:30.790 The publisher structure stores the list of subscribed observers in a slice field called Observer's list. 03:30.990 --> 03:34.860 Then it has the three methods mentioned in the acceptance criteria. 03:34.860 --> 03:38.870 The ad observer method to subscribe a new observer to the publisher. 03:38.940 --> 03:45.810 The remove observer method to unsubscribe an observer and notify observers method with a string that 03:45.930 --> 03:49.580 acts as the message we want to spread between all observers. 03:49.860 --> 03:55.950 With these three methods we have to set up a route test to configure the publisher and three sub tests 03:56.100 --> 03:57.990 to test each method. 03:57.990 --> 04:03.420 We also need to define a test type structure that implements the observer interface. 04:03.420 --> 04:10.020 This structure is going to be called Test observer save this file and go to the Observer underscore 04:10.050 --> 04:12.420 test dot go file. 04:12.420 --> 04:15.440 Let's add the test observer struct here. 04:15.630 --> 04:21.330 The test observer structure implements the observer pattern by defining a notify string method in its 04:21.330 --> 04:22.470 structure. 04:22.500 --> 04:28.920 In this case it prints the receive message together with its own observer I.D. then it stores the message 04:28.920 --> 04:30.570 in its message field. 04:30.570 --> 04:34.650 This allows us to check later if the content of the message field is expected. 04:34.650 --> 04:40.830 Remember that it could also be done bypassing the testing dot t pointer and the expected message and 04:40.830 --> 04:43.560 checking within the test observer structure. 04:43.560 --> 04:47.150 Now we can set up the publisher structure to execute the three tests. 04:47.310 --> 04:51.560 We will create three instances of the test observer structure. 04:51.560 --> 04:52.620 Let's do it. 04:52.620 --> 04:59.930 Also let me add the publisher we have given a different idea to each observer so that we can see later 04:59.930 --> 05:03.200 that each of them has printed the expected message. 05:03.200 --> 05:09.140 Then we have added the observers by calling the ad observer method on the publisher structure. 05:09.330 --> 05:11.810 Let us write an ad observer test. 05:11.990 --> 05:17.190 It must add a new observer to the Observer's list field of the publisher structure. 05:17.270 --> 05:22.460 We have added three observers to the publisher structure so the length of the slice must be three. 05:22.640 --> 05:29.300 If its not three the test will fail the remove observer test will take the observer with I.D. 2 and 05:29.300 --> 05:31.130 remove it from the list. 05:31.130 --> 05:35.120 So next we add the remove observer test cool. 05:35.120 --> 05:40.690 After removing the second observer the length of the publisher structure must now be two. 05:40.730 --> 05:46.050 We also check that none of the observers left have the I.D. too because it must be removed. 05:46.160 --> 05:51.440 The last method to test is the notify method when using the notify method. 05:51.440 --> 05:58.220 All instances of Test observer structure must change their message field from empty to the past message 05:58.460 --> 06:01.170 which is hello world in this case. 06:01.250 --> 06:06.460 First we will check that all the message fields are in fact empty before calling the notify. 06:06.460 --> 06:08.300 Observers test. 06:08.300 --> 06:09.980 Let's add the code for this. 06:10.310 --> 06:16.470 Using a false statement we are iterating over the Observer's list field to slice in the publisher instance. 06:16.580 --> 06:22.700 We need to make a type casting from a pointer to an observer to a pointer to the test observer structure 06:23.000 --> 06:26.060 and check that the casting has been done correctly. 06:26.060 --> 06:29.540 Then we check that the message field is actually empty. 06:29.540 --> 06:32.580 The next step is to create a message to send. 06:32.600 --> 06:38.480 In this case it will be hello world and then pass the message to the notify observers method to notify 06:38.570 --> 06:40.400 every observer on the list. 06:40.400 --> 06:43.250 Currently observers 1 and 3 only. 06:43.940 --> 06:45.620 So here's the code. 06:45.620 --> 06:46.850 Okay. 06:46.850 --> 06:49.100 After calling the notify observers method. 06:49.130 --> 06:55.490 Each test observer tests in the Observer list field must have the message Hello World stored in their 06:55.490 --> 06:56.880 message field. 06:56.990 --> 07:03.770 Again we use a for loop to iterate over every observer of the observers list field and we typecast each 07:03.830 --> 07:05.840 to a test observer test. 07:05.840 --> 07:10.970 Remember that test observer structure doesn't have any field as it's an interface. 07:10.970 --> 07:17.120 We could avoid typecasting by adding a new message method to observer instance and implementing it in 07:17.120 --> 07:21.470 the test observer structure to return the contents of the message field. 07:21.470 --> 07:23.770 Both methods are equally valid. 07:23.900 --> 07:30.170 Once we have typecast it to a test observer method called Print observe a variable as a local variable. 07:30.260 --> 07:35.990 We check that each instance in the Observer lists structure has the string Hello World stored in their 07:35.990 --> 07:37.430 message field. 07:37.580 --> 07:43.550 It's time to run the tests that must fail all to check their effectiveness in later implementation. 07:43.550 --> 07:52.670 Save the file and move to the terminal run the command go test hyphen v something isn't working as expected. 07:52.730 --> 07:55.560 How is the notify method passing the test. 07:55.640 --> 08:01.400 If we haven't implemented the function yet take a look at the test of the notify method again. 08:01.400 --> 08:08.740 Right over here the test iterate over the observers list structure and each failed call is inside this 08:08.740 --> 08:09.860 for loop. 08:10.030 --> 08:16.010 If the list is empty it won't iterate so it won't execute any failed call. 08:16.210 --> 08:22.990 Let's fix this issue by adding a small non empty list check at the beginning of the notify test done 08:23.410 --> 08:30.640 save the file and now we will rerun the tests to see if the test subject or notify method is already 08:30.640 --> 08:31.090 failing 08:36.200 --> 08:36.620 nice. 08:36.950 --> 08:41.090 All of them are failing and now we have some guarantees on our tests. 08:41.090 --> 08:43.580 We can proceed to the implementation. 08:44.000 --> 08:51.150 Our implementation is just to define the add observer the remove observer and notify observers methods. 08:51.180 --> 08:52.680 Let's open the observer dots. 08:52.700 --> 08:56.240 Go file and modify the add observer method. 08:56.510 --> 09:02.030 The add observer method adds The Observer instance to the observers list structure by appending the 09:02.030 --> 09:04.710 pointer to the current list of pointers. 09:04.730 --> 09:06.250 This one was very easy. 09:06.320 --> 09:10.370 The add observer test must be passing now but not the rest. 09:10.370 --> 09:15.870 Or we could have done something wrong now saved the file and moved to the terminal to run the test. 09:16.040 --> 09:17.390 Go test hyphen V. 09:18.200 --> 09:19.040 Whoops. 09:19.040 --> 09:23.030 We don't need to include f empty in the import statement. 09:23.030 --> 09:25.430 Let's add it as a comment for now. 09:25.430 --> 09:29.420 Fine let's save the file and again run the test. 09:29.420 --> 09:30.420 Excellent. 09:30.470 --> 09:37.780 Just the add observer method has passed the test so we can now continue to remove observer method. 09:37.800 --> 09:42.200 Let's go back to our file and now modify the remove observer method. 09:42.200 --> 09:43.340 Perfect. 09:43.610 --> 09:49.100 Remove observer method will iterate for each element in the Observer's list structure comparing the 09:49.100 --> 09:55.580 observer Object o variable with the one stored in the list if it finds a match it saves the index in 09:55.580 --> 10:00.470 the local variable index to remove and stops the iteration. 10:00.710 --> 10:05.300 The way to remove index is on a slice and go is a bit tricky. 10:05.300 --> 10:11.030 First we need to use slice indexing to return a new slice containing every object from the beginning 10:11.030 --> 10:12.560 of the slice to the index. 10:12.560 --> 10:19.390 We want to remove that is not included then we get another slice from the index we want to remove not 10:19.390 --> 10:22.000 included to the last object in the slice. 10:22.000 --> 10:25.580 Finally we joined the previous two slices into a new one. 10:25.690 --> 10:31.810 That is the append function for example in a list from one to 10 in which we want to remove the number 10:31.810 --> 10:34.220 five we have to create a new slice. 10:34.330 --> 10:41.450 Joining a slice from 1 to 4 and a slice from 6 to 10 this index removal is done with the append function 10:41.450 --> 10:45.110 again because we are actually appending two lists together. 10:45.110 --> 10:50.030 Just take a closer look at the three dots at the end of the second argument of the append function. 10:50.270 --> 10:52.550 The append function adds an element. 10:52.550 --> 10:58.270 The second argument to a slice which is the first but we want to spend an entire list. 10:58.340 --> 11:03.920 This can be achieved using the three dots which translate to something like keep adding elements until 11:03.920 --> 11:06.230 you finish the second array. 11:06.260 --> 11:09.010 Okay let's run this test now. 11:09.380 --> 11:11.420 We continue in the good path. 11:11.550 --> 11:15.810 The remove observer test has been fixed without fixing anything else. 11:15.830 --> 11:21.310 Now we have to finish our implementation by defining the notify observers method. 11:21.380 --> 11:27.050 Let's go back to the Observer dot go file and this time we modify the notify observer method. 11:27.050 --> 11:30.320 And since we are using f empty we need to on comment. 11:30.320 --> 11:36.530 The import statement the notify observers method is quite simple because it prints a message to the 11:36.530 --> 11:41.520 console to announce that a particular message is going to be passed to the observers. 11:41.540 --> 11:48.170 After this we use a for loop to iterate over Observer's list structure and execute each notify string 11:48.170 --> 11:52.920 method by passing the argument M after executing this. 11:53.030 --> 11:59.780 All observers must have the message Hello World stored in their message field saved the file again and 11:59.780 --> 12:02.100 navigate to the terminal. 12:02.140 --> 12:05.390 Let's see if this is true by running the tests. 12:05.390 --> 12:06.440 Excellent. 12:06.440 --> 12:11.360 We can also see the outputs of the publisher and observer types on the console. 12:11.360 --> 12:17.300 The publisher structure prints the message hey I have received the message Hello World and I'm going 12:17.300 --> 12:20.000 to pass the same message to the observers. 12:20.090 --> 12:23.570 After this all observers print their respective messages. 12:23.570 --> 12:31.040 Hey I'm observer one and I've received the message Hello World and the same for the third observer in 12:31.040 --> 12:37.670 this section we have unlocked the power of event driven architectures with the state pattern and the 12:37.670 --> 12:39.140 observer pattern. 12:39.140 --> 12:45.050 Now you can really execute asynchronous algorithms and operations in your application that respond to 12:45.050 --> 12:51.920 events in your system the observer pattern is commonly used in you eyes Android programming is filled 12:51.920 --> 12:57.920 with Observer patterns so that the Android SDK can delegate the actions to be performed by the programmers 12:57.950 --> 12:59.570 creating an app. 12:59.750 --> 13:04.680 So we had a wonderful journey exploring the behavioral design patterns. 13:04.780 --> 13:10.250 I am sure you had fun with go and these concepts have strengthened your programming knowledge. 13:10.280 --> 13:16.760 I hope to see you in our next part go concurrency patterns where we will dive into some advanced design 13:16.760 --> 13:20.720 patterns in go till then goodbye. 13:20.720 --> 13:21.440 Let's go.