This workshop will be retired on May 31, 2020.
One Type to Rule Them All8:48 with Pasan Premaratne
Since our protocol encodes most of the information our concrete types do, we may not even need multiple airline types. In this video, let's move even more information out of the concrete types and let the protocol do nearly all the work.
Right now our type, 0:00 domestic airline, has two pieces of information it needs for an instance. 0:02 The type of the airline and the descent speed. 0:07 So let's assume that in our example, 0:11 all domestic flights have basically the same descent speed. 0:13 So they use the same runway. 0:16 International flights have another identical descent 0:19 speed amongst all flights, and so do private planes. 0:21 This obviously isn't really the case, but 0:25 if we assume this silly example, then I can show you another case where we 0:28 can move our logic from the concrete type domestic airline back to the protocol. 0:33 So right now, 0:38 to figure out which runway to land on, all we need to know is the descent speed. 0:39 We enforce this design, again, through the airline protocol. 0:44 But more specifically, we do it through the fly protocol, which requires a or 0:48 flying which requires a descent speed. 0:52 The descent speed in our naive example 0:55 is a static value based on what type of flight we take. 0:58 If you think about it, 1:02 the type of flight that we take is defined as a series of enums, right? 1:03 So the domestic flight type 1:08 is defined by DomesticAirlineType and international is this type right here. 1:12 What if we move the descent speed information to each of those types? 1:18 Remember that when a protocol defines a property requirement, 1:23 this can be satisfied using either a stored, or a computed property. 1:27 So, I'm going to go back down here, and under the extension of airline, 1:32 let's extend DomesticAirlineType. 1:36 And to this we're going to add a computed property for descentSpeed. 1:44 Okay, now the descentSpeed for 1:56 domestic airlines is defined within the enum itself. 1:58 So can we use this to provide a default implementation 2:03 to the airline protocol to satisfy the property requirement? 2:07 Let's try. 2:11 So back in the definition of the airline protocol, so 2:13 let me go all the way up to the top. 2:16 We have one additional requirement on top of those required by flying and 2:19 landing, and that is the AirlineType property. 2:23 Now that we have the descentSpeed encoded in the AirlineType, 2:27 can we use this type property to satisfy the requirement of the flying protocol? 2:33 The decent speed as a default implementation, and 2:39 we can do that in an extension. 2:43 That was a lot of jargon, so let me repeat again. 2:45 Airline inherits from flying, so 2:48 objects conforming to flying need to implement the descentSpeed requirement. 2:51 We can provide default implementations in protocol extensions. 2:57 So in the extension of Airline, can we provide a default implementation for 3:03 descentSpeed so that conforming types don't have to do that? 3:09 The way we're going to attempt that is by using the information 3:13 that we've now encoded in the AirLineType property. 3:17 So if we go back down, all the way down through the extension of Airline, 3:21 let's add a computed property in here for descent speed as well. 3:27 So we'll say var descent speed in knots okay. 3:31 Now where are we going to get this actual speed information? 3:39 Well the airline protocol knows about the airline types since that is a property it 3:42 defines. 3:47 And since we encoded the descentSpeed information in the AirlineType, 3:48 why not use that? 3:54 So let's give it a try. 3:54 So we'll say return type.descentSpeed. 3:56 If we try to do this, clearly it doesn't work. 4:02 Now if we click on the error message, it says that the value of 4:05 type AirlineType has no member descentSpeed. 4:10 Okay, the problem here is that the information is encoded in an enum, 4:14 as you can see here. 4:19 Whereas the type that we're interacting with through the type property 4:20 is the higher type, the airline type protocol, 4:25 which you can't even see here but over here you can see, type is of AirlineType. 4:28 So what we can do to make this work, is we can expose the descent speed property 4:34 in the AirlineType protocol so that's it's available to use at the protocol level. 4:41 If you didn't understand that, rewind me as many times as you need. 4:46 We can add the descent speed requirement directly in airline type but 4:50 it's easier to simply inherit the requirement through the flying protocol. 4:55 Now protocols cannot inherit from other protocols via an extension, so 5:00 let's go back up and add it to the original declaration. 5:05 So over here we have the original AirlineType protocol that we declared. 5:09 In here, let's inherit from the Flying protocol. 5:14 Now any type that conforms to AirlineType 5:19 also needs to implement the descent speed requirement. 5:22 We've done that for DomesticAirlineType through an extension. 5:25 But we have an error here for InternationalAirlineType because we 5:29 haven't provided that information for this type, and so it doesn't conform just yet. 5:33 So, we'll add that at the bottom as well in an extension. 5:38 So we'll say extension international airline type. 5:45 And we'll provide a value for descent speed. 5:50 And we'll just say it's 130 always. 5:58 Cool. 6:01 No more errors. 6:02 Now, the airline protocol, as you can see here, provides a default 6:04 implementation for the descent speed that it gets through the airline type property. 6:09 So now that it provides a default implementation, conforming types, 6:15 types that conform to airline, don't necessarily need to provide it either. 6:19 Which means we can go down to domestic airline and international airline and 6:24 just remove this altogether. 6:28 It now gets that information from the protocol. 6:31 Okay. 6:35 At this point, why do we even need a specific object for 6:35 a domestic airline versus an international airline? 6:39 Since we're specifying the type in the type property, 6:43 we can now have a really tiny struct where we just specify the type of flight. 6:46 And the protocol is going to do all the work. 6:52 So let's change this. 6:55 We'll get rid of it altogether, and we'll define a new type. 6:56 We'll call this Flight. 6:59 Conforms to Airline, and all it needs to provide is a type. 7:02 And that's it. 7:07 Let's test this out. 7:08 So let me go back to the view controller, and we'll get rid of this. 7:09 And instead, I'm going to type, let domesticFlight = Flight. 7:15 And for the type, I'll say it is a DomesticAirline. 7:22 And it is an American flight. 7:25 Okay, now using this, let me try and print the landing instructions. 7:29 Okay, for some reason it's not picking up all this. 7:40 I'm pretty sure I have an error. 7:42 Let's see if that works. 7:45 Okay, it does. 7:47 And now let's add one more. 7:49 So I'll say let internationalFlight. 7:50 And we'll do the same thing. 7:59 This is the flight type and it takes a type in the initializer. 8:00 So we'll say this is an InternationalAirline AirFrance. 8:04 Simple enough. 8:10 And we'll print the landing instructions for this flight as well. 8:11 Run the code or if you're in a playground, it's already running. 8:19 And you should see in your console that despite the flight strut 8:24 having zero logic whatsoever, we get the correct implementation. 8:29 The domestic flight takes runway L31R and 8:34 heads over to gate B2, while the international flight takes runway M52J, 8:38 and parks at the international terminal at gate 4. 8:42
You need to sign up for Treehouse in order to download course files.Sign up