SlideShare ist ein Scribd-Unternehmen logo
1 von 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

Weitere ähnliche Inhalte

Was ist angesagt?

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
 
Jscex: Write Sexy JavaScript (中文)
Jscex: Write Sexy JavaScript (中文)Jscex: Write Sexy JavaScript (中文)
Jscex: Write Sexy JavaScript (中文)
jeffz
 
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
Tutconstructordes
Niti 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 operator
Jussi Pohjolainen
 
深入浅出Jscex
深入浅出Jscex深入浅出Jscex
深入浅出Jscex
jeffz
 
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
 
6.1.1一步一步学repast代码解释
6.1.1一步一步学repast代码解释6.1.1一步一步学repast代码解释
6.1.1一步一步学repast代码解释
zhang shuren
 

Was ist angesagt? (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代码解释
 

Ähnlich wie Inheritance patterns

Constructors.16
Constructors.16Constructors.16
Constructors.16
myrajendra
 
Advanced Javascript
Advanced JavascriptAdvanced Javascript
Advanced Javascript
Adieu
 
Get started with YUI
Get started with YUIGet started with YUI
Get started with YUI
Adam Lu
 

Ähnlich wie 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
 

Mehr von Luke Smith

Mehr von 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
 

Kürzlich hochgeladen

IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
Enterprise Knowledge
 

Kürzlich hochgeladen (20)

🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 

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

Hinweis der Redaktion

  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