Refactoring a video player using reveal module and command pattern in JavaScript
Tags: javascript, desingpattern, commandpattern, modulepattern
Published: 2019-02-23 00:19:47

---
title: Refactoring a video player using reveal module and command pattern in JavaScript
published: true
description: Today, I’m going to show a basic code in which a video player is done using a few good practices to develop code in the present days in the JavaScript language. My intention is show step to step the process from the original code to the finish code using several classic patterns such as Reveal Module and Command.
tags: javascript, desing pattern, command pattern, module pattern
cover_image: https://cdn-images-1.medium.com/max/1000/0*7IrOII04VHuF_8pd.png
---

*****

Originally published at [www.carloscaballero.io](https://carloscaballero.io/refactoring-a-video-player-using-reveal-pattern-and-command-pattern-in-js/) on January 11, 2019.

*****

Today, I’m going to show a basic code in which a video player is done using a
few good practices to develop code in the present days in the JavaScript
language. My intention is show step to step the process from the original code
to the finish code using several classic patterns such as [RevealModule](https://addyosmani.com/resources/essentialjsdesignpatterns/book/#revealingmodulepatternjavascript) and [Command](https://addyosmani.com/resources/essentialjsdesignpatterns/book/#commandpatternjavascript).

So, the initial code is the following:

![](https://cdn-images-1.medium.com/max/1000/1*XlEOJsMYNUj-QjqIaPod1A.png)

![](https://cdn-images-1.medium.com/max/1000/1*bLL0j_DuJIA3wOp2DFOzUg.png)

![](https://cdn-images-1.medium.com/max/1000/1*abIDernC6wbfBMO9ahdLKg.png)

The result of our code is the shown in the following image.

![](https://cdn-images-1.medium.com/max/1000/0*7IrOII04VHuF_8pd.png)

### USE INTERNATIONAL LANGUAGE TO CODE: ENGLISH + PRETTIER

The first step in any code of this world is use the international language of
coding. Today the mainstream language is English, I know that the other
languages such as Chinese or Spanish are top trending language but really is
more easy understand a code which is written in English. I’m Spanish-native and
for me is more difficult write and speak in English but I know that if I write
my code in English I can share my code with the world.

So, the first step is translate my code to English, It is not required a perfect
English because the majority of the audience is not English-native.

Another important and basic tip to code is use a tool which normalize your code
because there is not relevant the spaces or tabs in your code, the number of
characters which use in each line or the way in that your create a new object
but there is **very important** that you always do this task the same way. I.e,
you need normalize your code with you and your partners. The best tool in the
Web develop ecosystem today es [Prettier](https://github.com/prettier/prettier).
So, I recommend you that you install this tool in your favorite IDE (in my case
I’m using the extension in [VSCode](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode)).

Now, you can read the code using an international language and using a tool
which formatted my code:

![](https://cdn-images-1.medium.com/max/1000/1*TG19Tz7aidG34KJrmZCnGg.png)

![](https://cdn-images-1.medium.com/max/1000/1*PI4kKnBoRCipyO7eVlQUZg.png)

![](https://cdn-images-1.medium.com/max/1000/1*LYYKKs7WCQRY3Bnn3d867g.png)

> The GitHub project in this branch is [https://github.com/Caballerog/refactoring-js-patterns-tips/tree/01-international-code](https://github.com/Caballerog/refactoring-js-patterns-tips/tree/01-international-code).

### VARIABLE SCOPE — REVEAL MODULE PATTERN

There is very important that you know how variable scope works in your language
because you can avoid effects side in the future and to do your code more
cleaner and readable.

In JavaScript there are 4 way to define a variable and the main difference
between those way is the scope of the variable. In the following links you can
read about this [Vojtechruzicka Blog](https://www.vojtechruzicka.com/javascript-hoisting-var-let-const-variables/), [Stackoverflow QA](https://stackoverflow.com/questions/762011/whats-the-difference-between-using-let-and-var-to-declare-a-variable-in-jav)and [Andy Carter Blog](https://andy-carter.com/blog/variable-scope-in-modern-javascript) but a brief summary could be the following:

1.  **Only write your variable in any place of your code.** This is the worst way to declare a variable. In this case, the variable has a scope **GLOBAL** in your
app (OMG!! since a private function are you defining a **GLOBAL** variable)
which can provoke side-effects and several conflicts in your code. So, never
declare a variable without a keyword.
2.  Use the keyword **var**. Using the keyword var you have hoisting and functional scope. Your variable can provoke side-effects inside a function because the variable is define in the top of your code (in your function) and there is in
any place inside your function and the value is assigned in the line of code in
which you are initializing your variable.
3.  Use the keyword **let/const**. This is the way in which ES6 and the community
prefer used to define the variables because the scope of this variables is block
(as you expect it to behave because most languages using a block scope) but the
main different between let and const is that the pointer of memory in which is
store the reference of the value of the variable can change or not (OMG!). In
other words, let is used to variables in which the value can change in the code
and const is used when the value of the variable can not change if the type is
primitive (number or string) and can the pointer of the value can not change if
the type is not primitive, for example objects and array.

Ok, in this moment I know that I should change the way in which I’m defining my
variables in JavaScript. So, the code would be the following:

![](https://cdn-images-1.medium.com/max/1000/1*hBV9EJbItIOfjKiG-yPz0A.png)

The global variables that was define in the init function are moved to the top
of the script and use the keyword `const` because of there are references to the
DOM or a primitive value such as `max`. Also, there is a variable called `loop`
which is used to store the reference ID using returned in the `setTimeInterval`
function.

At the moment, both code are the same behavior because the variables were global
and in this moment are global too. For this reason, we could use the pattern [Reveal Module (https://addyosmani.com/resources/essentialjsdesignpatterns/book/#revealingmodulepatternjavascript) which allow create private scope to the functions and variables. This pattern can be read in this [blogpost](https://blog.bitsrc.io/understanding-design-patterns-in-javascript-13345223f2dd).

The pattern module reveal allow us convert in public our interface of
communication with the other pieces of the code. In this case the methods
`init`, `click`, and `move`. The method `state` now has the scope of our module
which is called `player`. The rest of variables are private too, so there, we
just to avoid side-effects provoke for the global scope of our variables or
methods.

The code with applying this pattern is the following:

![](https://cdn-images-1.medium.com/max/1000/1*oa0mRA-f236U9GPowI6GaA.png)

But the code below there is not works due to, the pattern module reveal is using
a IIFE which run before that the DOM is loaded, so the variables `media`,
`play`, etc. are `null`when the script run for these lines. The solution is move
the definition of this variables inside the method init, but in this refactoring
we going to create a object called `GUI`which store the information about the
DOM (in large apps this object would be translate to other files using the
famous pattern
[MVC](https://addyosmani.com/resources/essentialjsdesignpatterns/book/#detailmvc).

So, the final code in this step is the following:

![](https://cdn-images-1.medium.com/max/1000/1*b7IHl2ZD4XPKaFJdBWsZFg.png)

> The GitHub project in this branch is [https://github.com/Caballerog/refactoring-js-patterns-tips/tree/02-scope-module](https://github.com/Caballerog/refactoring-js-patterns-tips/tree/02-scope-module).

### CREATE CONDITIONAL METHODS

The following step to avoid complex in our code consist in create functions
which abstract your complex logic in simple and readable functions to take
decision about of different states.

For example, the logic from the conditional sentence can be extract in short
functions using the prefix “is” to express that the function return a boolean
value.

![](https://cdn-images-1.medium.com/max/1000/1*r2f6j52x-FfQDLb5ai0Ztg.png)

The code could be the following:

![](https://cdn-images-1.medium.com/max/1000/1*mOjzg_ANHP6pMtPXXHReVw.png)

> The GitHub project in this branch is [https://github.com/Caballerog/refactoring-js-patterns-tips/tree/04-create-conditional-methods](https://github.com/Caballerog/refactoring-js-patterns-tips/tree/04-create-conditional-methods).

The next step can be extract code in readable pieces of code (functions) which
add semantic value in our code. Thanks to this decision we can think about the
goal of our application. So, the method click and state can be refactor in the
following methods:

Refactor code

![](https://cdn-images-1.medium.com/max/1000/1*XlEOJsMYNUj-QjqIaPod1A.png)

> The GitHub project in this branch is [https://github.com/Caballerog/refactoring-js-patterns-tips/tree/05-short-methods](https://github.com/Caballerog/refactoring-js-patterns-tips/tree/05-short-methods).

### COMMAND PATTERN

In this moment, the code is a bit confuse because we are using if-else to use a
function which to do a action or command. There is a classical pattern called
`Command` which allows us abstract our actions/commands in an object. This
pattern is more complex in its traditional version but in JavaScript we can
implement this pattern using an object which receive a key to indicate the
action to do.

So, the first step is define the commands/actions, to simply the code, this
object is define in the same player.js.

![](https://cdn-images-1.medium.com/max/1000/1*9F6i6EzbkGQSLmnvW6rW7w.png)

The actions are **Play**, **Pause**, **State** **end** and **State**
**Playing**. The [command pattern](https://addyosmani.com/resources/essentialjsdesignpatterns/book/#commandpatternjavascript) consist in execute a method or action using this key (in our example there is not required parameters), therefor the command object is the following:

![](https://cdn-images-1.medium.com/max/1000/1*tyUJg2vVwVe9rcuKWPFbTQ.png)

Now, the moment in which the if-else dissapers using the pattern command:

![](https://cdn-images-1.medium.com/max/1000/1*7yYbcof8P5-3evJyfpCcxg.png)

> The GitHub project in this branch is [https://github.com/Caballerog/refactoring-js-patterns-tips/tree/06-command-pattern](https://github.com/Caballerog/refactoring-js-patterns-tips/tree/06-command-pattern).

### RESUME

In this example I’ve done several changes to improve the quality of my code. The
quality of my code is not relational with performance but also about the
readable and extensible. The following list is a resume about the different
techniques which I’ve been applied in my code.

1. **International Code.** Never programming using your local language, unless your local language is English. Nowadays, the international language is the english. So, you must develop your code using english. Imagine a code in German or French or Polish and you don’t know that language!
2.  **Prettier + CommitLint**
3.  **Variables Scope.** Study in your language how the scope works in the
declaration of variables. In JavaScript must understand that there are 4 ways to
define a variable and its scope is totally different.
4.  **Create conditional methods.** Refactor your condition in functions which
abstract your complex logic in a simple and readable function.
5.  **Create short, simple and readable functions.** Extract code in reusable
functions or, at least, add semantic value in your code.

> The GitHub project is [https://github.com/Caballerog/refactoring-js-patterns-tips](https://github.com/Caballerog/refactoring-js-patterns-tips).

*****

Originally published at [www.carloscaballero.io](https://carloscaballero.io/refactoring-a-video-player-using-reveal-pattern-and-command-pattern-in-js/) on January 11, 2019.

*****