OOP Principles

Introduction

Up until now, you have learned and had a chance to practice the most common object-creation and organization patterns in JavaScript.

The entire lesson has been about the Object Oriented Programming" paradigm (OOP). How to create objects and classes is relatively straightforward. On the other hand, what to put in each object or when to make a new object, or when to let an object ‘inherit’ from another one isn’t that straightforward.

Learning Objectives

  • Four OOP pillars Encapsulation, Abstraction,Inheritance and Polymorphism
  • The Single Responsibility Principle
  • Additional SOLID principles
  • What "tightly coupled" objects are and why we want to avoid them

Study

There are several concepts and principles that can guide us into making good decisions when it comes to our objects. In this topic we will see an introduction to the most important of those concepts and principles.

Be aware of that there is not a clear answer to application design questions. In other words, some patterns and ideas might be better than others, but there is a trade-off when deciding where to put a specific function. Thus these principles are helpful guidelines and not rules.

In addition as you go through these resources it might be a good idea to go back to previous projects that you have already done and think about how what you’ve written measures up to the examples you see. As you move on keep these things in mind when building new projects.

Single Responsibility Principle

Single Responsibility Principle is an important principle when creating a project. This principle states that a class (or object or module.. you get the point) should only have one responsibility.

Let’s see a common example. Most of our code has functions to update and write things to the DOM in addition to our application logic. Thus it is a really good idea to separate out your DOM stuff from the application logic.

So instead of writing the code like 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 instead extract all the DOM manipulation into it’s own module and use it like this:

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.

  1. Read This Article.

  2. This article hits the same topic, and also covers the rest of ‘SOLID’ concisely.

  3. ..and one more for good measure

Loosely Coupled Objects

Although all of our objects work together to form our final application, we should make sure that our individual objects can stand alone as much as possible. Tightly coupled objects are objects that rely so heavily on each other. In other words, removing or changing one will mean that we have to completely change the other as well.

For 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. Therefore we should be able to start off writing our game using primarily console.logs(). Then later on we could add in a bunch of DOM functions without touching the game logic.

  1. This article explains it pretty well.

  2. The best book we have 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.