WEBVTT 00:00.480 --> 00:06.570 We are now at the third video of this section factory method where we will be delegating the creation 00:06.570 --> 00:08.650 of different types of payments. 00:08.910 --> 00:13.730 In the previous video we looked at the builder design pattern in this video. 00:13.770 --> 00:16.570 We will implement a payment method factory. 00:16.650 --> 00:20.790 We will create two methods of paying cash and credit card. 00:20.790 --> 00:28.290 We'll also have an interface with the pay method the factory method pattern or simply factory is probably 00:28.290 --> 00:32.490 the second best known and used design pattern in the industry. 00:32.490 --> 00:38.280 Its purpose is to abstract the user from the knowledge of the struct he needs to achieve for a specific 00:38.280 --> 00:43.850 purpose such as retrieving some value maybe from a web service or a database. 00:43.850 --> 00:50.180 The user only needs an interface that provides him this value by delegating this decision to a factory. 00:50.190 --> 00:54.000 This factory can provide an interface that fits the user needs. 00:54.000 --> 00:59.970 It also eases the process of downgrading or upgrading of the implementation of the underlying type if 00:59.970 --> 01:01.290 needed. 01:01.290 --> 01:07.530 When using the factory method design pattern we gain an extra layer of encapsulation so that our program 01:07.530 --> 01:11.700 can grow in a controlled environment with the factory method. 01:11.700 --> 01:17.370 We delegate the creation of families of objects to a different package or object to abstract us from 01:17.370 --> 01:21.270 the knowledge of the pool of possible objects we could use. 01:21.270 --> 01:25.710 Imagine that you want to organize your holidays using a trip agency. 01:25.710 --> 01:30.570 You don't deal with hotels and travelling you just tell the agency the destination you are interested 01:30.570 --> 01:33.870 in so that they provide you with everything you need. 01:33.990 --> 01:39.590 The trip agency represents a factory of trips after the previous description. 01:39.630 --> 01:46.020 The objectives of the factory method design pattern must be clear to you which we have listed here. 01:46.020 --> 01:52.260 Delegating the creation of new instances of structures to a different part of the program working at 01:52.260 --> 01:58.530 the interface level instead of with concrete implementations grouping families of objects to obtain 01:58.650 --> 02:03.080 a family object creator using the previous description. 02:03.110 --> 02:08.520 The requirements for the acceptance criteria are these which you see on your screen to have a common 02:08.520 --> 02:14.790 method for every payment method called pay to be able to delegate the creation of payment methods to 02:14.790 --> 02:18.710 the factory to be able to add more payment methods to the library. 02:18.810 --> 02:21.660 Just by adding it to the factory method. 02:21.930 --> 02:27.750 Now let's move on to the first unit test a factory method has a very simple structure. 02:27.870 --> 02:32.910 We just need to identify how many implementations of our interface we are storing. 02:32.910 --> 02:35.590 Let me open the code file here. 02:35.610 --> 02:41.760 We provide a method get payment method where you can pass a type of payment as an argument. 02:41.820 --> 02:44.910 These lines define the interface of the payment method. 02:45.180 --> 02:48.120 They define a way of making a payment at the shop. 02:48.180 --> 02:55.260 The factory method will return instances of types that implement this interface we have to define the 02:55.260 --> 03:02.040 identified payment methods of the factory as constants so that we can call and check the possible payment 03:02.040 --> 03:04.730 methods from outside of the package. 03:04.770 --> 03:10.890 The highlighted code is the function that will create the object for us it returns a pointer which must 03:10.890 --> 03:16.830 have an object that implements the payment method interface and an error if asked for a method which 03:16.830 --> 03:20.480 is not registered to finish the declaration of the factory. 03:20.490 --> 03:23.130 We create the 2 payment methods. 03:23.130 --> 03:29.650 As you can see the cash PM and the debit card PM struct implement the payment method interface. 03:29.730 --> 03:32.710 By declaring a method pay amount. 03:32.710 --> 03:38.830 Float 32 string the return string will contain information about the payment. 03:38.830 --> 03:42.070 Let's save this file and go back to our factory test Dot. 03:42.180 --> 03:45.220 Go file with this declaration. 03:45.220 --> 03:50.740 We will start by writing the tests for the first acceptance criteria to have a common method to retrieve 03:50.740 --> 03:54.400 objects that implement the payment method interface. 03:54.400 --> 04:00.400 Now we have to separate the tests among a few of the test functions get the payment method is a common 04:00.400 --> 04:02.750 method to retrieve methods of payment. 04:02.830 --> 04:07.600 We use the constant cash which we have defined in the implementation file. 04:07.600 --> 04:12.050 We also check that we have not received an error when asking for a payment method. 04:12.100 --> 04:18.520 Observe that if we receive the error when asking for a payment method we call T dot beetle to stop the 04:18.520 --> 04:20.210 execution of the tests. 04:20.230 --> 04:25.930 If we called just T dot error like in the previous tests we would have a problem in the next lines when 04:25.930 --> 04:28.880 trying to access the pay method of a nil object. 04:29.050 --> 04:31.840 And our tests would crash execution. 04:31.990 --> 04:39.130 We continue by using the pay method of the interface by passing ten dot thirty as the amount the returned 04:39.130 --> 04:42.730 message will have to contain the text paid using cash. 04:42.730 --> 04:49.690 The T dot log method is a special method in testing this struct allows us to write some logs when we 04:49.690 --> 04:50.730 run the tests. 04:50.740 --> 04:56.920 If we pass the hyphen the flag we repeat the same operation with the debit card method. 04:56.920 --> 05:02.090 We asked for the payment method defined with the constant debit card and the returned message. 05:02.200 --> 05:09.410 When paying with a debit card must contain the paid using debit card string finally we are going to 05:09.410 --> 05:15.800 test the situation when we request the payment method that doesn't exist represented by the number 20 05:16.160 --> 05:19.710 which doesn't match any recognized constant in the factory. 05:19.730 --> 05:22.100 We will check if an error message is returned. 05:22.130 --> 05:28.660 When asking for an unknown payment method let us go back to the terminal and check whether all tests 05:28.750 --> 05:29.800 are failing. 05:29.920 --> 05:36.820 Now run this command as you can see in this example we can only see tests that return the payment method 05:36.860 --> 05:42.190 interface interfaces failing in this case we'll have to implement just a part of the code and then test 05:42.190 --> 05:47.430 again before continuing let's jump right into the implementation. 05:47.450 --> 05:50.300 We will start with the get payment method. 05:50.300 --> 05:56.300 It must receive an integer that matches with one of the defined constants of the same file to know which 05:56.300 --> 05:58.400 implementation it should return. 05:58.400 --> 06:01.220 Now open the factory dot go file. 06:01.220 --> 06:03.180 I've already made the changes. 06:03.200 --> 06:10.340 Here's the code which I have added as you can see I have added F.M. T dot Sprint F in the return statement 06:11.380 --> 06:16.860 we use a plain switch to check the contents of the argument and method if it matches any of the known 06:16.860 --> 06:20.880 methods cash or debit card it returns a new instance of them. 06:20.970 --> 06:27.300 Otherwise it will return a nil and an error indicating that the payment method has not been recognized. 06:27.300 --> 06:32.070 Now we can run our tests again to check the second part of the unit tests. 06:32.080 --> 06:35.670 Let's go back to the terminal and execute the same command again. 06:35.700 --> 06:40.630 So these are the messages which are generated after the changes we made. 06:40.630 --> 06:44.950 Now we do not get the errors saying it couldn't find the type of payment methods. 06:44.950 --> 06:52.390 Instead we receive a message not correct error when it tries to use any of the methods that covers. 06:52.390 --> 06:57.880 We also got rid of the not implemented message that was being returned when we asked for an unknown 06:57.880 --> 06:58.990 payment method. 06:59.240 --> 07:05.770 Let's implement the struct now so move on to the factory file and that these lines of code to return 07:05.770 --> 07:12.320 the statement Save the file and navigate to the terminal open the terminal and execute the previous 07:12.320 --> 07:13.900 command again. 07:14.180 --> 07:19.700 We just get the amount printing it in a nicely formatted message with this implementation. 07:19.700 --> 07:22.030 The tests are all passed now. 07:22.040 --> 07:25.600 Also did you see the log messages. 07:25.600 --> 07:26.880 They aren't errors. 07:26.980 --> 07:31.750 We just print some information that we receive when using the package under test. 07:31.750 --> 07:36.600 These messages can be emitted unless you pass the hyphen the flag to the test command. 07:37.060 --> 07:38.240 Let's do it again. 07:38.320 --> 07:42.170 You can see we got the output as pass okay. 07:42.190 --> 07:46.960 We now step ahead to upgrading the debit card method to a new platform. 07:46.960 --> 07:52.780 Imagine that your debit card payment method has changed for some reason and you need a new Struct for 07:52.780 --> 07:54.770 it to achieve this scenario. 07:54.790 --> 08:00.340 You will only need to create the new Struct and replace the old one when the user asks for the debit 08:00.340 --> 08:02.170 card payment method. 08:02.170 --> 08:06.400 This is our new type that will replace the debit card PPM structure. 08:06.610 --> 08:11.770 The debit card PEM implements the same payment method interface as the debit card. 08:11.770 --> 08:13.150 We haven't deleted the previous one. 08:13.150 --> 08:15.340 In case we need it in the future. 08:15.340 --> 08:20.830 The only difference lies in the returned message that now contains the information about the new type. 08:20.830 --> 08:24.990 We also have to modify the method to retrieve the payment methods. 08:25.030 --> 08:28.740 The only modification is in the line where we create the new debit card. 08:28.750 --> 08:31.770 That now points to the newly created struct. 08:31.930 --> 08:34.910 Let's run the tests to see if everything is still correct. 08:35.020 --> 08:42.910 So navigate to the terminal and run the command go test iPhone the iPhone run equal to get payment method 08:44.050 --> 08:44.820 0. 08:45.020 --> 08:46.700 Something has gone wrong. 08:46.760 --> 08:51.950 The expected message when paying with a credit card does not match the returned message. 08:51.950 --> 08:54.260 Does it mean that our code isn't correct. 08:54.260 --> 08:56.070 Generally speaking yes. 08:56.270 --> 09:01.040 You shouldn't modify your tests to make your program work when defining tests. 09:01.040 --> 09:06.170 You should also be aware of not defining them too much because you could achieve some coupling in the 09:06.170 --> 09:08.950 tests that you didn't have in your code. 09:09.780 --> 09:14.940 With the message restriction we have a few grammatically correct possibilities for the message so we'll 09:14.940 --> 09:16.080 change it. 09:16.080 --> 09:19.260 Let's make the changes to the factory don't go file. 09:19.380 --> 09:24.610 Also make the changes to the switch case save the file and move back to the terminal. 09:24.830 --> 09:26.430 Let us run the tests again now. 09:27.460 --> 09:28.350 Everything is okay. 09:28.360 --> 09:35.050 Again this was just a small example of how to write good unit tests to when we wanted to check that 09:35.050 --> 09:41.060 a debit card payment method returns a message that contains paid using debit card string. 09:41.080 --> 09:47.190 We were probably being a bit restrictive and it would be better to check those words separately or define 09:47.230 --> 09:50.210 a better formatting for the returned messages. 09:50.230 --> 09:54.420 Now let's summarize and see what we have learned about the factory method. 09:54.460 --> 10:00.790 So with the factory method pattern we have learned how to group Families of objects to their implementation 10:00.790 --> 10:03.070 is outside of our scope. 10:03.070 --> 10:08.710 We have also learned what to do when we need to upgrade an implementation of a used struct. 10:08.710 --> 10:12.460 Finally we have seen that tests must be written with care. 10:12.520 --> 10:17.260 If you don't want to tie yourself to certain implementations that don't have anything to do with the 10:17.260 --> 10:22.810 tests directly in the next video we will learn about the abstract factory. 10:22.810 --> 10:26.050 Or rather we could say factory of factories.