This course has been updated! We now recommend you take the Basics of Go course.
Transcript from the "Refactor for an Interface" Lesson
[00:00:02]
>> Cool, so let's hop over to INTERFACES.GO, we'll kinda implement some of this in real time. So right now, we're kinda starting from a copy of the code that should look pretty similar to what you finished in methods. You're welcome to also start from that file since you're familiar with it, whatever you'd prefer.
[00:00:16] I'm gonna be working in interfaces.go for right now. And what we're trying to do here is we want to add that describer interface, and then create a method where we can pass in any of the structs that satisfy the describer interface, and then call describe on them. So we have our two structs here, both of which you can call describe on.
[00:00:36] And then in our main function, we are simply calling the describe methods in them. So similar code that we've been working with for a little while here. Cool, so let's start at the top and let's add our describer interface. Additional to side note, the convention for interfaces is to name them with whatever job that the interface does.
[00:00:57] So right now, just type describer interface. It describes, so it is a describer that can get a little funky if your methods don't make an Ending to a word sound very good, but it is kind of the accepted pattern if possible. Describe. So we've now established that. Any struct that has a method called describe is also of type describer.
[00:01:43] Add a comment or go into his happy. We can kinda scroll down. And kinda lump these two guys together. So let's create a function that doesn't care what type is passed in, as long as that type satisfies our interface. So we can say func. I think I call it do the describing.
[00:02:10] It's gonna take some type, we're not quite sure what, we haven't specified user or group, but we do know it has to be of interface type describer. And because all of our describe methods do return a string, we'll make sure that our function to describing also returns a string.
[00:02:31] I'm making a capital cuz I'd assume that if I am using this elsewhere, I'm describing lots of stuff. I want this to be exportable. I want it to be visible in other packages. So let's do the describing, describes whatever struct is passed in. And then within our function here, I'm going to say, hey, let's return d.describe since whatever struct is passed in is part of our interface describer.
[00:02:59] I know it must have this method, and that's what I'm trying to accomplish within this function, cool. And then data in our main function. We can say our naming right now, because we have so many examples is getting a little fun but that's okay. So user description, with interface, I know it's very long but just for clarity.
[00:03:24] It's going to be do the describing, that's going to take a user, cool. And then we're gonna do the same thing with our group. Group description with interface is going to be you do the describing function, and it's going to take a group. So you'll see we're getting some errors around what we're passing in.
[00:03:51] And the error that I'm seeing is that we have describe, we have some sort of describe function in an interface that's returning a string, but we're not returning a string in our actual interface definition. So we just go up to the top here. We're saying that hey, this describe method exists on our interface, but we still have to say that at the end of the day it returns a string.
[00:04:10] Just add that additional piece of information into our interface definition. Cool, the next error we're getting is, I've kind of been flipping between using either a pointer or non-pointer as a struct type or passing in. So you'll notice that if we go up to both of our methods in this particular file, I am passing in a pointer type for our user and our group.
[00:04:38] So that's what's gonna happen in this file, you know that we need to pass in the actual address, the ampersand A4 address version of our variables here. So if we add our at here. We. Have a bunch of variables that we're not actually referencing. So we're going to just print line.
[00:05:10] Save it and then run it. Kill these guys. And we're also gonna kill these guys since we are now accomplishing the same job just with our do the describing method that takes the interface, rather than to individual calls to methods. So again, kind of contrived based on the examples we have here.
[00:05:34] But if you can imagine large services that set up as three buckets or other more complex interactions with large code bases, having a single function, be less specific about what it takes in, as long as all of these other rules that live in some other file are established.
[00:05:52] It reduces a lot of duplication within your code. It also encapsulates kind of all of his behavior, and all of the attributes, and in a more object oriented way, which makes everything a little bit more readable.