This workshop will be retired on May 31, 2020.
Refactoring with Protocol Extensions5:16 with Pasan Premaratne
Much of our code isn't DRY and can be improved. Because our protocol encodes most of the information we need, we can move the logic into a protocol extension.
In a previous course, we learned about extensions and 0:00 how you can use an extension to a functionality to an existing type. 0:03 Along with that, we learned how protocols and 0:08 extensions come together to do something just short to magic. 0:10 Using a protocol extension, we can provide default functionality for 0:14 methods defined in the original protocol. 0:18 If we take a look at the code in requestLandingInstructions method 0:22 of domestic airline, you'll notice that all we're doing is calling land 0:26 on the control tower and passing in self. 0:31 How would this look for international airline? 0:34 Exactly the same. 0:37 Since the information the control tower needs to land an aircraft 0:39 is encoded in the airline protocol and these types, 0:43 domestic airlines and international airlines, conform to the protocol, 0:47 by passing in self we're providing all the information that the control tower needs. 0:52 As always, for example, 0:57 if we had let's say, I keep referring to International Airline. 0:59 Let me just type it out. 1:03 Right, as you can see this is identical. 1:08 And as always, if you see two lines of identical code like this, 1:11 this is a good place for a refactor. 1:17 So how do we refactor this? 1:20 Well, this method is implemented in the domestic airline and 1:22 international airline types because it's required by the airline protocol. 1:26 Well, we just discussed how we can provide a default implementation for 1:32 a protocol requirement via an extension. 1:37 So let's try that out. 1:39 So let's extend airline, and I'll do that up over here. 1:41 And we do that using the extension keyword, 1:46 followed by the type that we want to extend, which is Airline. 1:49 Now inside here, we're going to write out the request landing instructions method 1:54 and provide a default implementation. 1:59 So we'll say func requestLandingInstructions, and 2:01 in the body of the method we write out the exact same implementation 2:05 that we have here. 2:09 So I can even copy, paste it. 2:10 Now since we've provided a default implementation for the method, we 2:13 can get rid of the implementation in the actual type that conforms to the protocol. 2:18 Earlier, this would have raised a compiler error, 2:25 because we don't conform to the airline protocol by not providing implementation. 2:28 Now, however, since there's a default implementation, 2:33 we don't necessarily need to provide one, and the compiler is happy. 2:36 So, how does this work? 2:40 Clearly the protocol has new information on it's own and 2:42 we don't create any instance of it. 2:45 When we wrote out the method inside DomesticAirline, 2:48 we passed self as an argument to the control tower's land method. 2:50 This self referred to the instance of 2:55 domestic airline type that calls this method. 2:57 In the protocol extension, however, this same self now refers to the instance 3:01 of whatever object conforms to the protocol and calls this method. 3:06 So if DomesticAirline conforms to the protocol, 3:11 which it does, and calls this method, as it does, 3:14 then self refers to the instance of DomesticAirline that calls the method. 3:19 Similarly, with InternationalAirline conforming to Airline, if an instance 3:24 calls request landing instructions, self refers to that instance. 3:29 Because the implementation is identical regardless of the type, 3:34 we can move it to the protocol itself and avoid repeating any code. 3:38 Now, if I head over to my view controller, 3:43 you can do this on the same page if you're in playground. 3:46 And in viewDidLoad, I'm going to type let 3:49 domesticAirline = DomesticAirline. 3:54 We'll create an instance, so for descend speed I'll say 92 knots. 3:59 And for type, this is in DomesticAirlineType and 4:04 it is a United flight. 4:07 Okay, and then I'll say let landingInstructions = 4:12 domesticAirline.requestLandingInstructi- ons. 4:17 Let me print this out to see if it worked. 4:23 And if I run it in my console, I should have a set of landing instructions. 4:28 So we'll wait until that goes through. 4:36 And there you go. 4:41 When we call the method on and instance, the compiler first checks to see if 4:42 there's an implementation for the method provided in the conforming type. 4:46 If there isn't one it uses the default implementation provided in the extension. 4:51 And as you can see, this works. 4:56 Our flight is landing at runway L31R. 4:58 And it's landing at Terminal C at gate number 5. 5:00 Okay so we've abstracted that method out of the type and into the protocol. 5:06 Is there anything else we can do? 5:11 Certainly let's jump to the next video to find out. 5:13
You need to sign up for Treehouse in order to download course files.Sign up