How to Create Reusable Code In JavaScript Using Design Patterns

If you ever want to create reusable JavaScript code or collaborate with a team of developers, then you need to know how to use and identify the different design patterns in the language.

In JavaScript, the term design pattern refers to a specific way of writing code and is often thought of as a programming template. The interesting thing is that the label “design pattern” can be applied to anything from an entire application to a simple block of code.

Design pattern is a broad topic, but by understanding the module pattern and the factory method you should get to grips with it.

The Module Pattern

JavaScript modules were introduced in 2009, with the ES5 version of the programming language. Using modules developers were now able to create custom pieces of code and export them to be used in other sections of a JavaScript application.

The Basic Structure of the Module Pattern


(function(){
//Declare private variables and functions
//Declare and return public variables and functions
})();

In the example above, module patterns are always enclosed in an immediately invoked function expression (IIFE). This means that a module pattern is executed as soon as it is defined. The important thing to note is that the module pattern consists of two distinct sections.

The first section is used to declare private variables and functions, which can only be accessed within the scope of the module pattern.

The second section consists of a return value that encloses public variables and functions that can be accessed outside of the scope of the module pattern.

Using the Module Pattern to Create an Application

Consider a simple application such as a task manager. Using the module pattern you will need to create custom modules for each section. These might include:

  • A task controller
  • A UI controller
  • A storage controller
  • An app controller

Related: Programming Projects for Beginners

The task controller will be used to create each new task. The UI controller will be used to control the UI-related functions, such as listening for the click of a button or changing what is being displayed. The storage controller will be used to save each new task to a  database. The app module will be used to execute the application.

Using the Module Pattern to Create a UI Controller Example


const UIController = ( function() {
//the private section of the module
let component = 'Replacement Text';
const changeComponent = function() {
//change all the h1 text to what is in the component variable above
const element = document.querySelector('h1');
element.textContent = component;
}
//the public section of the module
return{
callChangeComponent: function() {
changeComponent();
}
}
})();

The example above clearly shows the two sections that are found within a module pattern—private and public.

In the private section of the function, the component variable and the changeComponent function are both private. Therefore, if you wanted to change all the h1 text on a webpage you would get an error if you were to write the following code.

Incorrect Way to Invoke the changeComponent Example


UIController.changeComponent();

The error message will explicitly state that changeComponent() is not a function of the UIController function. This is the beauty of the module pattern; the variables and functions that are created in the private section will never be directly accessed outside of the scope of that function.

Though private variables cannot be directly accessed, they can, however, be indirectly accessed (from the public section). A takeaway from the UI controller example above is that the public section in the module pattern is always marked by the return property.

Within the parameters of the return property, we are now able to gain indirect access to the changeComponent function. We can now use the following line of code (with the module pattern above) to effectively change all of the h1 text on a targeted web page to “Replacement Text”.

Correct Way to Invoke the changeComponent Example


UIController.callChangeComponent();

The Factory Pattern

The factory pattern (also known as the factory method) is another popular JavaScript design pattern. The module pattern shines when data encapsulation is required, and the factory pattern is most useful in instances when we are dealing with a collection of different objects that are similar in some aspects.

Going back to our task manager above; if we were to allow the user to assign a type to each task that is created, then we could create that aspect of the app (quite efficiently) using the factory pattern

Using the Factory Pattern to Assign a Task Type Example


//Factory pattern function
const TaskFactory = function(){
this.createTask = function(name, type){
let task;
//check the type the user selected
if(type === 'urgent'){
task = new UrgentTask(name);
}else if(type === 'trivial'){
task = new TrivialTask(name);
}
//set the type selected in the if statement to the one received as a property
task.type = type;
//used to print the task and its type to the console
task.define = function(){
console.log(`${this.name} (${this.type}): ${this.priority}`)
}
return task
}
}

The code above uses the factory method to create new tasks, check the type (urgent or trivial), and assign the appropriate property before printing the new task to the console.

The inner function createTask, sets the stage for multiple tasks to be created simultaneously, but before we try to create any new tasks there is some additional code that we need to include in this section of the project.

In the code above we are creating a new UrgentTask or a new Trivialtask if a specific condition is met. However, there isn’t any function or class with these names in our project—this problem can be easily solved by introducing the following code to our project.

Create Urgent and Trivial Task Types


//Create the urgent task type
const UrgentTask = function(name){
this.name = name;
this.priority = "as soon as possible"
}
//create the trivial task type
const TrivialTask = function(name){
this.name = name;
this.priority = "when you can"
}

Because of the code above, we are now able to assign the UrgentTask or TrivialTask property to each new task that is created. The next step is to now create a new task, but before that, we need to create a database to store each new task as it is created.

Given that creating a database is an entire article in itself, we will substitute a database with a data structure (an array).

Creating an Array Example


//create an array to host the different task
const task = [];

Now we can finally create a new task.

Creating New Tasks Example


//create two new tasks
const factory = new TaskFactory();
task.push(factory.createTask('Clean the house', 'urgent'));
task.push(factory.createTask('Reach level 30 in Candy Crush', 'trivial'));

With the code above you are now able to create two new tasks using the TaskFactory function that we created initially. When we create each new task the properties (name and type) are being past to the createTask function, which is located in the TaskFactory function that we created using the factory pattern.

After each task has made its way through the TaskFactory and the appropriate type property is assigned to it. It is then pushed into the task array that we created earlier.

Our only dilemma now is how do we know that those two tasks were created or that our factory pattern worked? If we had used a database then we could simply check the database to see if two new tasks were created.

Go back to the “Using the Factory Pattern to Assign a Task Type Example” above, directly below the “used to print the task and its type to the console” comment, there is a small “task.define” function that was created to print each task in the array to the console using the following array method.


//print each task to the console
task.forEach(function(task){
task.define();
});

You should see the following output being display in your console.


Clean the house (urgent): as soon as possible
Reach level 30 in Candy Crush (trivial): when you can

Now You Can Use Design Patterns in Your JavaScript Projects

At this stage you should understand design patterns in JavaScript and understand how design patterns can be used to create reusable code and make life easier for all the developers involved in a project.

Now you know how two popular JavaScript design patterns work, you should be able to  efficiently apply them to develop an application.

Image Credit: Alltechbuzz/Pixabay

Source: makeuseof.com

Related posts

AppleCare+ Explained: How Much Does It Cost and Is It Worth the Price?

Today’s NYT Connections Hints and Solution (Sunday, June 16, 2024)

This Handy App Lets You Customize Menus in Windows Explorer