SlideShare a Scribd company logo
1 of 137
From one, many
 From many, one
Class inheritance and composition
         patterns in YUI



           Luke Smith
It’s war
Being a web developer
       is hard.

     We got it.
Time
Development time

   VS
Maintenance time
Development time
Development time
   • Prototyping

   • Structuring
• Prototyping

• Structuring
ad er
★L o         nd G rids
     S Re set a
★ CS
 ★ Module   system
 ★ Custom Event system
Class structure strategies


   • Pseudo-classical
   • Prototypal
   • Augmentation (Class A + Class B)
   • Plugins
   • Class extensions (mixins)
   • MVC
Class structure strategies


   • Pseudo-classical
   • Prototypal
   • Augmentation
   • Plugins
   • Class extensions
   • MVC
Class structure strategies

                • Pseudo-classical
  Native
                  Pseudo-classical
                • Prototypal
                • Prototypal
                • Augmentation
                • Plugins
  Artificial
                • Class extensions
                • MVC
Class structure strategies

                • Pseudo-classical
  Native
                • Prototypal
Pseudo-classical
     (Old school)
Pseudo-classical
function SubClass() {
  // constructor
}

SubClass.prototype = new SuperClass();
SubClass.prototype.someProperty = "booga!";
SubClass.prototype.someMethod   = function () { ... };
...

SubClass.someStaticMethod = function () { ... };
...
Pseudo-classical
Y.extend = function (SubClass, SuperClass, proto, static)


function SubClass() {
  // constructor
}

SubClass.prototype = new SuperClass();
SubClass.prototype.someProperty = "booga!";
SubClass.prototype.someMethod   = function () { ... };
...

SubClass.someStaticMethod = function () { ... };
...
Pseudo-classical
Y.extend = function (SubClass, SuperClass, proto, static)



function SubClass() {
  // constructor
}

Y.extend(SubClass, SuperClass);
SubClass.prototype.someProperty = "booga!";
SubClass.prototype.someMethod   = function () { ... };
...

SubClass.someStaticMethod = function () { ... };
...
Pseudo-classical
Y.extend = function (SubClass, SuperClass, proto, static)



function SubClass() {
  // constructor
}

Y.extend(SubClass, SuperClass, {
  someProperty: "booga!",
  someMethod : function () { ... },
  ...
});
SubClass.someStaticMethod = function () { ... };
...
Pseudo-classical
Y.extend = function (SubClass, SuperClass, proto, static)



function SubClass() {
  // constructor
}

Y.extend(SubClass,   SuperClass, {
  someProperty: "booga!",
  someMethod : function () { ... },
  ...
}, {
  someStaticMethod: function () { ... },
  ...
});
Pseudo-classical
Y.extend = function (SubClass, SuperClass, proto, static)



Y.SubClass = Y.extend(
  function() {
     // constructor
  },

  /* extends */ SuperClass,

 { // Instance members
    someProperty: "booga!",
    someMethod : function () { ... }
 },

 { // Static members
   someStaticMethod: function () { ... }
 });
Y.extend() PROs


•   Creates a “clean” subclass relationship
•   no YUI class requirement
•   Preserves instanceof
•   SubClass.superclass (not super, but close)
•   Control superclass constructor execution
Y.extend() CONs


•   No multiple inheritance
•   Manual constructor chaining required
•   Constructor chaining is awkward
•   Constructor chaining may be costly
Y.extend() CONs


•       No multiple inheritance
•       Manual constructor chaining required
•       Constructor chaining is awkward
•       Constructor chaining may be costly

    function SubClass() {
      // Chain superclass constructor
      SubClass.superclass.constructor.apply(this, arguments);

        // My constructor stuff
        ...
    }
Y.extend() CONs


•       No multiple inheritance
•       Manual constructor chaining required
•       Constructor chaining is awkward
•       Constructor chaining may be costly

    function SubClass() {
      // Chain superclass constructor
      SubClass.superclass.constructor.apply(this, arguments);
                                          A RD
                                   W KW
        // My constructor stuff   A
        ...
    }
Y.extend() CONs


•       No multiple inheritance
•       Manual constructor chaining required
•       Constructor chaining is awkward
•       Constructor chaining may be costly

    function SubClass() {
      // Chain superclass constructor
      SubClass.superclass.constructor.apply(this, arguments);
                                          A RD
                                   W KW          COST
        // My constructor stuff   A                  LY?
        ...
    }
To sum up

•   Good for basic class inheritance
•   If you can extend Y.Base, there are more options
Prototypal
Prototypal

Y.extend = function(SubClass, SuperClass,...) {
  var superProto = SuperClass.prototype,
      subProto   = Y.Object(superProto);

  SubClass.prototype = subProto;
  ...
Prototypal

Y.extend = function(SubClass, SuperClass,...) {
  var superProto = SuperClass.prototype,
      subProto   = Y.Object(superProto);

  SubClass.prototype = subProto;
  ...
Prototypal

Y.Object = (function () {
  function F() {}

  return function (obj) {
     F.prototype = obj;
     return new F();
  };
})();
Prototypal

 // Old and busted
 SubClass.prototype = new SuperClass();




 SuperClass                                  SubClass
f(n)                                      f(n)
     Constructor                               Constructor

{}                                        {}
       Prototype                                 Prototype
Prototypal

 // Old and busted
 SubClass.prototype = new SuperClass();




 SuperClass                                  SubClass
f(n)                                      f(n)
     Constructor                               Constructor

{}                                        {}
       Prototype                                 Prototype
Prototypal

 // Old and busted
 SubClass.prototype = new SuperClass();




                   BA
 SuperClass           D                      SubClass
f(n)                                      f(n)
     Constructor                               Constructor

{}                                        {}
       Prototype                                 Prototype
Prototypal

 // Old and busted
 SubClass.prototype = new SuperClass();




 SuperClass                                  SubClass
f(n)                                      f(n)
     Constructor                               Constructor

{}                                        {}
       Prototype                                 Prototype
Prototypal

 Y.Object = (function () {
   function F() {}

   return function (obj) {
      F.prototype = obj;
      return new F();
   };
 })();




 SuperClass                     (anon)         SubClass
f(n)                     f(n)               f(n)
                                EMPTY
     Constructor                                 Constructor
                              Constructor
{}                       {}                 {}
       Prototype                Prototype          Prototype
Prototypal

 Y.Object = (function () {
   function F() {}

   return function (obj) {
      F.prototype = obj;
      return new F();
   };
 })();




 SuperClass                     (anon)         SubClass
f(n)                     f(n)               f(n)
                                EMPTY
     Constructor                                 Constructor
                              Constructor
{}                       {}                 {}
       Prototype                Prototype          Prototype
Prototypal

 Y.Object = (function () {
   function F() {}

   return function (obj) {
      F.prototype = obj;
      return new F();
   };
 })();




 SuperClass                     (anon)         SubClass
f(n)                     f(n)               f(n)
                                EMPTY
     Constructor                                 Constructor
                              Constructor
{}                       {}                 {}
       Prototype                Prototype          Prototype
Prototypal

 Y.Object = (function () {
   function F() {}

   return function (obj) {
      F.prototype = obj;
      return new F();
   };
 })();




 SuperClass                     (anon)         SubClass
f(n)                     f(n)               f(n)
                                EMPTY
     Constructor                                 Constructor
                              Constructor
{}                       {}                 {}
       Prototype                Prototype          Prototype
Prototypal

Y.Object = (function () {
  function F() {}

  return function (obj) {
     F.prototype = obj;
     return new F();
  };
})();




                               (anon)
                        f(n)
                               EMPTY
                             Constructor
{}                      {}
     Any Object                Prototype
Prototypal

Y.Object = (function () {
  function F() {}

  return function (obj) {
     F.prototype = obj;
     return new F();
  };
})();




                               (anon)
                        f(n)
                               EMPTY
                             Constructor
{}                      {}
     Any Object                Prototype
Prototypal

Y.Object = (function () {
  function F() {}

  return function (obj) {
     F.prototype = obj;
     return new F();
  };
})();




                               (anon)
                        f(n)
                               EMPTY
                             Constructor
{}                      {}                    f(n)
                                                     (anon)
                                                     EMPTY
                                                   Constructor




     Any Object                Prototype   New Object
                                              {}
                                                     Prototype
Factory constructor

function Set() {
  var that = (this instanceof Set) ?
                 this :
                Y.Object(Set.prototype);

    // use that instead of this
    [].push.apply(that._items, arguments);

    return that;
}
Factory constructor

function Set() {
  var that = (this instanceof Set) ?
                 this :
                Y.Object(Set.prototype);

    // use that instead of this
    [].push.apply(that._items, arguments);

    return that;
}



var set = new Set(‘a’,’b’);
Factory constructor

function Set() {
  var that = (this instanceof Set) ?
                 this :
                Y.Object(Set.prototype);

    // use that instead of this
    [].push.apply(that._items, arguments);

    return that;
}



var set = new Set(‘a’,’b’);

set instanceof Set; // true
Factory constructor

function Set() {
  var that = (this instanceof Set) ?
                 this :
                Y.Object(Set.prototype);

    // use that instead of this
    [].push.apply(that._items, arguments);

    return that;
}



var set = Set(‘a’,’b’); // <-- OOPS! I forgot 'new'!
Factory constructor

function Set() {
  var that = (this instanceof Set) ?
                 this :
                Y.Object(Set.prototype);

    // use that instead of this
    [].push.apply(that._items, arguments);

    return that;
}



var set = Set(‘a’,’b’);

set instanceof Set; // true
Y.Object() PROs

•   Avoids copying a lot of properties
•   Can be used to make factory constructors
•   Can be used to store original values for revert
•   Any object can be the prototype
•   Avoids class explosion
Y.Object() CONs

•   No multiple inheritance
•   Factory constructor can promote sloppiness
•   Can’t use hasOwnProperty in for/in loops
To sum up

•   Useful for some internal logic patterns
•   Not a good fit for most web app problems
•   Common use suggests need for a constructor
To sum up

•     Useful for some internal logic patterns
•     Not a good fit for most web app problems
•     Common use suggests need for a constructor

    var account1 = Y.Object(accountProto);
    account1.id = 1234;
    account1.holder = 'John Q. Consumer';

    var account2 = Y.Object(accountProto);
    account2.id = 1235;
    account2.holder = 'Jane B. Investor';
To sum up

•     Useful for some internal logic patterns
•     Not a good fit for most web app problems
•     Common use suggests need for a constructor

    var account1 = Y.Object(accountProto);
    account1.id = 1234;
    account1.holder = 'John Q. Consumer';

    var account2 = Y.Object(accountProto);
    account2.id = 1235;
    account2.holder = 'Jane B. Investor';
To sum up

•     Useful for some internal logic patterns
•     Not a good fit for most web app problems
•     Common use suggests need for a constructor

    var account1 = Y.Object(accountProto);   CO
    account1.id = 1234;                        NS
    account1.holder = 'John Q. Consumer';        TR
                                                    UC
    var account2 = Y.Object(accountProto);            TO
    account2.id = 1235;                                 R
    account2.holder = 'Jane B. Investor';
To sum up

•     Useful for some internal logic patterns
•     Not a good fit for most web app problems
•     Common use suggests need for a constructor

    function Account(id, holder) {
      this.id = id;
      this.holder = holder;
    }

    var account1 = new Account(1234, 'John Q. Consumer');
    var account2 = new Account(1235, 'Jane B. Invester');
Class structure strategies

                ✓ Pseudo-classical
  Native
                ✓ Prototypal


                • Augmentation
                • Plugins
  Artificial
                • Class extensions
                • MVC
Class structure strategies

                ✓ Pseudo-classical
   Native
                ✓ Prototypal


                • Augmentation
                • Plugins
 Artificial
                • Class extensions
                • MVC
instanceof
Augmentation
    B




    A   C
Augmentation
Y.augment = function (to, from, force, whitelist, config)



Y.ModelList = Y.extend(
  function () {
     /* constructor */
     ModeList.superclass.constructor.apply(this, arguments);
  },

  Y.Base,

  { /* prototype */ },
  { /* static */ });

Y.augment(Y.ModelList, Y.ArrayList);
Augmentation
Y.augment = function (to, from, force, whitelist, config)



Y.ModelList = Y.extend(
  function () {
     /* constructor */
     ModeList.superclass.constructor.apply(this, arguments);
  },

  Y.Base,

  { /* prototype */ },
  { /* static */ });

Y.augment(Y.ModelList, Y.ArrayList);
Augmentation
Y.augment = function (to, from, force, whitelist, config)



Y.ModelList = Y.extend(
  function () {
     /* constructor */
     ModeList.superclass.constructor.apply(this, arguments);
  },

  Y.Base,

  { /* prototype */ },
  { /* static */ });

Y.augment(Y.ModelList, Y.ArrayList);
Augmentation
Y.augment(Y.ModelList, Y.ArrayList);


var list = new Y.ModelList({ ... });

list.each(function (item) { ... });



 ModelList
 Constructor
                 ArrayList
  Prototype
                  Constructor
    create
     init          Prototype
                     each
                     item
Augmentation
Y.augment(Y.ModelList, Y.ArrayList);
  augment


var list = new Y.ModelList({ ... });

list.each(function (item) { ... });



 ModelList
 Constructor
                 ArrayList
  Prototype
                  Constructor
    create
     init          Prototype
    each             each
    item             item
Augmentation
Y.augment(Y.ModelList, Y.ArrayList);


var list = new Y.ModelList({ ... });

list.each(function (item) { ... });



 ModelList
 Constructor
                 ArrayList
  Prototype
                  Constructor
    create
     init          Prototype
    each             each
    item             item
Augmentation
Y.augment(Y.ModelList, Y.ArrayList);


var list = new Y.ModelList({ ... });

list.each(function (item) { ... });



 ModelList
 Constructor
                 ArrayList                             list
  Prototype                                          Prototype
                  Constructor
    create                                             create
     init          Prototype
                                       ModelList
                                       Constructor

                                        Prototype
                                         create
                                           init
                                                        init
                                          each
                                          item




    each             each                              each
    item             item                              item
Augmentation
Y.augment(Y.ModelList, Y.ArrayList);


var list = new Y.ModelList({ ... });

list.each(function (item) { ... });



 ModelList
 Constructor
                 ArrayList                             list
  Prototype
                  Constructor
    create
     init          Prototype
                                       ModelList
                                       Constructor

                                        Prototype
                                         create
                                           init
                                          each
                                          item




    each             each
    item             item                            Prototype
Augmentation
Y.augment(Y.ModelList, Y.ArrayList);


var list = new Y.ModelList({ ... });

list.each(function (item) { ... });



 ModelList
 Constructor
                 ArrayList               list
  Prototype
                  Constructor
    create
     init          Prototype
    each             each
    item             item              Prototype
Augmentation
Y.augment(Y.ModelList, Y.ArrayList);


var list = new Y.ModelList({ ... });

     each
list.each(function (item) { ... });



 ModelList
 Constructor
                 ArrayList               list
  Prototype
                  Constructor
    create
     init          Prototype
    each             each
    item             item              Prototype
Augmentation
Y.augment(Y.ModelList, Y.ArrayList);


var list = new Y.ModelList({ ... });

     each
list.each(function (item) { ... });



 ModelList
 Constructor
                 ArrayList               list
  Prototype
                  Constructor
    create
     init          Prototype
    each             each
    item             item              Prototype
Augmentation
Y.augment(Y.ModelList, Y.ArrayList);


var list = new Y.ModelList({ ... });

     each
list.each(function (item) { ... });



 ModelList
 Constructor
                 ArrayList               list
  Prototype                              each
    create
                  Constructor                      1. Copy
                                         item
     init          Prototype
    each             each
    item             item              Prototype
Augmentation
Y.augment(Y.ModelList, Y.ArrayList);


var list = new Y.ModelList({ ... });

     each
list.each(function (item) { ... });



 ModelList
 Constructor
                 ArrayList               list
  Prototype                              each
    create
                  Constructor                      1. Copy
                                         item
     init          Prototype
                                                   2. Construct
    each             each
    item             item              Prototype
Augmentation
Y.augment(Y.ModelList, Y.ArrayList);


var list = new Y.ModelList({ ... });

list.each(function (item) { ... });



 ModelList
 Constructor
                 ArrayList               list
  Prototype                              each
    create
                  Constructor                      1. Copy
                                         item
     init          Prototype
                                                   2. Construct
    each             each                          3. Execute
    item             item              Prototype
Augmentation
Y.augment = function (to, from, force, whitelist, config)



Y.augment(Y.HistoryBase, Y.EventTarget, null, null, {
    emitFacade : true,
    prefix     : 'history',
    preventable: false,
    queueable : true
});
Y.augment() PROs

•   Defers constructor overhead
•   Can augment with multiple classes
•   Supports class or instance augmentation
•   No YUI class requirement
Y.augment() CONs

•   First augmented method call is costly
•   instanceof is false for augmenting classes
•   Consumes more memory
•   Limited control of constructor invocation
To sum up

•   Use it to simulate lazy multiple inheritance
•   Y.Base-based classes should use class extensions
•   Beware the diamond problem
•   Weigh the importance of constructor deferral
To sum up

•     Use it to simulate lazy multiple inheritance
•     Y.Base-based classes should use class extensions
•     Beware the diamond problem
•     Weigh the importance of constructor deferral

    Y.SubClass = Y.extend(
      function () {
         Y.SuperClass.apply(this, arguments);
         Y.EventTarget.apply(this, { /* config */ });
      },
      Y.SuperClass, // <-- one "official" extention class
      Y.mix({ /* prototype */ }, Y.EventTarget.prototype),
      { /* static */ });
Plugins
A
    a   a   a   a
Plugins
 var overlay = new Y.Overlay({ ... });

 overlay.plug(Y.Plugin.Drag);

 overlay.dd.set('lock', true);

 overlay.unplug('dd');
Plugins
 var overlay = new Y.Overlay({ ... });

 overlay.plug(Y.Plugin.Drag);

 overlay.dd.set('lock', true);

 overlay.unplug('dd');




   Overlay
   Constructor

    Attributes
        x
        y
Plugins
 var overlay = new Y.Overlay({ ... });

 overlay.plug(Y.Plugin.Drag);

 overlay.dd.set('lock', true);

 overlay.unplug('dd');




   Overlay
   Constructor


    Attributes
        x
        y
Plugins
 var overlay = new Y.Overlay({ ... });

 overlay.plug(Y.Plugin.Drag);

 overlay.dd.set('lock', true);

 overlay.unplug('dd');




   Overlay
                          overlay
   Constructor

    Attributes           Attributes
        x                    x

        y                    y
Plugins
 var overlay = new Y.Overlay({ ... });

 overlay.plug(Y.Plugin.Drag);

 overlay.dd.set('lock', true);

 overlay.unplug('dd');




   Overlay
   Constructor
                          overlay        Plugin.Drag
                                          Constructor
     ATTRS               Attributes
       x                     x              ATTRS
       y                     y               lock
Plugins
 var overlay = new Y.Overlay({ ... });

 overlay.plug(Y.Plugin.Drag);

 overlay.dd.set('lock', true);

 overlay.unplug('dd');




   Overlay
   Constructor
                          overlay        Plugin.Drag
                                          Constructor
     ATTRS               Attributes
       x                     x              ATTRS
       y                     y               lock
Plugins
 var overlay = new Y.Overlay({ ... });

 overlay.plug(Y.Plugin.Drag);

 overlay.dd.set('lock', true);

 overlay.unplug('dd');




   Overlay
   Constructor
                          overlay     overlay.dd   Plugin.Drag
                                      Attributes
                                                    Constructor
                         Attributes      lock
     ATTRS
       x                     x                        ATTRS
       y                     y                         lock
Plugins
 var overlay = new Y.Overlay({ ... });

 overlay.plug(Y.Plugin.Drag);

 overlay.dd.set('lock', true);

 overlay.unplug('dd');




   Overlay
   Constructor
                          overlay     overlay.dd   Plugin.Drag
                            dd        Attributes
                                                    Constructor
                         Attributes      lock
     ATTRS
       x                     x                        ATTRS
       y                     y                         lock
Plugins
 var overlay = new Y.Overlay({ ... });

 overlay.plug(Y.Plugin.Drag);

 overlay.dd.set('lock', true);

 overlay.unplug('dd');




   Overlay
   Constructor
                          overlay     overlay.dd   Plugin.Drag
                            dd        Attributes
                                                    Constructor
                         Attributes      lock
     ATTRS
       x                     x                        ATTRS
       y                     y                         lock
Plugins
 var overlay = new Y.Overlay({ ... });

 overlay.plug(Y.Plugin.Drag);

 overlay.dd.set('lock', true);

 overlay.unplug('dd');




   Overlay
   Constructor
                          overlay     overlay.dd   Plugin.Drag
                            dd        Attributes
                                                    Constructor
                         Attributes      lock
     ATTRS
       x                     x                        ATTRS
       y                     y                         lock
Plugins
 var overlay = new Y.Overlay({ ... });

 overlay.plug(Y.Plugin.Drag);

 overlay.dd.set('lock', true);

 overlay.unplug('dd');




   Overlay
   Constructor
                          overlay        Plugin.Drag
                                          Constructor
     ATTRS               Attributes
       x                     x              ATTRS
       y                     y               lock
The requirements

Host class
 •   Y.Plugin.Host (free in Y.Base, or add with Y.augment)



Plugin class
 •   Static NS property
The requirements

Host class
 •   Y.Plugin.Host (free in Y.Base, or add with Y.augment)



Plugin class
 •   Static NS property



                    That’s it
Plugins (instance)


 Y.Plugin.Host.prototype.plug = function (Plugin, config) {
   ...
   if (Plugin && Plugin.NS) {
     config.host = this;

       this[Plugin.NS] = new Plugin(config);
   }
 };
Plugins (instance)


 Y.Plugin.Host.prototype.plug = function (Plugin, config) {
   ...
   if (Plugin && Plugin.NS) {
     config.host = this;

       this[Plugin.NS] = new Plugin(config);
   }
 };




 overlay.dd.set('lock', true);

 overlay.unplug('dd');
The contract

SHOULD
✓ Expect an object
  constructor argument
  with ‘host’ property
The contract

SHOULD                   MAY
✓ Expect an object       ✓ Provide namespaced API
  constructor argument   ✓ Modify core behavior via
  with ‘host’ property     events or AOP
The contract

SHOULD                   MAY
✓ Expect an object       ✓ Provide namespaced API
  constructor argument   ✓ Modify core behavior via
  with ‘host’ property     events or AOP


MUST
✓ Remove all traces
  when unplugged
The contract

SHOULD                   MAY
✓ Expect an object       ✓ Provide namespaced API
  constructor argument   ✓ Modify core behavior via
  with ‘host’ property     events or AOP


MUST                     MUST NOT
✓ Remove all traces      ✓ Modify host directly
  when unplugged           other than add the
                           namespace
Plugins (class)

 Y.Plugin.Host.plug(Y.Overlay, Y.Plugin.Drag, {
   handles: ['.yui3-widget-hd']
 });

 var overlay = new Y.Overlay({ ... });

 overlay.dd.set('lock', true);
Plugin PROs


•   Avoids method/property naming collisions
•   Preserves host behavior when unplug()ed
•   Plug classes or instances
•   Generic plugins can work for multiple host types
•   Works on Nodes
Plugin CONs


•   Fragments API
•   Plugin contract to restore host can add code weight
•   Difficult to manage competing plugins
•   plug() could use a little sugar
to sum up

•   Flexible
•   Better in smaller numbers
•   Class Plugins vs Augmentation?
•   Free with Y.Base-based classes and Y.Nodes


         (have I mentioned that you should use Y.Base?)
Class Extensions
           B
         Y.Base




     A            C
Class extensions
Y.extend = function (SubClass, SuperClass, proto, static)


Y.SubClass = Y.extend(
  function() {
     SubClass.superclass.constructor.apply(this, arguments);
  },

  /* extends */ Y.Base

  {
      someProperty: ‘booga!’,
      someMethod : function () { ... }
  },

  {
    NAME: ‘subsub’,
    /* NAME */ ‘subsub’,
    ATTRS: { ... }
  });
Class extensions
Y.extend = function (SubClass, SuperClass, proto, static)


Y.SubClass = Y.extend(
  NAME: ‘subsub’,
  /* NAME */ ‘subsub’,

 /* extends */ Y.Base




 {
     someProperty: ‘booga!’,
     someMethod : function () { ... }
 },

 {
    ATTRS: { ... }
  });
Class extensions
Y.extend = function (SubClass, SuperClass, proto, static)


Y.SubClass = Y.extend(
  NAME: ‘subsub’,
  /* NAME */ ‘subsub’,

 /* extends */ Y.Base

 [], // <-- class extensions!

 {
     someProperty: ‘booga!’,
     someMethod : function () { ... }
 },

 {
    ATTRS: { ... }
  });
Class extensions
Y.Base.create = function(NAME, SuperClass, ext, proto, static)



Y.SubClass = Y.extend(
  NAME: ‘subsub’,
  /* NAME */ ‘subsub’,

 /* extends */ Y.Base

 [], // <-- class extensions!

 {
     someProperty: ‘booga!’,
     someMethod : function () { ... }
 },

 {
    ATTRS: { ... }
  });
Class extensions
Y.Base.create = function(NAME, SuperClass, ext, proto, static)



Y.LineSeries = Y.Base.create('lineSeries', Y.CartesianSeries,
  [ Y.Lines ],

 {
   /* Glue Y.Lines APIs to Y.CartesianSeries APIs */
 });
Class extensions
Y.Base.create = function(NAME, SuperClass, ext, proto, static)



Y.LineSeries = Y.Base.create('lineSeries', Y.CartesianSeries,
  [ Y.Lines ],

 {
   /* Glue Y.Lines APIs to Y.CartesianSeries APIs */
 });



Y.ComboSeries = Y.Base.create('comboSeries', Y.CartesianSeries,
  [ Y.Fills, Y.Lines, Y.Plots ],

 {
      /* Glue Y.Fills etc APIs to Y.CartesianSeries APIs */
 },
 {
   ATTRS: { ... }
 });
Class extensions
Y.Base.create = function(NAME, SuperClass, ext, proto, static)



Y.LineSeries = Y.Base.create('lineSeries', Y.CartesianSeries,
  [ Y.Lines ],

 {
   /* Glue Y.Lines APIs to Y.CartesianSeries APIs */
 });



Y.ComboSeries = Y.Base.create('comboSeries', Y.CartesianSeries,
  [ Y.Fills, Y.Lines, Y.Plots ],

 {
      /* Glue Y.Fills etc APIs to Y.CartesianSeries APIs */
 },
 {
   ATTRS: { ... }
 });
Class extensions
 Y.LineSeries = Y.Base.create('lineSeries', Y.CartesianSeries,
   [ Y.Lines ], { ... });

 var series = new Y.LineSeries({ ... });



  Cartesian                LineSeries                   Lines
   Constructor              Constructor               Constructor

     ATTRS                                              ATTRS

    Prototype                                          Prototype
                              ATTRS



                             Prototype
Class extensions
 Y.LineSeries = Y.Base.create('lineSeries', Y.CartesianSeries,
   [ Y.Lines ], { ... });

 var series = new Y.LineSeries({ ... });



  Cartesian                LineSeries                   Lines
   Constructor             Constructor                Constructor
                            Constructor
     ATTRS                                              ATTRS
                            Constructor
    Prototype                                          Prototype
                              ATTRS



                             Prototype
Class extensions
 Y.LineSeries = Y.Base.create('lineSeries', Y.CartesianSeries,
   [ Y.Lines ], { ... });

 var series = new Y.LineSeries({ ... });



  Cartesian                LineSeries                   Lines
   Constructor             Constructor
                            Constructor               Constructor
                            Constructor
     ATTRS                                              ATTRS
                            Constructor
    Prototype                                          Prototype
                              ATTRS



                             Prototype
Class extensions
 Y.LineSeries = Y.Base.create('lineSeries', Y.CartesianSeries,
   [ Y.Lines ], { ... });

 var series = new Y.LineSeries({ ... });



  Cartesian                LineSeries                   Lines
  Constructor               Constructor               Constructor

     ATTRS                    ATTRS                     ATTRS
    direction                                            type

      type
                                                       Prototype

   Prototype

                             Prototype
Class extensions
 Y.LineSeries = Y.Base.create('lineSeries', Y.CartesianSeries,
   [ Y.Lines ], { ... });

 var series = new Y.LineSeries({ ... });



  Cartesian                LineSeries                   Lines
  Constructor               Constructor               Constructor

     ATTRS                    ATTRS                     ATTRS
    direction                 styles                     type

      type
                                                       Prototype

   Prototype

                             Prototype
Class extensions
 Y.LineSeries = Y.Base.create('lineSeries', Y.CartesianSeries,
   [ Y.Lines ], { ... });

 var series = new Y.LineSeries({ ... });



  Cartesian                LineSeries                   Lines
  Constructor               Constructor               Constructor

     ATTRS                    ATTRS                     ATTRS
    direction                 styles                     type

      type                    direction
                                                       Prototype
                                type
   Prototype

                             Prototype
Class extensions
 Y.LineSeries = Y.Base.create('lineSeries', Y.CartesianSeries,
   [ Y.Lines ], { ... });

 var series = new Y.LineSeries({ ... });



  Cartesian                LineSeries                   Lines
  Constructor               Constructor               Constructor

     ATTRS                    ATTRS                     ATTRS
    direction                 styles                     type

      type                    direction
                                                       Prototype
                                type
   Prototype

                             Prototype
Class extensions
 Y.LineSeries = Y.Base.create('lineSeries', Y.CartesianSeries,
   [ Y.Lines ], { ... });

 var series = new Y.LineSeries({ ... });



  Cartesian                LineSeries                   Lines
  Constructor               Constructor               Constructor

     ATTRS                     ATTRS                    ATTRS
    direction                  styles                    type

      type                    direction
                                                       Prototype
                                type
   Prototype

                             Prototype
Class extensions
 Y.LineSeries = Y.Base.create('lineSeries', Y.CartesianSeries,
   [ Y.Lines ], { ... });

 var series = new Y.LineSeries({ ... });



  Cartesian                LineSeries                   Lines
  Constructor               Constructor               Constructor

     ATTRS                    ATTRS                     ATTRS

   Prototype                 Prototype                 Prototype
     draw                                              drawLines
Class extensions
 Y.LineSeries = Y.Base.create('lineSeries', Y.CartesianSeries,
   [ Y.Lines ], { ... });

 var series = new Y.LineSeries({ ... });



  Cartesian                LineSeries                   Lines
  Constructor               Constructor               Constructor

     ATTRS                    ATTRS                     ATTRS

   Prototype                 Prototype                 Prototype
     draw                                              drawLines
Class extensions
 Y.LineSeries = Y.Base.create('lineSeries', Y.CartesianSeries,
   [ Y.Lines ], { ... });

 var series = new Y.LineSeries({ ... });



  Cartesian                LineSeries                   Lines
  Constructor               Constructor               Constructor

     ATTRS                    ATTRS                     ATTRS

   Prototype                 Prototype                 Prototype
                             Prototype
     draw                        Prototype
                                   draw                drawLines
                               draw
                             drawLines

                             drawSeries
Class extensions
 Y.LineSeries = Y.Base.create('lineSeries', Y.CartesianSeries,
   [ Y.Lines ], { ... });

 var series = new Y.LineSeries({ ... });



  Cartesian                LineSeries                   Lines
  Constructor               Constructor               Constructor
                               ATTRS
     ATTRS                                              ATTRS

   Prototype                 Prototype                 Prototype
      draw
    initializer               initializer              drawLines
                                                       initializer
                              initializer
                              initializer
                              initializer
Class extensions
 Y.LineSeries = Y.Base.create('lineSeries', Y.CartesianSeries,
   [ Y.Lines ], { ... });

 var series = new Y.LineSeries({ ... });



1. Constructors are called
2. Attributes are set
3. initializers are called
Two types of extensions



    1. Class decoration
       Add feature APIs and Attributes


    2. Core functionality
       Satisfy abstract class implementation
Class extensions
Y.Base.create = function(NAME, SuperClass, ext, proto, static)



Y.Overlay = Y.Base.create('overlay', Y.Widget, [
  Y.WidgetStdMod,
  Y.WidgetPosition,
  Y.WidgetStack,
  Y.WidgetPosition,
  Y.WidgetPositionConstrain
]);
Class extensions
Y.Base.mix = function(Class, ext)



Y.Slider = Y.Base.create('slider', Y.SliderBase,
   [Y.SliderValueRange]);

Y.Base.mix(Y.Slider, [Y.ClickableRail]);
Extensions PROs


•   Promotes code reuse across environments
•   Feature APIs are added to the prototype
•   Can be used to mimic MVC breakdown
Extensions CONs


•   Requires Y.Base
•   Initialization overhead
•   Class definition only (no instance feature additions)
•   Does not work on Nodes
•   Increased potential for accidental name collisions
Extension vs Plugin

•   Extensions can be used to contribute core behavior
•   Extensions modify the class prototype, plugins are
    always namespaced
•   Feature extension constructors are always
    executed, plugin constructors on plug()
•   Feature APIs/attributes on the prototype vs class
    plugins in namespace is a stylistic choice
MVC
MVC
Go see Eric’s talk tomorrow
There ain’t just one
   way to do it.
You owe it to future-you
 to structure your code
Try out plugins and
    extensions
Invest in the future
Invest in the future
    (and use Y.Base)
Invest in the future
    (and use Y.Base)
   (and join us in #yui)
Thank you



            Luke Smith
            @ls_n

More Related Content

What's hot

The Evolution of Async-Programming (SD 2.0, JavaScript)
The Evolution of Async-Programming (SD 2.0, JavaScript)The Evolution of Async-Programming (SD 2.0, JavaScript)
The Evolution of Async-Programming (SD 2.0, JavaScript)jeffz
 
Cocoaheads Meetup / Kateryna Trofimenko / Feature development
Cocoaheads Meetup / Kateryna Trofimenko / Feature developmentCocoaheads Meetup / Kateryna Trofimenko / Feature development
Cocoaheads Meetup / Kateryna Trofimenko / Feature developmentBadoo Development
 
Jscex: Write Sexy JavaScript (中文)
Jscex: Write Sexy JavaScript (中文)Jscex: Write Sexy JavaScript (中文)
Jscex: Write Sexy JavaScript (中文)jeffz
 
data Structure Lecture 1
data Structure Lecture 1data Structure Lecture 1
data Structure Lecture 1Teksify
 
Type Driven Development with TypeScript
Type Driven Development with TypeScriptType Driven Development with TypeScript
Type Driven Development with TypeScriptGarth Gilmour
 
The Evolution of Async-Programming on .NET Platform (.Net China, C#)
The Evolution of Async-Programming on .NET Platform (.Net China, C#)The Evolution of Async-Programming on .NET Platform (.Net China, C#)
The Evolution of Async-Programming on .NET Platform (.Net China, C#)jeffz
 
Tutconstructordes
TutconstructordesTutconstructordes
TutconstructordesNiti Arora
 
C++: Constructor, Copy Constructor and Assignment operator
C++: Constructor, Copy Constructor and Assignment operatorC++: Constructor, Copy Constructor and Assignment operator
C++: Constructor, Copy Constructor and Assignment operatorJussi Pohjolainen
 
Beyond Java: 자바 8을 중심으로 본 자바의 혁신
Beyond Java: 자바 8을 중심으로 본 자바의 혁신Beyond Java: 자바 8을 중심으로 본 자바의 혁신
Beyond Java: 자바 8을 중심으로 본 자바의 혁신Sungchul Park
 
深入浅出Jscex
深入浅出Jscex深入浅出Jscex
深入浅出Jscexjeffz
 
The Evolution of Async-Programming on .NET Platform (TUP, Full)
The Evolution of Async-Programming on .NET Platform (TUP, Full)The Evolution of Async-Programming on .NET Platform (TUP, Full)
The Evolution of Async-Programming on .NET Platform (TUP, Full)jeffz
 
Machine-level Composition of Modularized Crosscutting Concerns
Machine-level Composition of Modularized Crosscutting ConcernsMachine-level Composition of Modularized Crosscutting Concerns
Machine-level Composition of Modularized Crosscutting Concernssaintiss
 
Objective-C Blocks and Grand Central Dispatch
Objective-C Blocks and Grand Central DispatchObjective-C Blocks and Grand Central Dispatch
Objective-C Blocks and Grand Central DispatchMatteo Battaglio
 
6.1.1一步一步学repast代码解释
6.1.1一步一步学repast代码解释6.1.1一步一步学repast代码解释
6.1.1一步一步学repast代码解释zhang shuren
 

What's hot (20)

Constructors & destructors
Constructors & destructorsConstructors & destructors
Constructors & destructors
 
NS2 Object Construction
NS2 Object ConstructionNS2 Object Construction
NS2 Object Construction
 
The Evolution of Async-Programming (SD 2.0, JavaScript)
The Evolution of Async-Programming (SD 2.0, JavaScript)The Evolution of Async-Programming (SD 2.0, JavaScript)
The Evolution of Async-Programming (SD 2.0, JavaScript)
 
Cocoaheads Meetup / Kateryna Trofimenko / Feature development
Cocoaheads Meetup / Kateryna Trofimenko / Feature developmentCocoaheads Meetup / Kateryna Trofimenko / Feature development
Cocoaheads Meetup / Kateryna Trofimenko / Feature development
 
Jscex: Write Sexy JavaScript (中文)
Jscex: Write Sexy JavaScript (中文)Jscex: Write Sexy JavaScript (中文)
Jscex: Write Sexy JavaScript (中文)
 
data Structure Lecture 1
data Structure Lecture 1data Structure Lecture 1
data Structure Lecture 1
 
Constructor
ConstructorConstructor
Constructor
 
Type Driven Development with TypeScript
Type Driven Development with TypeScriptType Driven Development with TypeScript
Type Driven Development with TypeScript
 
C++ idioms.pptx
C++ idioms.pptxC++ idioms.pptx
C++ idioms.pptx
 
The Evolution of Async-Programming on .NET Platform (.Net China, C#)
The Evolution of Async-Programming on .NET Platform (.Net China, C#)The Evolution of Async-Programming on .NET Platform (.Net China, C#)
The Evolution of Async-Programming on .NET Platform (.Net China, C#)
 
Tutconstructordes
TutconstructordesTutconstructordes
Tutconstructordes
 
Kotlin Starter Pack
Kotlin Starter PackKotlin Starter Pack
Kotlin Starter Pack
 
C++: Constructor, Copy Constructor and Assignment operator
C++: Constructor, Copy Constructor and Assignment operatorC++: Constructor, Copy Constructor and Assignment operator
C++: Constructor, Copy Constructor and Assignment operator
 
MFC Message Handling
MFC Message HandlingMFC Message Handling
MFC Message Handling
 
Beyond Java: 자바 8을 중심으로 본 자바의 혁신
Beyond Java: 자바 8을 중심으로 본 자바의 혁신Beyond Java: 자바 8을 중심으로 본 자바의 혁신
Beyond Java: 자바 8을 중심으로 본 자바의 혁신
 
深入浅出Jscex
深入浅出Jscex深入浅出Jscex
深入浅出Jscex
 
The Evolution of Async-Programming on .NET Platform (TUP, Full)
The Evolution of Async-Programming on .NET Platform (TUP, Full)The Evolution of Async-Programming on .NET Platform (TUP, Full)
The Evolution of Async-Programming on .NET Platform (TUP, Full)
 
Machine-level Composition of Modularized Crosscutting Concerns
Machine-level Composition of Modularized Crosscutting ConcernsMachine-level Composition of Modularized Crosscutting Concerns
Machine-level Composition of Modularized Crosscutting Concerns
 
Objective-C Blocks and Grand Central Dispatch
Objective-C Blocks and Grand Central DispatchObjective-C Blocks and Grand Central Dispatch
Objective-C Blocks and Grand Central Dispatch
 
6.1.1一步一步学repast代码解释
6.1.1一步一步学repast代码解释6.1.1一步一步学repast代码解释
6.1.1一步一步学repast代码解释
 

Similar to Inheritance patterns

Similar to Inheritance patterns (20)

Advanced JavaScript
Advanced JavaScript Advanced JavaScript
Advanced JavaScript
 
Javascript
JavascriptJavascript
Javascript
 
Ajaxworld
AjaxworldAjaxworld
Ajaxworld
 
Type script, for dummies
Type script, for dummiesType script, for dummies
Type script, for dummies
 
Demystifying Prototypes
Demystifying PrototypesDemystifying Prototypes
Demystifying Prototypes
 
Constructors.16
Constructors.16Constructors.16
Constructors.16
 
Journey of a C# developer into Javascript
Journey of a C# developer into JavascriptJourney of a C# developer into Javascript
Journey of a C# developer into Javascript
 
4front en
4front en4front en
4front en
 
Prototype
PrototypePrototype
Prototype
 
Advanced Javascript
Advanced JavascriptAdvanced Javascript
Advanced Javascript
 
Advanced Javascript
Advanced JavascriptAdvanced Javascript
Advanced Javascript
 
Advanced Javascript
Advanced JavascriptAdvanced Javascript
Advanced Javascript
 
ClassJS
ClassJSClassJS
ClassJS
 
Javascript tid-bits
Javascript tid-bitsJavascript tid-bits
Javascript tid-bits
 
front-end dev
front-end devfront-end dev
front-end dev
 
Advanced javascript
Advanced javascriptAdvanced javascript
Advanced javascript
 
Get started with YUI
Get started with YUIGet started with YUI
Get started with YUI
 
Object Oriented JavaScript
Object Oriented JavaScriptObject Oriented JavaScript
Object Oriented JavaScript
 
Java Constructor
Java ConstructorJava Constructor
Java Constructor
 
Class method
Class methodClass method
Class method
 

More from Luke Smith

Promises. The basics, from Promises/A+
Promises. The basics, from Promises/A+Promises. The basics, from Promises/A+
Promises. The basics, from Promises/A+Luke Smith
 
Debugging tips in YUI 3
Debugging tips in YUI 3Debugging tips in YUI 3
Debugging tips in YUI 3Luke Smith
 
YUI 3: Events Evolved
YUI 3: Events EvolvedYUI 3: Events Evolved
YUI 3: Events EvolvedLuke Smith
 
YUI 3 quick overview
YUI 3 quick overviewYUI 3 quick overview
YUI 3 quick overviewLuke Smith
 
YUI 3: Below the Surface
YUI 3: Below the SurfaceYUI 3: Below the Surface
YUI 3: Below the SurfaceLuke Smith
 
Front end engineering, YUI Gallery, and your future
Front end engineering, YUI Gallery, and your futureFront end engineering, YUI Gallery, and your future
Front end engineering, YUI Gallery, and your futureLuke Smith
 

More from Luke Smith (9)

Promises. The basics, from Promises/A+
Promises. The basics, from Promises/A+Promises. The basics, from Promises/A+
Promises. The basics, from Promises/A+
 
Attribute
AttributeAttribute
Attribute
 
Hack with YUI
Hack with YUIHack with YUI
Hack with YUI
 
Debugging tips in YUI 3
Debugging tips in YUI 3Debugging tips in YUI 3
Debugging tips in YUI 3
 
YUI 3: Events Evolved
YUI 3: Events EvolvedYUI 3: Events Evolved
YUI 3: Events Evolved
 
YUI 3 quick overview
YUI 3 quick overviewYUI 3 quick overview
YUI 3 quick overview
 
YUI 3: Below the Surface
YUI 3: Below the SurfaceYUI 3: Below the Surface
YUI 3: Below the Surface
 
Yui3
Yui3Yui3
Yui3
 
Front end engineering, YUI Gallery, and your future
Front end engineering, YUI Gallery, and your futureFront end engineering, YUI Gallery, and your future
Front end engineering, YUI Gallery, and your future
 

Recently uploaded

A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxLoriGlavin3
 
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality AssuranceInflectra
 
Manual 508 Accessibility Compliance Audit
Manual 508 Accessibility Compliance AuditManual 508 Accessibility Compliance Audit
Manual 508 Accessibility Compliance AuditSkynet Technologies
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxLoriGlavin3
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfMounikaPolabathina
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxLoriGlavin3
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxLoriGlavin3
 
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Alkin Tezuysal
 
Sample pptx for embedding into website for demo
Sample pptx for embedding into website for demoSample pptx for embedding into website for demo
Sample pptx for embedding into website for demoHarshalMandlekar2
 
UiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPathCommunity
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .Alan Dix
 
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesHow to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesThousandEyes
 
Potential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsPotential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsRavi Sanghani
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfNeo4j
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024Lonnie McRorey
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteDianaGray10
 
Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rick Flair
 
A Framework for Development in the AI Age
A Framework for Development in the AI AgeA Framework for Development in the AI Age
A Framework for Development in the AI AgeCprime
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersNicole Novielli
 

Recently uploaded (20)

A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
 
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
 
Manual 508 Accessibility Compliance Audit
Manual 508 Accessibility Compliance AuditManual 508 Accessibility Compliance Audit
Manual 508 Accessibility Compliance Audit
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptx
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdf
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
 
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
 
Sample pptx for embedding into website for demo
Sample pptx for embedding into website for demoSample pptx for embedding into website for demo
Sample pptx for embedding into website for demo
 
UiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to Hero
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .
 
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesHow to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
 
Potential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsPotential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and Insights
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdf
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test Suite
 
Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...
 
A Framework for Development in the AI Age
A Framework for Development in the AI AgeA Framework for Development in the AI Age
A Framework for Development in the AI Age
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software Developers
 

Inheritance patterns

  • 1. From one, many From many, one Class inheritance and composition patterns in YUI Luke Smith
  • 3. Being a web developer is hard. We got it.
  • 5. Development time VS Maintenance time
  • 7. Development time • Prototyping • Structuring
  • 8.
  • 10. ad er ★L o nd G rids S Re set a ★ CS ★ Module system ★ Custom Event system
  • 11. Class structure strategies • Pseudo-classical • Prototypal • Augmentation (Class A + Class B) • Plugins • Class extensions (mixins) • MVC
  • 12. Class structure strategies • Pseudo-classical • Prototypal • Augmentation • Plugins • Class extensions • MVC
  • 13. Class structure strategies • Pseudo-classical Native Pseudo-classical • Prototypal • Prototypal • Augmentation • Plugins Artificial • Class extensions • MVC
  • 14. Class structure strategies • Pseudo-classical Native • Prototypal
  • 15. Pseudo-classical (Old school)
  • 16. Pseudo-classical function SubClass() { // constructor } SubClass.prototype = new SuperClass(); SubClass.prototype.someProperty = "booga!"; SubClass.prototype.someMethod = function () { ... }; ... SubClass.someStaticMethod = function () { ... }; ...
  • 17. Pseudo-classical Y.extend = function (SubClass, SuperClass, proto, static) function SubClass() { // constructor } SubClass.prototype = new SuperClass(); SubClass.prototype.someProperty = "booga!"; SubClass.prototype.someMethod = function () { ... }; ... SubClass.someStaticMethod = function () { ... }; ...
  • 18. Pseudo-classical Y.extend = function (SubClass, SuperClass, proto, static) function SubClass() { // constructor } Y.extend(SubClass, SuperClass); SubClass.prototype.someProperty = "booga!"; SubClass.prototype.someMethod = function () { ... }; ... SubClass.someStaticMethod = function () { ... }; ...
  • 19. Pseudo-classical Y.extend = function (SubClass, SuperClass, proto, static) function SubClass() { // constructor } Y.extend(SubClass, SuperClass, { someProperty: "booga!", someMethod : function () { ... }, ... }); SubClass.someStaticMethod = function () { ... }; ...
  • 20. Pseudo-classical Y.extend = function (SubClass, SuperClass, proto, static) function SubClass() { // constructor } Y.extend(SubClass, SuperClass, { someProperty: "booga!", someMethod : function () { ... }, ... }, { someStaticMethod: function () { ... }, ... });
  • 21. Pseudo-classical Y.extend = function (SubClass, SuperClass, proto, static) Y.SubClass = Y.extend( function() { // constructor }, /* extends */ SuperClass, { // Instance members someProperty: "booga!", someMethod : function () { ... } }, { // Static members someStaticMethod: function () { ... } });
  • 22. Y.extend() PROs • Creates a “clean” subclass relationship • no YUI class requirement • Preserves instanceof • SubClass.superclass (not super, but close) • Control superclass constructor execution
  • 23. Y.extend() CONs • No multiple inheritance • Manual constructor chaining required • Constructor chaining is awkward • Constructor chaining may be costly
  • 24. Y.extend() CONs • No multiple inheritance • Manual constructor chaining required • Constructor chaining is awkward • Constructor chaining may be costly function SubClass() { // Chain superclass constructor SubClass.superclass.constructor.apply(this, arguments); // My constructor stuff ... }
  • 25. Y.extend() CONs • No multiple inheritance • Manual constructor chaining required • Constructor chaining is awkward • Constructor chaining may be costly function SubClass() { // Chain superclass constructor SubClass.superclass.constructor.apply(this, arguments); A RD W KW // My constructor stuff A ... }
  • 26. Y.extend() CONs • No multiple inheritance • Manual constructor chaining required • Constructor chaining is awkward • Constructor chaining may be costly function SubClass() { // Chain superclass constructor SubClass.superclass.constructor.apply(this, arguments); A RD W KW COST // My constructor stuff A LY? ... }
  • 27. To sum up • Good for basic class inheritance • If you can extend Y.Base, there are more options
  • 29. Prototypal Y.extend = function(SubClass, SuperClass,...) { var superProto = SuperClass.prototype, subProto = Y.Object(superProto); SubClass.prototype = subProto; ...
  • 30. Prototypal Y.extend = function(SubClass, SuperClass,...) { var superProto = SuperClass.prototype, subProto = Y.Object(superProto); SubClass.prototype = subProto; ...
  • 31. Prototypal Y.Object = (function () { function F() {} return function (obj) { F.prototype = obj; return new F(); }; })();
  • 32. Prototypal // Old and busted SubClass.prototype = new SuperClass(); SuperClass SubClass f(n) f(n) Constructor Constructor {} {} Prototype Prototype
  • 33. Prototypal // Old and busted SubClass.prototype = new SuperClass(); SuperClass SubClass f(n) f(n) Constructor Constructor {} {} Prototype Prototype
  • 34. Prototypal // Old and busted SubClass.prototype = new SuperClass(); BA SuperClass D SubClass f(n) f(n) Constructor Constructor {} {} Prototype Prototype
  • 35. Prototypal // Old and busted SubClass.prototype = new SuperClass(); SuperClass SubClass f(n) f(n) Constructor Constructor {} {} Prototype Prototype
  • 36. Prototypal Y.Object = (function () { function F() {} return function (obj) { F.prototype = obj; return new F(); }; })(); SuperClass (anon) SubClass f(n) f(n) f(n) EMPTY Constructor Constructor Constructor {} {} {} Prototype Prototype Prototype
  • 37. Prototypal Y.Object = (function () { function F() {} return function (obj) { F.prototype = obj; return new F(); }; })(); SuperClass (anon) SubClass f(n) f(n) f(n) EMPTY Constructor Constructor Constructor {} {} {} Prototype Prototype Prototype
  • 38. Prototypal Y.Object = (function () { function F() {} return function (obj) { F.prototype = obj; return new F(); }; })(); SuperClass (anon) SubClass f(n) f(n) f(n) EMPTY Constructor Constructor Constructor {} {} {} Prototype Prototype Prototype
  • 39. Prototypal Y.Object = (function () { function F() {} return function (obj) { F.prototype = obj; return new F(); }; })(); SuperClass (anon) SubClass f(n) f(n) f(n) EMPTY Constructor Constructor Constructor {} {} {} Prototype Prototype Prototype
  • 40. Prototypal Y.Object = (function () { function F() {} return function (obj) { F.prototype = obj; return new F(); }; })(); (anon) f(n) EMPTY Constructor {} {} Any Object Prototype
  • 41. Prototypal Y.Object = (function () { function F() {} return function (obj) { F.prototype = obj; return new F(); }; })(); (anon) f(n) EMPTY Constructor {} {} Any Object Prototype
  • 42. Prototypal Y.Object = (function () { function F() {} return function (obj) { F.prototype = obj; return new F(); }; })(); (anon) f(n) EMPTY Constructor {} {} f(n) (anon) EMPTY Constructor Any Object Prototype New Object {} Prototype
  • 43. Factory constructor function Set() { var that = (this instanceof Set) ? this : Y.Object(Set.prototype); // use that instead of this [].push.apply(that._items, arguments); return that; }
  • 44. Factory constructor function Set() { var that = (this instanceof Set) ? this : Y.Object(Set.prototype); // use that instead of this [].push.apply(that._items, arguments); return that; } var set = new Set(‘a’,’b’);
  • 45. Factory constructor function Set() { var that = (this instanceof Set) ? this : Y.Object(Set.prototype); // use that instead of this [].push.apply(that._items, arguments); return that; } var set = new Set(‘a’,’b’); set instanceof Set; // true
  • 46. Factory constructor function Set() { var that = (this instanceof Set) ? this : Y.Object(Set.prototype); // use that instead of this [].push.apply(that._items, arguments); return that; } var set = Set(‘a’,’b’); // <-- OOPS! I forgot 'new'!
  • 47. Factory constructor function Set() { var that = (this instanceof Set) ? this : Y.Object(Set.prototype); // use that instead of this [].push.apply(that._items, arguments); return that; } var set = Set(‘a’,’b’); set instanceof Set; // true
  • 48. Y.Object() PROs • Avoids copying a lot of properties • Can be used to make factory constructors • Can be used to store original values for revert • Any object can be the prototype • Avoids class explosion
  • 49. Y.Object() CONs • No multiple inheritance • Factory constructor can promote sloppiness • Can’t use hasOwnProperty in for/in loops
  • 50. To sum up • Useful for some internal logic patterns • Not a good fit for most web app problems • Common use suggests need for a constructor
  • 51. To sum up • Useful for some internal logic patterns • Not a good fit for most web app problems • Common use suggests need for a constructor var account1 = Y.Object(accountProto); account1.id = 1234; account1.holder = 'John Q. Consumer'; var account2 = Y.Object(accountProto); account2.id = 1235; account2.holder = 'Jane B. Investor';
  • 52. To sum up • Useful for some internal logic patterns • Not a good fit for most web app problems • Common use suggests need for a constructor var account1 = Y.Object(accountProto); account1.id = 1234; account1.holder = 'John Q. Consumer'; var account2 = Y.Object(accountProto); account2.id = 1235; account2.holder = 'Jane B. Investor';
  • 53. To sum up • Useful for some internal logic patterns • Not a good fit for most web app problems • Common use suggests need for a constructor var account1 = Y.Object(accountProto); CO account1.id = 1234; NS account1.holder = 'John Q. Consumer'; TR UC var account2 = Y.Object(accountProto); TO account2.id = 1235; R account2.holder = 'Jane B. Investor';
  • 54. To sum up • Useful for some internal logic patterns • Not a good fit for most web app problems • Common use suggests need for a constructor function Account(id, holder) { this.id = id; this.holder = holder; } var account1 = new Account(1234, 'John Q. Consumer'); var account2 = new Account(1235, 'Jane B. Invester');
  • 55. Class structure strategies ✓ Pseudo-classical Native ✓ Prototypal • Augmentation • Plugins Artificial • Class extensions • MVC
  • 56. Class structure strategies ✓ Pseudo-classical Native ✓ Prototypal • Augmentation • Plugins Artificial • Class extensions • MVC
  • 58. Augmentation B A C
  • 59. Augmentation Y.augment = function (to, from, force, whitelist, config) Y.ModelList = Y.extend( function () { /* constructor */ ModeList.superclass.constructor.apply(this, arguments); }, Y.Base, { /* prototype */ }, { /* static */ }); Y.augment(Y.ModelList, Y.ArrayList);
  • 60. Augmentation Y.augment = function (to, from, force, whitelist, config) Y.ModelList = Y.extend( function () { /* constructor */ ModeList.superclass.constructor.apply(this, arguments); }, Y.Base, { /* prototype */ }, { /* static */ }); Y.augment(Y.ModelList, Y.ArrayList);
  • 61. Augmentation Y.augment = function (to, from, force, whitelist, config) Y.ModelList = Y.extend( function () { /* constructor */ ModeList.superclass.constructor.apply(this, arguments); }, Y.Base, { /* prototype */ }, { /* static */ }); Y.augment(Y.ModelList, Y.ArrayList);
  • 62. Augmentation Y.augment(Y.ModelList, Y.ArrayList); var list = new Y.ModelList({ ... }); list.each(function (item) { ... }); ModelList Constructor ArrayList Prototype Constructor create init Prototype each item
  • 63. Augmentation Y.augment(Y.ModelList, Y.ArrayList); augment var list = new Y.ModelList({ ... }); list.each(function (item) { ... }); ModelList Constructor ArrayList Prototype Constructor create init Prototype each each item item
  • 64. Augmentation Y.augment(Y.ModelList, Y.ArrayList); var list = new Y.ModelList({ ... }); list.each(function (item) { ... }); ModelList Constructor ArrayList Prototype Constructor create init Prototype each each item item
  • 65. Augmentation Y.augment(Y.ModelList, Y.ArrayList); var list = new Y.ModelList({ ... }); list.each(function (item) { ... }); ModelList Constructor ArrayList list Prototype Prototype Constructor create create init Prototype ModelList Constructor Prototype create init init each item each each each item item item
  • 66. Augmentation Y.augment(Y.ModelList, Y.ArrayList); var list = new Y.ModelList({ ... }); list.each(function (item) { ... }); ModelList Constructor ArrayList list Prototype Constructor create init Prototype ModelList Constructor Prototype create init each item each each item item Prototype
  • 67. Augmentation Y.augment(Y.ModelList, Y.ArrayList); var list = new Y.ModelList({ ... }); list.each(function (item) { ... }); ModelList Constructor ArrayList list Prototype Constructor create init Prototype each each item item Prototype
  • 68. Augmentation Y.augment(Y.ModelList, Y.ArrayList); var list = new Y.ModelList({ ... }); each list.each(function (item) { ... }); ModelList Constructor ArrayList list Prototype Constructor create init Prototype each each item item Prototype
  • 69. Augmentation Y.augment(Y.ModelList, Y.ArrayList); var list = new Y.ModelList({ ... }); each list.each(function (item) { ... }); ModelList Constructor ArrayList list Prototype Constructor create init Prototype each each item item Prototype
  • 70. Augmentation Y.augment(Y.ModelList, Y.ArrayList); var list = new Y.ModelList({ ... }); each list.each(function (item) { ... }); ModelList Constructor ArrayList list Prototype each create Constructor 1. Copy item init Prototype each each item item Prototype
  • 71. Augmentation Y.augment(Y.ModelList, Y.ArrayList); var list = new Y.ModelList({ ... }); each list.each(function (item) { ... }); ModelList Constructor ArrayList list Prototype each create Constructor 1. Copy item init Prototype 2. Construct each each item item Prototype
  • 72. Augmentation Y.augment(Y.ModelList, Y.ArrayList); var list = new Y.ModelList({ ... }); list.each(function (item) { ... }); ModelList Constructor ArrayList list Prototype each create Constructor 1. Copy item init Prototype 2. Construct each each 3. Execute item item Prototype
  • 73. Augmentation Y.augment = function (to, from, force, whitelist, config) Y.augment(Y.HistoryBase, Y.EventTarget, null, null, { emitFacade : true, prefix : 'history', preventable: false, queueable : true });
  • 74. Y.augment() PROs • Defers constructor overhead • Can augment with multiple classes • Supports class or instance augmentation • No YUI class requirement
  • 75. Y.augment() CONs • First augmented method call is costly • instanceof is false for augmenting classes • Consumes more memory • Limited control of constructor invocation
  • 76. To sum up • Use it to simulate lazy multiple inheritance • Y.Base-based classes should use class extensions • Beware the diamond problem • Weigh the importance of constructor deferral
  • 77. To sum up • Use it to simulate lazy multiple inheritance • Y.Base-based classes should use class extensions • Beware the diamond problem • Weigh the importance of constructor deferral Y.SubClass = Y.extend( function () { Y.SuperClass.apply(this, arguments); Y.EventTarget.apply(this, { /* config */ }); }, Y.SuperClass, // <-- one "official" extention class Y.mix({ /* prototype */ }, Y.EventTarget.prototype), { /* static */ });
  • 78. Plugins A a a a a
  • 79. Plugins var overlay = new Y.Overlay({ ... }); overlay.plug(Y.Plugin.Drag); overlay.dd.set('lock', true); overlay.unplug('dd');
  • 80. Plugins var overlay = new Y.Overlay({ ... }); overlay.plug(Y.Plugin.Drag); overlay.dd.set('lock', true); overlay.unplug('dd'); Overlay Constructor Attributes x y
  • 81. Plugins var overlay = new Y.Overlay({ ... }); overlay.plug(Y.Plugin.Drag); overlay.dd.set('lock', true); overlay.unplug('dd'); Overlay Constructor Attributes x y
  • 82. Plugins var overlay = new Y.Overlay({ ... }); overlay.plug(Y.Plugin.Drag); overlay.dd.set('lock', true); overlay.unplug('dd'); Overlay overlay Constructor Attributes Attributes x x y y
  • 83. Plugins var overlay = new Y.Overlay({ ... }); overlay.plug(Y.Plugin.Drag); overlay.dd.set('lock', true); overlay.unplug('dd'); Overlay Constructor overlay Plugin.Drag Constructor ATTRS Attributes x x ATTRS y y lock
  • 84. Plugins var overlay = new Y.Overlay({ ... }); overlay.plug(Y.Plugin.Drag); overlay.dd.set('lock', true); overlay.unplug('dd'); Overlay Constructor overlay Plugin.Drag Constructor ATTRS Attributes x x ATTRS y y lock
  • 85. Plugins var overlay = new Y.Overlay({ ... }); overlay.plug(Y.Plugin.Drag); overlay.dd.set('lock', true); overlay.unplug('dd'); Overlay Constructor overlay overlay.dd Plugin.Drag Attributes Constructor Attributes lock ATTRS x x ATTRS y y lock
  • 86. Plugins var overlay = new Y.Overlay({ ... }); overlay.plug(Y.Plugin.Drag); overlay.dd.set('lock', true); overlay.unplug('dd'); Overlay Constructor overlay overlay.dd Plugin.Drag dd Attributes Constructor Attributes lock ATTRS x x ATTRS y y lock
  • 87. Plugins var overlay = new Y.Overlay({ ... }); overlay.plug(Y.Plugin.Drag); overlay.dd.set('lock', true); overlay.unplug('dd'); Overlay Constructor overlay overlay.dd Plugin.Drag dd Attributes Constructor Attributes lock ATTRS x x ATTRS y y lock
  • 88. Plugins var overlay = new Y.Overlay({ ... }); overlay.plug(Y.Plugin.Drag); overlay.dd.set('lock', true); overlay.unplug('dd'); Overlay Constructor overlay overlay.dd Plugin.Drag dd Attributes Constructor Attributes lock ATTRS x x ATTRS y y lock
  • 89. Plugins var overlay = new Y.Overlay({ ... }); overlay.plug(Y.Plugin.Drag); overlay.dd.set('lock', true); overlay.unplug('dd'); Overlay Constructor overlay Plugin.Drag Constructor ATTRS Attributes x x ATTRS y y lock
  • 90. The requirements Host class • Y.Plugin.Host (free in Y.Base, or add with Y.augment) Plugin class • Static NS property
  • 91. The requirements Host class • Y.Plugin.Host (free in Y.Base, or add with Y.augment) Plugin class • Static NS property That’s it
  • 92. Plugins (instance) Y.Plugin.Host.prototype.plug = function (Plugin, config) { ... if (Plugin && Plugin.NS) { config.host = this; this[Plugin.NS] = new Plugin(config); } };
  • 93. Plugins (instance) Y.Plugin.Host.prototype.plug = function (Plugin, config) { ... if (Plugin && Plugin.NS) { config.host = this; this[Plugin.NS] = new Plugin(config); } }; overlay.dd.set('lock', true); overlay.unplug('dd');
  • 94. The contract SHOULD ✓ Expect an object constructor argument with ‘host’ property
  • 95. The contract SHOULD MAY ✓ Expect an object ✓ Provide namespaced API constructor argument ✓ Modify core behavior via with ‘host’ property events or AOP
  • 96. The contract SHOULD MAY ✓ Expect an object ✓ Provide namespaced API constructor argument ✓ Modify core behavior via with ‘host’ property events or AOP MUST ✓ Remove all traces when unplugged
  • 97. The contract SHOULD MAY ✓ Expect an object ✓ Provide namespaced API constructor argument ✓ Modify core behavior via with ‘host’ property events or AOP MUST MUST NOT ✓ Remove all traces ✓ Modify host directly when unplugged other than add the namespace
  • 98. Plugins (class) Y.Plugin.Host.plug(Y.Overlay, Y.Plugin.Drag, { handles: ['.yui3-widget-hd'] }); var overlay = new Y.Overlay({ ... }); overlay.dd.set('lock', true);
  • 99. Plugin PROs • Avoids method/property naming collisions • Preserves host behavior when unplug()ed • Plug classes or instances • Generic plugins can work for multiple host types • Works on Nodes
  • 100. Plugin CONs • Fragments API • Plugin contract to restore host can add code weight • Difficult to manage competing plugins • plug() could use a little sugar
  • 101. to sum up • Flexible • Better in smaller numbers • Class Plugins vs Augmentation? • Free with Y.Base-based classes and Y.Nodes (have I mentioned that you should use Y.Base?)
  • 102. Class Extensions B Y.Base A C
  • 103. Class extensions Y.extend = function (SubClass, SuperClass, proto, static) Y.SubClass = Y.extend( function() { SubClass.superclass.constructor.apply(this, arguments); }, /* extends */ Y.Base { someProperty: ‘booga!’, someMethod : function () { ... } }, { NAME: ‘subsub’, /* NAME */ ‘subsub’, ATTRS: { ... } });
  • 104. Class extensions Y.extend = function (SubClass, SuperClass, proto, static) Y.SubClass = Y.extend( NAME: ‘subsub’, /* NAME */ ‘subsub’, /* extends */ Y.Base { someProperty: ‘booga!’, someMethod : function () { ... } }, { ATTRS: { ... } });
  • 105. Class extensions Y.extend = function (SubClass, SuperClass, proto, static) Y.SubClass = Y.extend( NAME: ‘subsub’, /* NAME */ ‘subsub’, /* extends */ Y.Base [], // <-- class extensions! { someProperty: ‘booga!’, someMethod : function () { ... } }, { ATTRS: { ... } });
  • 106. Class extensions Y.Base.create = function(NAME, SuperClass, ext, proto, static) Y.SubClass = Y.extend( NAME: ‘subsub’, /* NAME */ ‘subsub’, /* extends */ Y.Base [], // <-- class extensions! { someProperty: ‘booga!’, someMethod : function () { ... } }, { ATTRS: { ... } });
  • 107. Class extensions Y.Base.create = function(NAME, SuperClass, ext, proto, static) Y.LineSeries = Y.Base.create('lineSeries', Y.CartesianSeries, [ Y.Lines ], { /* Glue Y.Lines APIs to Y.CartesianSeries APIs */ });
  • 108. Class extensions Y.Base.create = function(NAME, SuperClass, ext, proto, static) Y.LineSeries = Y.Base.create('lineSeries', Y.CartesianSeries, [ Y.Lines ], { /* Glue Y.Lines APIs to Y.CartesianSeries APIs */ }); Y.ComboSeries = Y.Base.create('comboSeries', Y.CartesianSeries, [ Y.Fills, Y.Lines, Y.Plots ], { /* Glue Y.Fills etc APIs to Y.CartesianSeries APIs */ }, { ATTRS: { ... } });
  • 109. Class extensions Y.Base.create = function(NAME, SuperClass, ext, proto, static) Y.LineSeries = Y.Base.create('lineSeries', Y.CartesianSeries, [ Y.Lines ], { /* Glue Y.Lines APIs to Y.CartesianSeries APIs */ }); Y.ComboSeries = Y.Base.create('comboSeries', Y.CartesianSeries, [ Y.Fills, Y.Lines, Y.Plots ], { /* Glue Y.Fills etc APIs to Y.CartesianSeries APIs */ }, { ATTRS: { ... } });
  • 110. Class extensions Y.LineSeries = Y.Base.create('lineSeries', Y.CartesianSeries, [ Y.Lines ], { ... }); var series = new Y.LineSeries({ ... }); Cartesian LineSeries Lines Constructor Constructor Constructor ATTRS ATTRS Prototype Prototype ATTRS Prototype
  • 111. Class extensions Y.LineSeries = Y.Base.create('lineSeries', Y.CartesianSeries, [ Y.Lines ], { ... }); var series = new Y.LineSeries({ ... }); Cartesian LineSeries Lines Constructor Constructor Constructor Constructor ATTRS ATTRS Constructor Prototype Prototype ATTRS Prototype
  • 112. Class extensions Y.LineSeries = Y.Base.create('lineSeries', Y.CartesianSeries, [ Y.Lines ], { ... }); var series = new Y.LineSeries({ ... }); Cartesian LineSeries Lines Constructor Constructor Constructor Constructor Constructor ATTRS ATTRS Constructor Prototype Prototype ATTRS Prototype
  • 113. Class extensions Y.LineSeries = Y.Base.create('lineSeries', Y.CartesianSeries, [ Y.Lines ], { ... }); var series = new Y.LineSeries({ ... }); Cartesian LineSeries Lines Constructor Constructor Constructor ATTRS ATTRS ATTRS direction type type Prototype Prototype Prototype
  • 114. Class extensions Y.LineSeries = Y.Base.create('lineSeries', Y.CartesianSeries, [ Y.Lines ], { ... }); var series = new Y.LineSeries({ ... }); Cartesian LineSeries Lines Constructor Constructor Constructor ATTRS ATTRS ATTRS direction styles type type Prototype Prototype Prototype
  • 115. Class extensions Y.LineSeries = Y.Base.create('lineSeries', Y.CartesianSeries, [ Y.Lines ], { ... }); var series = new Y.LineSeries({ ... }); Cartesian LineSeries Lines Constructor Constructor Constructor ATTRS ATTRS ATTRS direction styles type type direction Prototype type Prototype Prototype
  • 116. Class extensions Y.LineSeries = Y.Base.create('lineSeries', Y.CartesianSeries, [ Y.Lines ], { ... }); var series = new Y.LineSeries({ ... }); Cartesian LineSeries Lines Constructor Constructor Constructor ATTRS ATTRS ATTRS direction styles type type direction Prototype type Prototype Prototype
  • 117. Class extensions Y.LineSeries = Y.Base.create('lineSeries', Y.CartesianSeries, [ Y.Lines ], { ... }); var series = new Y.LineSeries({ ... }); Cartesian LineSeries Lines Constructor Constructor Constructor ATTRS ATTRS ATTRS direction styles type type direction Prototype type Prototype Prototype
  • 118. Class extensions Y.LineSeries = Y.Base.create('lineSeries', Y.CartesianSeries, [ Y.Lines ], { ... }); var series = new Y.LineSeries({ ... }); Cartesian LineSeries Lines Constructor Constructor Constructor ATTRS ATTRS ATTRS Prototype Prototype Prototype draw drawLines
  • 119. Class extensions Y.LineSeries = Y.Base.create('lineSeries', Y.CartesianSeries, [ Y.Lines ], { ... }); var series = new Y.LineSeries({ ... }); Cartesian LineSeries Lines Constructor Constructor Constructor ATTRS ATTRS ATTRS Prototype Prototype Prototype draw drawLines
  • 120. Class extensions Y.LineSeries = Y.Base.create('lineSeries', Y.CartesianSeries, [ Y.Lines ], { ... }); var series = new Y.LineSeries({ ... }); Cartesian LineSeries Lines Constructor Constructor Constructor ATTRS ATTRS ATTRS Prototype Prototype Prototype Prototype draw Prototype draw drawLines draw drawLines drawSeries
  • 121. Class extensions Y.LineSeries = Y.Base.create('lineSeries', Y.CartesianSeries, [ Y.Lines ], { ... }); var series = new Y.LineSeries({ ... }); Cartesian LineSeries Lines Constructor Constructor Constructor ATTRS ATTRS ATTRS Prototype Prototype Prototype draw initializer initializer drawLines initializer initializer initializer initializer
  • 122. Class extensions Y.LineSeries = Y.Base.create('lineSeries', Y.CartesianSeries, [ Y.Lines ], { ... }); var series = new Y.LineSeries({ ... }); 1. Constructors are called 2. Attributes are set 3. initializers are called
  • 123. Two types of extensions 1. Class decoration Add feature APIs and Attributes 2. Core functionality Satisfy abstract class implementation
  • 124. Class extensions Y.Base.create = function(NAME, SuperClass, ext, proto, static) Y.Overlay = Y.Base.create('overlay', Y.Widget, [ Y.WidgetStdMod, Y.WidgetPosition, Y.WidgetStack, Y.WidgetPosition, Y.WidgetPositionConstrain ]);
  • 125. Class extensions Y.Base.mix = function(Class, ext) Y.Slider = Y.Base.create('slider', Y.SliderBase, [Y.SliderValueRange]); Y.Base.mix(Y.Slider, [Y.ClickableRail]);
  • 126. Extensions PROs • Promotes code reuse across environments • Feature APIs are added to the prototype • Can be used to mimic MVC breakdown
  • 127. Extensions CONs • Requires Y.Base • Initialization overhead • Class definition only (no instance feature additions) • Does not work on Nodes • Increased potential for accidental name collisions
  • 128. Extension vs Plugin • Extensions can be used to contribute core behavior • Extensions modify the class prototype, plugins are always namespaced • Feature extension constructors are always executed, plugin constructors on plug() • Feature APIs/attributes on the prototype vs class plugins in namespace is a stylistic choice
  • 129. MVC
  • 130. MVC Go see Eric’s talk tomorrow
  • 131. There ain’t just one way to do it.
  • 132. You owe it to future-you to structure your code
  • 133. Try out plugins and extensions
  • 134. Invest in the future
  • 135. Invest in the future (and use Y.Base)
  • 136. Invest in the future (and use Y.Base) (and join us in #yui)
  • 137. Thank you Luke Smith @ls_n

Editor's Notes

  1. \n
  2. \n
  3. \n
  4. \n
  5. \n
  6. \n
  7. \n
  8. \n
  9. \n
  10. \n
  11. \n
  12. \n
  13. \n
  14. \n
  15. \n
  16. \n
  17. \n
  18. \n
  19. \n
  20. \n
  21. \n
  22. \n
  23. \n
  24. \n
  25. \n
  26. \n
  27. \n
  28. \n
  29. \n
  30. \n
  31. \n
  32. \n
  33. \n
  34. \n
  35. \n
  36. \n
  37. \n
  38. \n
  39. \n
  40. \n
  41. \n
  42. \n
  43. \n
  44. \n
  45. \n
  46. \n
  47. \n
  48. \n
  49. \n
  50. \n
  51. \n
  52. \n
  53. \n
  54. \n
  55. \n
  56. \n
  57. \n
  58. \n
  59. \n
  60. \n
  61. \n
  62. \n
  63. \n
  64. \n
  65. \n
  66. \n
  67. \n
  68. \n
  69. \n
  70. \n
  71. \n
  72. \n
  73. \n
  74. \n
  75. \n
  76. \n
  77. \n
  78. \n
  79. \n
  80. \n
  81. \n
  82. \n
  83. \n
  84. \n
  85. \n
  86. \n
  87. \n
  88. \n
  89. \n
  90. \n
  91. \n
  92. \n
  93. \n
  94. \n
  95. \n
  96. \n
  97. \n
  98. \n
  99. \n
  100. \n
  101. \n
  102. \n
  103. \n
  104. \n
  105. \n
  106. \n
  107. \n
  108. \n
  109. \n
  110. \n
  111. \n
  112. \n
  113. \n
  114. \n
  115. \n
  116. \n
  117. \n
  118. \n
  119. \n
  120. \n
  121. \n
  122. \n
  123. \n
  124. \n
  125. \n
  126. \n
  127. \n
  128. \n
  129. \n
  130. \n
  131. \n
  132. \n
  133. \n
  134. \n
  135. \n
  136. \n
  137. \n
  138. \n
  139. \n
  140. \n
  141. \n
  142. \n
  143. \n
  144. \n
  145. \n
  146. \n
  147. \n
  148. \n
  149. \n
  150. \n
  151. \n
  152. \n
  153. \n
  154. \n
  155. \n
  156. \n
  157. \n
  158. \n
  159. \n
  160. \n
  161. \n
  162. \n
  163. \n
  164. \n
  165. Do you need constructor deferral?\nLike namespaced APIs?\nWill you unplug?\n
  166. \n
  167. \n
  168. \n
  169. \n
  170. \n
  171. \n
  172. \n
  173. \n
  174. \n
  175. \n
  176. \n
  177. \n
  178. \n
  179. \n
  180. \n
  181. \n
  182. \n
  183. \n
  184. \n
  185. \n
  186. \n
  187. \n
  188. \n
  189. \n
  190. \n
  191. \n
  192. \n
  193. \n
  194. \n
  195. \n
  196. \n
  197. \n
  198. \n
  199. \n
  200. \n
  201. \n
  202. \n
  203. \n
  204. \n
  205. \n
  206. \n
  207. \n
  208. \n
  209. \n
  210. \n
  211. \n
  212. \n
  213. \n
  214. \n
  215. \n
  216. \n
  217. \n
  218. \n
  219. \n
  220. \n
  221. \n
  222. \n
  223. \n
  224. \n
  225. \n
  226. \n
  227. \n
  228. \n
  229. Two types of extensions:\nOptional features that add new APIs\nCore behavior implementations (fill in abstract class)\n
  230. \n
  231. \n
  232. \n
  233. \n
  234. \n
  235. \n
  236. \n
  237. \n
  238. \n
  239. \n
  240. \n
  241. \n
  242. \n
  243. \n