One of the big leaps you'll have to make as a JavaScript developer is wrapping your head around Object Oriented Programming (OOP). This is tough, and that's ok because it's tough for everyone at first. When you start out with JavaScript you're taught to use functions as your primary way of organizing your code. This is fine, but you'll probably find that organizing your code around objects makes larger projects easier to accomplish and improve / maintain.
The cool thing is that what OOP amounts to is an organizational strategy. I have a set of related tasks, how do I go about starting the project and organizing my code? These tasks have some variables and functions that are used to accomplish them, so you create them and write the logic for them to interact. While you can write those out as detached functions and variables, making those variables and functions into properties and methods of an object can make the division between those tasks easier to see and maintain.
Maintaining some separation between your tasks is important, because it means bugs will be restricted to one place in the code. This makes them easier to fix. It's also clear where to add features, because you pick an existing object that is related to it or make a new one and that task is now neatly in one place. Dividing your tasks into discrete units also lets you work on them one at a time and somewhat independently, which solves the question of "Where do I start?" You start with the objects and tasks that the most other objects and tasks are dependent on and go from there.
Let's take a real world example. You're working as a developer at ACME Software Industries, and your boss comes to you and says "Our clients want to be quizzed on things, make a quiz app!". Generally your boss sees the big picture, and it's up to you take that large problem and divide it into smaller tasks, and eventually into lines of code that solve the overall problem. So let's think about the smaller problems involved in creating this application:
- We'll need some way to store the questions in the quiz along with their answers.
- We'll need to write some logic that moves from one question to another and starts and restarts the quiz.
- We'll need to do some DOM interaction like handling a click on a button and displaying a question to the user.
Within those tasks there are a lot of smaller tasks, and there are a lot of ways you could go about writing them. I chose to divide the tasks into these three categories for a reason though, and that reason is called MVC.
Just saying "use objects" is pretty vague, and the natural follow up question is "Well, which objects should I use?" There are lots of different strategies depending on the particular problem you're trying to solve, but the main idea is to lump your tasks into some categories that don't have much to do with one another and create objects within those categories. MVC is a set of categories for objects that fit a wide variety of tasks. Here's how it breaks down in this case.
- Model: Our quiz app is a data driven application. The data in this case are our questions. So we take our questions and the functions that interact with the data for those questions and put them into a set of objects.
- View: We're taking those questions and displaying them to the user, and handling user input. We can make a set of objects that just handle those tasks.
- Controller: Once we've separated out the data part and the view part, what's left is the logic that coordinates those two to create the application. We take that logic and put it into it's own object or objects as well.
The rationale behind MVC is really best explained by a question: "What things in my app are likely to change independently of eachother?" This is a good question to ask, because we don't want to mix these tasks and make them dependent on eachother. Otherwise every time we make a change in one we'll have to make some changes in the others. This increases the cost in terms of how many changes you'll have to make to add a feature or fix a bug, and our boss doesn't like cost. We don't like cost either, because it means work and frustration.
If you change the class on a button, does that affect how you check the answer to a question? If you add a feature to restart the quiz, does that change the way questions are displayed? The answers to these might end up being yes, but in many applications the concerns for your data, presentation, and logic can be separated in a way that they don't affect one another to a great extent. So for this application dividing up our tasks into objects that deal with data, objects that deal with presentation, and objects that deal with logic makes a lot of sense.
So are you ready to look at some code? Let us begin...