Pair program with me! profile for carousel at Stack Overflow, Q&A for professional and enthusiast programmers

2/20/2013

What is a helper method ?

You probably heard about them, and use them but you didn't know that. Helper methods are usually  provided by the library. Underscore.js _.each function is widely used helper method throught many libraries.

Here's a nice definiton, from the classic perspective:

Helpers are one consequence of composed methods. If you are going to divide big methods into several smaller ones, you need those smaller methods. These are the helpers. Their purpose is to make larger-scale computations more readable by hiding temporarily irrelevant details and giving you a chance to express your intention through the name of the method. Helpers are typically declared private, moving to protected if the class is intended to be refined by subclassing.
 And example from Backbone.js library:

 
 
  function (attributes, options) {
    var defaults;
    var attrs = attributes || {};
    this.cid = _.uniqueId('c');
    this.attributes = {};
    if (options && options.collection) this.collection = options.collection;
    if (options && options.parse) attrs = this.parse(attrs, options) || {};
    if (defaults = _.result(this, 'defaults')) {
      attrs = _.defaults({}, attrs, defaults);
    }
    this.set(attrs, options);
    this.changed = {};
    this.initialize.apply(this, arguments);
  }
Above, you can see Backbone.Model method, which needs to be instantiated. Model is full of properties, but it is not ment to serve as constructor. For that purpose we use Backbone.Model.extend method, which simply helps establishing inheritance and providing bridge between Model and instance:
function (protoProps, staticProps) {
    var parent = this;
    var child;

    // The constructor function for the new subclass is either defined by you
    // (the "constructor" property in your `extend` definition), or defaulted
    // by us to simply call the parent's constructor.
    if (protoProps && _.has(protoProps, 'constructor')) {
      child = protoProps.constructor;
    } else {
      child = function(){ return parent.apply(this, arguments); };
    }

    // Add static properties to the constructor function, if supplied.
    _.extend(child, parent, staticProps);

    // Set the prototype chain to inherit from `parent`, without calling
    // `parent`'s constructor function.
    var Surrogate = function(){ this.constructor = child; };
    Surrogate.prototype = parent.prototype;
    child.prototype = new Surrogate;

    // Add prototype properties (instance properties) to the subclass,
    // if supplied.
    if (protoProps) _.extend(child.prototype, protoProps);

    // Set a convenience property in case the parent's prototype is needed
    // later.
    child.__super__ = parent.prototype;

    return child;
  }

It is possible to keep together Model and extend. It is not good design approach, cause we will sacrifice modular approach (among others pitfalls). Choosing to separate main method on two loose coupled parts, we are making extend methond reusable to other parts of our code. As you can see, Backbone authors did exactly that - you can extend Model,View,Router,History and Collection with one helper function.

Happy Coding

No comments:

Post a Comment