Decorators and Code Reuse 
Tags: decorators, dry, javascript, designpattern
Published: 2017-08-06 14:47:48

---
title: Decorators and Code Reuse 
published: true
description: 
tags: decorators, dry, js, design pattern
---

Decorators is a **design pattern** that helps in code reuse. It allows behavior to be added/extended to an existing object dynamically. The idea is that the decoration itself isn't essential to the base functionality of an object.

### What is code reuse?

Short answer is to _DRY_ (**D**on't **R**epeat **Y**ourself) out your code by not have any duplicate logic in different location. It's a path to **generalize code aimed at similar goals**. It's good practice to always take notice of similar parts of your code and to take action by **refactor**ing that part to a more reusable code.

**Let's take an example:**

Let's take a simple example of a game where your character is a warrior that moves left, right and can jump. We'll use various _object oriented_ concept in this example.

Let's start with simply defining our warriors as objects. We will define the first warrior as `darkWarrior`

```js
var darkWarrior = {};
```

We will add a property `location` to our `darkWarrior` to store the position of the character.

```js
var darkWarrior = {
  location: 1,
  weapon: "Sword"
};
```

Now assume that at one point in time your character will need to move. We will need to increment the `location` property in our `darkWarrior` to reflect that.

```js
var darkWarrior = {
  location: 1,
  weapon: "Sword"
};

darkWarrior.location+=1
```

Now let's add another `lightWarrior` warrior

```js
var lightWarrior = {
  location: 7,
  weapon: "Spear"
};

lightWarrior.location+=1
```

We've started to repeat ourselves now with this new warrior. While this is a very simple code, you already see the need to _DRY_ out the code somehow. First question to ask is: **which part of the code needs to be refactored?**

Well, for our case we can see that we increment the `location` property at two different places.

One way to refactor this is by taking incrementation behavior into a separate function, like so:

```js
var moveRight= function(warrior){
  warrior.location+=1
}

var darkWarrior = {
  location: 1,
  weapon: "Sword"
};

moveRight(darkWarrior);

var lightWarrior = {
  location: 7,
  weapon: "Spear"
};

moveRight(lightWarrior);
```

This refactor helps in writing your logic only once without unnecessary repetition. Plus this makes your code more maintainable by having one place to update your changes if needed. For example, if you were to change the `location` count to increment by `10` instead of `1`, in the old case we would have to change it in two places but after the refactor we will only need to update the `moveRight` function.

Let's also pass the `moveRight` function to be a method in our warriors objects.

```js
var moveRight= function(warrior){
  warrior.location+=1
}

var darkWarrior = {
  location: 1,
  weapon: "Sword",
  moveRight: moveRight
};

var lightWarrior = {
  location: 7,
  weapon: "Spear",
  moveRight: moveRight
};
```

In that case we don't have to pass an object to the moveRight function. We can actually use `this` to reference the object invoking the method.

```js
var moveRight= function(){
  this.location+=1
}

var darkWarrior = {
  location: 1,
  weapon: "Sword",
  moveRight: moveRight
};

var lightWarrior = {
  location: 7,
  weapon: "Spear",
  moveRight: moveRight
};
```

One problem with this approach is the `this` keyword is based on the calling context. For example if we want our warrior to move to the right every 1 second, we will need to pass the `moveRight` function to an interval timeout function like so:

```js
setInterval(lightWarrior.moveRight, 1000);
```

### Decorators

In the case above, `this` will point to the global window object and not to the calling object. What we can do is create a wrapper function that takes our object and extends it with the `moveRight` function

```js

var darkWarrior = {
  location: 1,
  weapon: "Sword",
};

var lightWarrior = {
  location: 7,
  weapon: "Spear",
};

var moveAdder=function(warrior){
  warrior.moveRigt=function(){
    warrior.location+=1
  }
  return warrior
}

darkWarrior  = moveAdder(darkWarrior)
lightWarrior = moveAdder(lightWarrior)
```

We call this approach a **decorator** pattern where we used a function that has only one purpose, which is to add a new behavior to our warrior. We also used the closure concept by replacing `this` with the actual reference to the object passed to the decorator function

We can also extend this concept by not just adding functionality but also altering existing functionality. Let's extend the previous example of our `darkWarrior` being faster than the other.

```js
var moveFaster=function(warrior){
  warrior.moveRigt=function(){
    warrior.location+=8
  }
  return warrior
}

darkWarrior.moveRight() //darkWarrior.location = 2

darkWarrior = moveFaster(darkWarrior)

darkWarrior.moveRight() //darkWarrior.location = 10
```

That's it for Decorators.