Strategy Pattern

The strategy pattern is used to allow for a behavior to be selected at code run time.

  • this can be based on input data or other cues
  • The different behaviors are knows as the strategies
  • The strategy pattern is easy to implement in JS, but it’s not as commonly used as some of the other design patterns
  • This pattern is most useful in the situation that you have lots of similiar behaviors or modules doing similiar actions and you can’t code in which behavior will occur when the code runs live

The strategy module needs to expose a method for the strategy or behavior to be selected. It must also provide a way for the selected strategy (also called concrete strategy) to be invoked or used.

The beauty of this pattern is that main strategy doesn’t know anything about concrete (sub) strategies, and vice-versa. This makes it easy to add or remove stategies in the future.

Implementation

Page: strategy.js


// JavaScript Document
define(function () {
'use strict';

var Validator = function () {}; //this sets up main validation subroutine. In this example, we are creating a data validation script that will be different depending on what type of data is being validated.

Validator.prototype.selectValidator = function (validator) { //this allows for the concrete strategies to be selected.

this.validator = validator; //This will receive the strategies as an argument, and can set the argument as a property of the main validator.

return this; //return the main validator to enable chaining
};

Validator.prototype.validate = function (value) { //simple validate method that invokes the sub-validation strategy of the same name. It receives the value to validate as an argument, so we must make sure a validator has been selected before we attempt to use it. If not, we will throw and error.
if (this.validator) {
return this.validator.validate(value);
}
throw ('No Validator Selected');

};

return Validator; //return the object constructor
});

Page: telValidator.js


// This will be a telephone validation script that will check to see if the numbers entered into a telephone form object are valid
define(function () {
'use strict';

return {
validate: function (value) { //the validation function receive the data to evaluate as a value
return (/^[0-9]{10}$/g).test(value);
}
};
});

Page: emailValidator.js


// This will be a email validation script that will check to see if the string has an at symbol
define(function () {
'use strict';

return {
validate: function (value) { //the validation function receive the data to evaluate as a value
return value.indexOf('@') !== -1; //this line checks if there is an @ symbol in the entered string
}
};
});

Page: init.js


define(function(require) {
'use strict';

return {
init: function() {
var Strategy = require('strategy/strategy'),
telValidator = require('strategy/telValidator'),
emailValidator = require('strategy/emailValidator'),
validator;

validator = new Strategy(); //create a new validator by invoking strategy constructor

console.log(validator.selectValidator(telValidator).validate(123456789)); //this is testing the validation strategy for a 9 digit number, which should fail validation

console.log(validator.selectValidator(emailValidator).validate('jamesAtjamesportis.com'));//testing email varification strategy, no at symbol so this should fail
}
};
});