#

# Example: Compose Classes of Objects with `augment`

Creating a composition-based class structure using `augment`

### Using `augment`

    YUI().use('node', function(Y) {
        // This method is in the 'oop' module.  Since we require 'node'
        // for this example, and 'node' requires 'oop', the 'oop' module
        // will be loaded automatically.

### The example: Any class can be an `EventTarget`

This example creates a custom class, then augments it with `EventTarget`. Using the packaged functionality of `EventTarget`, the code for `Foo` is able to focus on the functionality unique to its purpose.

    YUI().use('node', function(Y) {
        // This method is in the 'oop' module.  Since we require 'node'
        // for this example, and 'node' requires 'oop', the 'oop' module
        // will be loaded automatically.

        var Foo = function() {
            /* code specific to Foo */
            this.publish('interestingMoment');
        };

        Foo.prototype.doSomething = function() {

            var eventData = {};

            // -- do something interesting, add results to eventData --

            eventData.statusText = 'bar';

            // notify the subscribers, passing the event data
            this.fire('interestingMoment', eventData);
        }

        Y.augment(Foo, Y.EventTarget);

        var foo = new Foo();

        // add some event listeners
        foo.on('interestingMoment', function (data) {
            var p = Y.one('#demo_p1');
            p.setHTML('I was notified of an interesting moment: ' + data.statusText);
        });

        foo.on('interestingMoment', function (data) {
            var p = Y.one('#demo_p2');
            p.setHTML('I was also notified of an interesting moment: ' + data.statusText);
        });

        Y.on('click', function() {
            foo.doSomething();
        }, '#demo_btn');
    });

### Composition, not inheritance

If `Foo` were a part of a class hierarchy, it would be improper to include `EventTarget` in the inheritance chain, because its custom event functionality is not an intrinsic characteristic but rather an ancillary, generic capability that many classes share.

Unlike `extend`ed classes, the relationship between a class and the classes augmenting it is not an indication of type hierarchy. The intent of `augment` is to aid in extracting nonessential behaviors or behaviors shared by many classes, allowing for a composition-style class architecture.

This may appear similar to multiple inheritance, but it's not. `augment` simply adds the public methods and members from one class prototype to another class prototype. Instances of the augmented class will not pass `instanceof` tests for the class(es) which augmented it.

    YUI().use('oop', function(Y) {

        function Foo() {}
        Foo.prototype.doSomething = function () { /* something */ };

        function Bar() {}
        Y.augment(Bar, Foo);

        var b = new Bar();
        if (b instanceof Bar) {} // true
        if (b instanceof Foo) {} // FALSE
    });