ruk·si

🍦 JavaScript Pattern
Decorator

Updated at 2015-05-13 16:11
var Warrior = (function() {
  'use strict';
  var Warrior = function() {
    this.getCost = function() { return 5; };
    this.getAttack = function() { return 5; };
    this.getStamina = function() { return 5; };
  };
  return Warrior;
}());

var Knight = (function() {
  'use strict';
  var Knight = function() {
    this.getCost = function() { return 7; };
    this.getAttack = function() { return 7; };
    this.getStamina = function() { return 7; };
  };
  return Knight;
}());

var UnitTraits = (function() {
  'use strict';

  var UnitTraits = {};

  UnitTraits.applyEnraged = function(unit) {
    var prevCostFunc = unit.getCost;
    var prevAttackFunc = unit.getAttack;
    var prevStaminaFunc = unit.getStamina;
    unit.getCost = function() {
      return prevCostFunc() + 2;
    };
    unit.getAttack = function() {
      return prevAttackFunc() + 4;
    };
    unit.getStamina = function() {
      return prevStaminaFunc() - 1;
    };
  };

  UnitTraits.applySickly = function(unit) {
    var prevCostFunc = unit.getCost;
    var prevAttackFunc = unit.getAttack;
    var prevStaminaFunc = unit.getStamina;
    unit.getCost = function() {
      return prevCostFunc() - 2;
    };
    unit.getAttack = function() {
      return prevAttackFunc() - 1;
    };
    unit.getStamina = function() {
      return prevStaminaFunc() - 1;
    };
  };

  return UnitTraits;
}());

// Base warrior
var warrior = new Warrior();
console.assert(warrior.getCost() === 5);
console.assert(warrior.getAttack() === 5);
console.assert(warrior.getStamina() === 5);

// Enraged warrior
UnitTraits.applyEnraged(warrior);
console.assert(warrior.getCost() === 7);
console.assert(warrior.getAttack() === 9);
console.assert(warrior.getStamina() === 4);

// Enraged sickly warrior
UnitTraits.applySickly(warrior);
console.assert(warrior.getCost() === 5);
console.assert(warrior.getAttack() === 8);
console.assert(warrior.getStamina() === 3);

// Base knight
var knight = new Knight();
console.assert(knight.getCost() === 7);
console.assert(knight.getAttack() === 7);
console.assert(knight.getStamina() === 7);

// Sickly knight
UnitTraits.applySickly(knight);
console.assert(knight.getCost() === 5);
console.assert(knight.getAttack() === 6);
console.assert(knight.getStamina() === 6);