Check out a free preview of the full Deep JavaScript Foundations course:
The "Challenge 5: Solution, Part 3" Lesson is part of the full, Deep JavaScript Foundations course featured in this preview video. Here's what you'd learn in this lesson:

Kyle walks through the solution to Challenge 5, Part 2 and takes questions from students.

Get Unlimited Access Now

Transcript from the "Challenge 5: Solution, Part 3" Lesson

[00:00:00]
>> Kyle Simpson: Okay, let's talk through the solution to part 3. First thing is I'll show how we implement that project module factory. So, here's the project function. The only piece of input data that it needs to take is the description because it's gonna generate its own ID, and we're gonna use API methods to update the time.

[00:00:20] So it takes in a description, immediately generates its own ID, keeps track of the work, and also, the total time for that given project. Here's the public API. We've got a couple of getters, we have a getId, a getDescription, a getTime to return those pieces of information to the calling program.

[00:00:40] Rather than returning or giving access to the actual variables, we use access or functions to get at them. Then we have a couple of, then we have a mutating function, mutator that's called addWork. That's how we add work into the project. That will add an entry into the work array and update the time and so forth.

[00:01:01] And then we have moved our getWork entry count and our getWork entry location functions from app over into this function. Because they actually are relevant to the given project. Whereas before we had to pass in a project ID, those functions now don't need a project ID at all, because we already know which project, they're being called against the project instance.

[00:01:24] So we can simply call getWork entry count and return the work length. GetWork entry location still needs a work entry ID, but the logic is the same, it just doesn't need to figure out what project to do that against since we already know that. So it simplified that code to have this isolated to a given project instance.

[00:01:44] Now we're gonna be calling this project function to create instances of the project each time we make one. So let's go to our app data model. You will notice instead of making project entry data and all that other stuff like we were doing before. Now I just called it capital P project function pass in the description and get a project object back.

[00:02:10] I don't need to deal with any of those details because those are handled by the project factory. So I just get a reference to a project object and that's what I store in my projects array here on line 214. That more cleanly separates the concern between my data model and the stuff that can be abstracted into these project instances.

[00:02:32] You'll also notice that now that project object is the thing that project instance is the thing that I pass around. Instead of passing around project ID, project description all of that is separate individual pieces of data, I'm just gonna ship that project object around and you can call the, the access or methods as you see fit.

[00:02:51] So it simplifies the passing between the app model and the UI model. Same thing down here with addWorkToProject, we simplified quite a bit our findProjectEntry simply gives us a project instance, we can call addWork on it to let it delegate the job of handling the work.

[00:03:12] And then we can pass project along to any UI methods as we see fit. So what you'll notice here is that by creating this abstraction, we actually have simplified the reasoning of code. And that's the hallmark of good abstraction. Abstraction's not about hiding things. Abstraction is about making independent things easier to reason about.

[00:03:32] So we've made this piece easier to reason about by taking the parts that were cluttering it up with other stuff and moving them to a different location. So we can independently think about the project logic separate from thinking about the data model logic that's the key idea behind abstraction and the module here was pretty good use for us, now I wanna address something.

[00:03:55] A small elephant in the room because we're creating multiple instances of this project and most people's preferences or their instinct would be to say, well I should be instantiating some class. You would think, why am I not doing a new here? Why am I not instantiation some class?

[00:04:14] The point that I'm trying to make, is that there's nothing unique about classes, in terms of our ability to create a data model abstraction and instantiate things. There's nothing specific to the class design pattern that requires us to go that route to accomplish that. Here, we just need a module instance, so I can just call that module factory function.

[00:04:36] I don't need to be creating some instance of a class to accomplish that goal. Yes?
>> Speaker 2: So, in this case, you don't have any effect right? Not hurt anything if you put new project right here, it will still work the same way, right?
>> Kyle Simpson: It would not break anything but it would actually be less performant because, the new keyword, we'll get into this later, but the new keyword actually creates object instances and would throw those away.

[00:05:04]
>> Speaker 2: Would that communicate to people that you're actually creating something new?
>> Kyle Simpson: No, I think that's a terrible idea, to communicate to them something that's not actually happening. The new keyword says I'm making an instance of something. That's different from module factories,so if you're doing a module factory, it should look like a module factory not like a class.

[00:05:28]
>> Kyle Simpson: When I see the new keyword, my assumption's gonna be, you're trying to instantiate a class. If you don't do that, you're creating a stumbling block for me.
>> Kyle Simpson: Okay. The usage in the UI functions Is more straightforward because now we receive a project. So for example, here on line 117, I call getId on the project object, and that's how I get my project Id, and I call getDescription to get the description.

[00:06:00] I add them to the dom elements so there's a nice clean separation there as well. Same with that ProjectToList. If you're still feeling a bit fuzzy about this whole module pattern and how to use it, not just as a syntactic approach, but as an actual design pattern and architecture that drives the design of your software I strongly recommend that you put a mental bookmark to go back and try this exercise a few more times from scratch.

[00:06:28] Try your hand at it so that you get more experienced with that.