By this point, you will have learned and had a chance to practice the most common object-creation and organization patterns in JavaScript. But that is just the tip of the iceberg. More important than learning the syntax for factory functions or modules is figuring out how to use them effectively.
This whole series of lessons has been about the "Object Oriented Programming" paradigm (OOP). The basics of creating objects and classes are relatively straightforward. But it is not straightforward to decide what to put in each object, or when to make a new object, or when to let an object ‘inherit’ from another one.
By the end of this lesson, you should be able to do the following:
Luckily there are several concepts and principles that can guide us into making good decisions when it comes to our objects. This lesson is an introduction to the most important of those concepts. Keep in mind that there is not usually a very clear answer to your application design questions. Some patterns and ideas are obviously better than others, but there is often some trade-off when deciding where to put a specific function. In other words.. these principles are not rules– they’re helpful guidelines.
As you read these resources, it might help to go back to some projects you’ve already done and think about how what you’ve written measures up to the examples you see. And of course, as you move on keep these things in mind when crafting new projects.
One of the most important things to remember as you craft your objects is the Single Responsibility Principle which states that a class (or object or module.. you get the point) should only have one responsibility. Here’s a really common example. Most of our code has functions to update and write things to the DOM in addition to our application logic. It’s a really good idea to separate out your DOM stuff from the application logic.
So instead of this:
function isGameOver() {
// game over logic goes here!
if (gameOver){
const gameOverDiv = document.createElement('div')
gameOverDiv.classList.add('game-over')
gameOverDiv.textContent = `${this.winner} won the game!`
document.body.appendChild(gameOverDiv)
}
}
You should extract all the DOM manipulation into it’s own module and use it like so:
function isGameOver() {
// game over logic goes here!
if (gameOver){
DOMStuff.gameOver(this.winner)
}
}
In fact – the function isGameOver
shouldn’t be calling the DOM function anyway that should go elsewhere (directly in the game-loop)
The Single Responsibility Principle is the first of a commonly found set of 5 design principles called the SOLID principles. Both of the following articles mention the acronym SOLID before going on to talk about Single Responsibility. Single Responsibility is definitely the most relevant of the 5. Feel free to dig into the rest of the SOLID principles if you like.. but pay special attention to Single Responsibility.
Read This Article.
This article hits the same topic, and also covers the rest of ‘SOLID’ concisely.
..and one more for good measure
Obviously, all of our objects are intended to work together to form our final application. You should take care, however, to make sure that your individual objects can stand alone as much as possible. Tightly coupled objects are objects that rely so heavily on each other that removing or changing one will mean that you have to completely change another one – a real bummer.
This one is related pretty strongly to ‘Single Responsibility’ but takes a different angle. As an example, if we were writing a game and wanted to completely change how the User Interface worked, we should be able to do that without completely reworking the game logic. So we should be able to start off writing our game using primarily console.logs()
and then add in a bunch of DOM
functions later without touching the game logic.
This article explains it pretty well.
The best book we’ve ever read on this subject is Practical Object-Oriented Design In Ruby. Unfortunately, it is not free.. and not JavaScript. We feel confident in recommending it anyway. If you don’t know Ruby, it is a clear enough language that you don’t really need to learn it to follow the examples and the content of the book is sincerely fantastic.