JavaScript: Design Patterns 08 – Abstract Factory Pattern

Abstract Factory Pattern

This is an enhancement of the Factory Pattern, in that it operates in basically
the same way, the factory creates objects based on the passed in arguments.
The difference lies in that additional abstraction is added to the factory.

The added abstraction

The purpose of the traditional factory pattern is to remove, from the codebase,
the redundant object creation code by encapsulating it within a reusable object
the factory.

The abstract factory pattern takes this a step further by removing from the
factory its knowledge of the objects it is creating, making the factory extremely
generic. Due to this level of abstraction, it becomes important that the objects
the factory will be building are first registered with the factory prior to the
factory being used. The registration of objects can be done:

  • Internally to the factory in the init function
  • Dynamically through factory configuration passed to the factory by the caller
  • Through a registration function on the factory to which constructor functions are
    passed by the caller

How the registration occurs is totally up to the needs of the system.

Script: Supplemental for Example Below
// Constructor functions that will be used inside of the Lizard Factory
function Lizard(args) {
this.kind = args.kind;
this.moves = args.moves;
}
Lizard.prototype.bites = function() {
console.log(`${this.kind} just bit me really hard as it ${this.moves} away.`);
};
Lizard.prototype.says = function() {
console.log(`I am a ${this.kind}.`);
};

function Chameleon(args) {
Lizard.call(this, { kind: 'Chameleon', moves: args.moves });
this.name = args.name;
this.color = 'green'
}
Chameleon.prototype = Object.create(Lizard.prototype);
Chameleon.prototype.changeColor = function(color){
this.color = color;
console.log(`${this.kind} just changed color to ${this.color}, you no see me!`);
}

function Dragon(args) {
Lizard.call(this, { kind: 'Dragon', moves: args.moves });
this.name = args.name;
}
Dragon.prototype = Object.create(Lizard.prototype);
Dragon.prototype.fireBreath = function(){
console.log(`${this.kind} breath, you are now on fire.`);
}
Script: Abstract Factory Example
// Abstract and more generic animal factory
let AnimalFactory = function(){
// Object to hold registered types with associated constructor functions
this.types = {};

// object creation function becomes more generic
this.create = function(type, args){
return new this.types[type](args);
};

// type + constructor registration method
this.register = function(type, builder){
this.types[type] = builder;
};
}

// in this example, we register the types that can be created by the factory
// externally using the register method of the factory
let factory = new AnimalFactory();
factory.register('lizard', Lizard);
factory.register('chameleon', Chameleon);
factory.register('dragon', Dragon);

let baseLizard = factory.create('lizard', { kind: 'lizard', moves: 'speedy little demon' });
console.log(baseLizard);

let myChameleon = factory.create('chameleon', { name: 'Freddy', moves: 'very very slow' });
console.log(myChameleon);
myChameleon.changeColor('red');
let myDragon = factory.create('dragon', { name: 'Freddy', moves: 'very very slow' });
console.log(myDragon);
myDragon.fireBreath();

Published by

Tim Clark

Experienced Business Owner, Chief Information Officer, Vice President, Chief Software Architect, Application Architect, Project Manager, Software Developer, Senior Web Developer, Graphic Designer & 3D Modeler, University Instructor, University Program Chair, Academic Director. Specialties: Ruby, Ruby on Rails, JavaScript, JQuery, AJAX, Node.js, React.js, Angular.js, MySQL, PostgreSQL, MongoDB, SQL Server, Responsive Design, HTML5, XHTML, CSS3, C#, ASP.net, Project Management, System Design/Architecture, Web Design, Web Development, Adobe CS6 (Photoshop, Illustrator)

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s