Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How technically different is Parasitic Constructor Pattern from Factory Pattern

Parasitic Constructor Pattern can be seen as a combination of factory and constructor pattern. In factory pattern, we call a function which then explicitly creates an object and adds desired properties and methods to the object and finally returns the object.

function createPerson(name, age, job){
    var o = new Object();   //explicit object creation
    o.name = name;
    o.age = age;
    o.job = job;
    o.sayName = function(){
            alert(this.name);
        };
    return o;
}

var person1 = createPerson(“Nicholas”, 29, “Software Engineer”);
var person2 = createPerson(“Greg”, 27, “Doctor”);

Things to note:

  • explicit object is created and returned
  • method and properties are added to the explicitly created object
  • method is called without new keyword

The disadvantage: it doesn’t allow to identify the type of the object.

Any function can be treated as constructor by calling it with new operator. When called without new operator, inside the function, this object points to the global object (window in browser). And when the function is called with the new operator, it first creates the new instance of object and then sets this object to a newly created object.

Constructor pattern adds methods and properties to this object and finally returns this object thus allowing to later identify the type of the object using instanceOf operator.

function Person(name, age, job){
    this.name = name;
    this.age = age;
    this.job = job;
    this.sayName = function(){
            alert(this.name);
        };
    }

    var person1 = new Person(“Nicholas”, 29, “Software Engineer”);
    var person2 = new Person(“Greg”, 27, “Doctor”);

Things to note:

  • function is called with new operator (to make JavaScript engine treat it as a constructor)
  • object is not created explicit instead this object is returned

Now the Parasitic Constructor Pattern explicitly creates and returns an object similar to factory pattern and it is called with new operator like constructor pattern:

function Person(name, age, job){
    var o = new Object();
    o.name = name;
    o.age = age;
    o.job = job;
    o.sayName = function(){
            alert(this.name);
        };
    return o;
}

var friend = new Person(“Nicholas”, 29, “Software Engineer”);
friend.sayName(); //”Nicholas”

However I can't see the use of calling the function with new operator. I mean since the function explicitly creates and returns the object we will not be able to identify the object type explicitly using instanceOf operator.

So what is great in Parasitic Constructor pattern? Is there any technical subtlety that can be exploited or suitably used for a specific object creation scenario? Or Is just another possible programmatic approach for creating object?

like image 309
Mahesha999 Avatar asked Oct 07 '22 05:10

Mahesha999


2 Answers

I think the part that you're skipping over with the Factory, is that in most other languages, the factory is either going to be making multiple different kinds of similar objects, whether done like:

var truck = carFactory("Truck");
var jeep  = carFactory("Jeep");

or done like:

var piano = instrumentFactory.piano("Grand");
var bass  = instrumentFactory.bass("Upright");

or any other interface you want it to have...

OR a factory's responsibility is going to be to make a very big class out of smaller classes, through dependency-injection, and potentially polymorphism:

function createTank (gunType) {
    var armour = new Armour();
    armour.hp  = 120;

    var wheels = new ChainTracks();

    var driver = new Soldier();
    driver.hp  = 15;

    var gun = gunFactory(gunType);

    var tank = new Tank(armour, wheels, gun);
    tank.driver = driver;

    return tank; 
}

var ground_tank = createTank("cannon");
var aa_tank = createTank("flak_cannon");
var at_tank = createTank("depleted_uranium_lancer");

If you have a Factory which is as simple as making an object, setting its properties and returning the object, then there really is no difference.

The differences come into play when you're either talking about using a lot of specialized components to make something come together (whether they're injected, or hard-coded), or you're dealing with inheritance.

And honestly, I'd suggest learning more about those things (object composition and inheritance), before looking too much further at different ways of doing them.

Because ultimately, it doesn't make any difference to the finished code, if you used a factory, or if you used a function which modified a generic object, or if you just used a whole lot of classes in the middle of your code... The program will run great, or will die, any way you slice it.

Where it does make a difference is in how you organize your code, and how you compose your code.
You don't really need a factory if all you're doing is making a button on the page.
If you're making a full-featured MP3 player on your page, which needs 6 buttons, a play-list, a progress-bar and a display for track name, artist name and cover art...

...NOW is a great time to start looking into factory patterns for figuring out how to put those pieces together, to ask for one thing, and have it spit out the finished product, off the assembly line.

like image 160
Norguard Avatar answered Oct 10 '22 02:10

Norguard


I think from your perspective there isn't much of a difference, but if you go one step further and implement the abstract factory pattern, or you start to polymorph your factories, you can save a lot of work every time you write a new one.

In javascript, since you can set any value to an object because the language doesnt have private values, factories can be verry powerfull and inherit most of its logic from base-classes if you work with a framework that supports OOP standarts for objects.

EDIT

Ok, one thing, in my eyes one of the most important when it comes to JavaScript and those patterns, is prototyping.

prototyping is basicly the way you define objects in javascript so the runtime actually recognizes the object and can tell it apart from other objects.

basicly only using prototypes looks like this:

var Person = function(name){
    this.name = name
}; //constructor
Person.prototype.constructor = Person;
Person.prototype.name = 'Dave';
Person.prototype.getName = function() {
    return this.name;
}

some test code:

var dave = new Person('Dave');
console.log(dave.getName());​

and finally a factory:

var PersonFactory = function(name) {
    return new Person(name);
}

Now the problem with that anotation usually is that it is poorly maintainable and it features no inheritance.

Now comes what most frameworks to: You can create helper functions building up your prototypes and even build a prototype chain. basicly you define an object that takes in another object and it resolves the other objects members into the prototypes of the desired class object, leaving open all sorts of possibilitys for inheritance etc.

some examples can be found here: http://www.ruzee.com/blog/2008/12/javascript-inheritance-via-prototypes-and-closures

i like the way mootools handles classes:

var MyClass = new Class({
Extends: MyOtherClass
Implements: [MyInterface, MyOtherInterface],

myPublicValue: null,
myOtherValue: null,


initialize: function() {
    //constructor
},

doStuff: function() {
    return 'stuff done';
}

});

Drawbacks of the mootools class system itself: -Closure Compiler doesnt like trailing commas, you tend to leave them in your code

-Allmost no IDE supports autocompletion for mootools classes (because the prototypes arent annotated in a file, could be resolved using scripts to resolve your classes into prototyped files)

Now with this there are tons of design desicions you could go for, let your factories inherit from your own prototype helper class, using the prototype helper class to create the actual factory (some recursion in here), you could resolve each object on its creation (lazy loading like) or resolve every class object on page load (be carefull, if you go into inheritance, in most implementations of it classes you derive from must be resolved first) or go any way possible.

i hope that helped out :)

(and sorry for my bad english right now, im pretty tired tonight xD)

like image 41
Vengarioth Avatar answered Oct 10 '22 03:10

Vengarioth