5

So I'm learning about design patterns in school. Many of them are silly little ideas, but nevertheless solve some recurring problems(singleton, adapters, asynchronous polling, ect). But today I was told about the so called 'Prototype' design pattern.

I must be missing something, because I don't see any benefits from it. I've seen people online say it's faster than using "new"' but this is doesn't make any sense, since at some point, regardless how the new object is created, memory needs to be allocated for it ect.

Furthermore, doesn't this pattern run in the same circles as the 'chicken or egg' problem? By this I mean, since the prototype pattern essentially is just cloning objects, at some point the original object must be created itself (ie, not cloned). So this would mean, that I would need to have an existing copy of every object that I would ever want to clone already ready to clone? Seems stupid to me.

Can anyone explain what the use of this pattern is?

Original post: https://stackoverflow.com/questions/13887704/whats-the-point-of-the-prototype-design-pattern

2
  • 8
    What can we tell you that the original post (on which you already accepted an answer) doesn't already provide? Commented Dec 15, 2012 at 0:04
  • @RobertHarvey: If you look at the other post someone commented that it might be better suited for (then) Programmers.SO. The username who posted the question is the same as well. Commented Mar 31, 2017 at 12:33

4 Answers 4

5

Allocating memory might not be the slow part of creating your object. If the object is data driven or otherwise the result of a calculation, it is sometimes prudent to cache the result so that that result can be cloned rather than re-done. Thus, the Prototype pattern.

3

This pattern can be used when the creation of the object is costly. For example, consider a class that requires configuration data from a file /database / over a network for initializing. This kind of operations make the object creation very costly especially if you want to create multiple objects of such type.

Have a look at this link.

0
2

There are lots of uses for Prototype, small and large...JavaScript and Io are both prototype based languages for instance. In one sense it is object based inheritance (vs class based), which is a pretty cool concept, IMO.

From a nuts and bolts design pattern perspective, Prototype works well if you have some specific case where the "cost" of creating an object is high, does not consist of only memory allocation, and you need more than one instance of that object...the higher the count the more useful the pattern.

Because of its general utility for solving this specific case, Prototype combos well with other design patterns; its frequently listed as complementary to other patterns in the GoF book.


Tangent

You can also do some fun little tricks w/ Prototype. For instance I recall a custom snippets based code generator utility I wrote a number of years ago that had a CodeScripter prototype that had a few instance specific things like target path, filename, some metadata options, and a mechanism to specify which snippets to use in what order...it pulled in a bunch of different templates from files on disk on creation, and then specific output scenarios would clone the CodeScripter thus avoiding the initialization cost, push in the appropriate info for the instance, and configure the appropriate selection of ordered snippets.

Of course, I could have solved that problem a lot of ways, but though it had its downside* the volume of outputs that needed to be generated and the fact that most of the scenarios were very similar and there was a high overlap in the snippets made Prototype a neat option.



* The downside was that the CodeScripter prototype was unabashedly a god object...but in the case of that utility I found it to be an acceptable tradeoff.

0

Build an object going around its constructor. It seems confusing, a favourable chance for an imagination exercise omitting the theory just by its name, prototype design pattern, it's close to templating in that it centralises the description of an object; to get a sense of a proper use of it consider the used programming language. With strongly typed programming languages might be less obvious that it is different with loosely typed programming languages being possible to create objects without previously defining a type.

With JavaScript among others, objects can be created using object literals...

var line = { fromX: 0, fromY: 0, toX: 0, toY: 0 };
var anotherLine = { fromX: 0, fromY: 0, toX: 0, toY: 0 };
var otherLine = { fromX: 0, fromY: 0, toX: 0, toY: 0 };

...that with prototype pattern may be defined in a single place...

var liner = () => {
    return { fromX: 0, fromY: 0, toX: 0, toY: 0 };
};

...and then it can be used calling the function returning it:

var liner = () => { return { fromX: 0, fromY: 0, toX: 0, toY: 0 }; };
var lined = (function() {
    
    return (function() {
        var originX = void(0);
        var originY = void(0);
        var toX = void(0);
        var toY = void(0);

        return { from : function(x, y) { originX = x; originY = y; return this; }
               , to : function(x, y) { toX = x; toY = y; return this; }
               , supply : function() { 
                     
                     var line = liner(); // get the prototype
                     line.fromX = originX;
                     line.fromY = originY;
                     line.toX = toX;
                     line.toY = toY;

                     return line;
               }};
     })();
})();

var line = lined.from(1, 1).to(10, 10).supply();
var anotherLine = lined.from(5, 5).to(10, 10).supply();
var otherLine = lined.from(20, 20).to(10, 10).supply();

Without line definition from liner function the object literal would have been spread all over the code turning it into a difficult to maintain one.

Prototype pattern is handy also to find out whether objects are or aren't of a certain type. With some boiler plate code...

var fields = (() => {
    
    var source = {};
    
    return { of: function(object) { source = object; return this; }
           , to: { array: function() {
                         var fields = [];
                         for ( var field in source ) {
                            fields.push(field);
                         }
                         return fields;
            }}};
})();

var is = function(object) {
    
    return { type : { of : function(type) {
                        var guidee = fields.of(object).to.array();
                        var guide = fields.of(type).to.array();
                        var congruous = guide.length == guidee.length;
                        for ( var field in guide ) {
                            congruous = congruous && field in guidee;
                        }
                        return congruous;
}}};};

...line type congruousness could be found in a blink of an eye...

var guidline = liner();

var lineType = is(line).type.of(guideline);
var anotherType = is(anotherLine).type.of(guideline);
var otherType = is(otherLine).type.of(guideline);

... all last three variables being true.

This is what I imagine the prototype design pattern is about. Pardon the rambling.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.