Inheritance patterns

3,003 views

Published on

Published in: Technology
1 Comment
18 Likes
Statistics
Notes
No Downloads
Views
Total views
3,003
On SlideShare
0
From Embeds
0
Number of Embeds
204
Actions
Shares
0
Downloads
91
Comments
1
Likes
18
Embeds 0
No embeds

No notes for slide
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • Do you need constructor deferral?\nLike namespaced APIs?\nWill you unplug?\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • Two types of extensions:\nOptional features that add new APIs\nCore behavior implementations (fill in abstract class)\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • Inheritance patterns

    1. 1. From one, many From many, oneClass inheritance and composition patterns in YUI Luke Smith
    2. 2. It’s war
    3. 3. Being a web developer is hard. We got it.
    4. 4. Time
    5. 5. Development time VSMaintenance time
    6. 6. Development time
    7. 7. Development time • Prototyping • Structuring
    8. 8. • Prototyping• Structuring
    9. 9. ad er★L o nd G rids S Re set a★ CS ★ Module system ★ Custom Event system
    10. 10. Class structure strategies • Pseudo-classical • Prototypal • Augmentation (Class A + Class B) • Plugins • Class extensions (mixins) • MVC
    11. 11. Class structure strategies • Pseudo-classical • Prototypal • Augmentation • Plugins • Class extensions • MVC
    12. 12. Class structure strategies • Pseudo-classical Native Pseudo-classical • Prototypal • Prototypal • Augmentation • Plugins Artificial • Class extensions • MVC
    13. 13. Class structure strategies • Pseudo-classical Native • Prototypal
    14. 14. Pseudo-classical (Old school)
    15. 15. Pseudo-classicalfunction SubClass() { // constructor}SubClass.prototype = new SuperClass();SubClass.prototype.someProperty = "booga!";SubClass.prototype.someMethod = function () { ... };...SubClass.someStaticMethod = function () { ... };...
    16. 16. Pseudo-classicalY.extend = function (SubClass, SuperClass, proto, static)function SubClass() { // constructor}SubClass.prototype = new SuperClass();SubClass.prototype.someProperty = "booga!";SubClass.prototype.someMethod = function () { ... };...SubClass.someStaticMethod = function () { ... };...
    17. 17. Pseudo-classicalY.extend = function (SubClass, SuperClass, proto, static)function SubClass() { // constructor}Y.extend(SubClass, SuperClass);SubClass.prototype.someProperty = "booga!";SubClass.prototype.someMethod = function () { ... };...SubClass.someStaticMethod = function () { ... };...
    18. 18. Pseudo-classicalY.extend = function (SubClass, SuperClass, proto, static)function SubClass() { // constructor}Y.extend(SubClass, SuperClass, { someProperty: "booga!", someMethod : function () { ... }, ...});SubClass.someStaticMethod = function () { ... };...
    19. 19. Pseudo-classicalY.extend = function (SubClass, SuperClass, proto, static)function SubClass() { // constructor}Y.extend(SubClass, SuperClass, { someProperty: "booga!", someMethod : function () { ... }, ...}, { someStaticMethod: function () { ... }, ...});
    20. 20. Pseudo-classicalY.extend = function (SubClass, SuperClass, proto, static)Y.SubClass = Y.extend( function() { // constructor }, /* extends */ SuperClass, { // Instance members someProperty: "booga!", someMethod : function () { ... } }, { // Static members someStaticMethod: function () { ... } });
    21. 21. Y.extend() PROs• Creates a “clean” subclass relationship• no YUI class requirement• Preserves instanceof• SubClass.superclass (not super, but close)• Control superclass constructor execution
    22. 22. Y.extend() CONs• No multiple inheritance• Manual constructor chaining required• Constructor chaining is awkward• Constructor chaining may be costly
    23. 23. 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 ... }
    24. 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); A RD W KW // My constructor stuff A ... }
    25. 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 COST // My constructor stuff A LY? ... }
    26. 26. To sum up• Good for basic class inheritance• If you can extend Y.Base, there are more options
    27. 27. Prototypal
    28. 28. PrototypalY.extend = function(SubClass, SuperClass,...) { var superProto = SuperClass.prototype, subProto = Y.Object(superProto); SubClass.prototype = subProto; ...
    29. 29. PrototypalY.extend = function(SubClass, SuperClass,...) { var superProto = SuperClass.prototype, subProto = Y.Object(superProto); SubClass.prototype = subProto; ...
    30. 30. PrototypalY.Object = (function () { function F() {} return function (obj) { F.prototype = obj; return new F(); };})();
    31. 31. Prototypal // Old and busted SubClass.prototype = new SuperClass(); SuperClass SubClassf(n) f(n) Constructor Constructor{} {} Prototype Prototype
    32. 32. Prototypal // Old and busted SubClass.prototype = new SuperClass(); SuperClass SubClassf(n) f(n) Constructor Constructor{} {} Prototype Prototype
    33. 33. Prototypal // Old and busted SubClass.prototype = new SuperClass(); BA SuperClass D SubClassf(n) f(n) Constructor Constructor{} {} Prototype Prototype
    34. 34. Prototypal // Old and busted SubClass.prototype = new SuperClass(); SuperClass SubClassf(n) f(n) Constructor Constructor{} {} Prototype Prototype
    35. 35. Prototypal Y.Object = (function () { function F() {} return function (obj) { F.prototype = obj; return new F(); }; })(); SuperClass (anon) SubClassf(n) f(n) f(n) EMPTY Constructor Constructor Constructor{} {} {} Prototype Prototype Prototype
    36. 36. Prototypal Y.Object = (function () { function F() {} return function (obj) { F.prototype = obj; return new F(); }; })(); SuperClass (anon) SubClassf(n) f(n) f(n) EMPTY Constructor Constructor Constructor{} {} {} Prototype Prototype Prototype
    37. 37. Prototypal Y.Object = (function () { function F() {} return function (obj) { F.prototype = obj; return new F(); }; })(); SuperClass (anon) SubClassf(n) f(n) f(n) EMPTY Constructor Constructor Constructor{} {} {} Prototype Prototype Prototype
    38. 38. Prototypal Y.Object = (function () { function F() {} return function (obj) { F.prototype = obj; return new F(); }; })(); SuperClass (anon) SubClassf(n) f(n) f(n) EMPTY Constructor Constructor Constructor{} {} {} Prototype Prototype Prototype
    39. 39. PrototypalY.Object = (function () { function F() {} return function (obj) { F.prototype = obj; return new F(); };})(); (anon) f(n) EMPTY Constructor{} {} Any Object Prototype
    40. 40. PrototypalY.Object = (function () { function F() {} return function (obj) { F.prototype = obj; return new F(); };})(); (anon) f(n) EMPTY Constructor{} {} Any Object Prototype
    41. 41. PrototypalY.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
    42. 42. Factory constructorfunction Set() { var that = (this instanceof Set) ? this : Y.Object(Set.prototype); // use that instead of this [].push.apply(that._items, arguments); return that;}
    43. 43. Factory constructorfunction 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’);
    44. 44. Factory constructorfunction 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
    45. 45. Factory constructorfunction 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!
    46. 46. Factory constructorfunction 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
    47. 47. 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
    48. 48. Y.Object() CONs• No multiple inheritance• Factory constructor can promote sloppiness• Can’t use hasOwnProperty in for/in loops
    49. 49. 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
    50. 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 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;
    51. 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. 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); 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;
    53. 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 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);
    54. 54. Class structure strategies ✓ Pseudo-classical Native ✓ Prototypal • Augmentation • Plugins Artificial • Class extensions • MVC
    55. 55. Class structure strategies ✓ Pseudo-classical Native ✓ Prototypal • Augmentation • Plugins Artificial • Class extensions • MVC
    56. 56. instanceof
    57. 57. Augmentation B A C
    58. 58. AugmentationY.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);
    59. 59. AugmentationY.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. 60. AugmentationY.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. 61. AugmentationY.augment(Y.ModelList, Y.ArrayList);var list = new Y.ModelList({ ... });list.each(function (item) { ... }); ModelList Constructor ArrayList Prototype Constructor create init Prototype each item
    62. 62. AugmentationY.augment(Y.ModelList, Y.ArrayList); augmentvar list = new Y.ModelList({ ... });list.each(function (item) { ... }); ModelList Constructor ArrayList Prototype Constructor create init Prototype each each item item
    63. 63. AugmentationY.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
    64. 64. AugmentationY.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
    65. 65. AugmentationY.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
    66. 66. AugmentationY.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
    67. 67. AugmentationY.augment(Y.ModelList, Y.ArrayList);var list = new Y.ModelList({ ... }); eachlist.each(function (item) { ... }); ModelList Constructor ArrayList list Prototype Constructor create init Prototype each each item item Prototype
    68. 68. AugmentationY.augment(Y.ModelList, Y.ArrayList);var list = new Y.ModelList({ ... }); eachlist.each(function (item) { ... }); ModelList Constructor ArrayList list Prototype Constructor create init Prototype each each item item Prototype
    69. 69. AugmentationY.augment(Y.ModelList, Y.ArrayList);var list = new Y.ModelList({ ... }); eachlist.each(function (item) { ... }); ModelList Constructor ArrayList list Prototype each create Constructor 1. Copy item init Prototype each each item item Prototype
    70. 70. AugmentationY.augment(Y.ModelList, Y.ArrayList);var list = new Y.ModelList({ ... }); eachlist.each(function (item) { ... }); ModelList Constructor ArrayList list Prototype each create Constructor 1. Copy item init Prototype 2. Construct each each item item Prototype
    71. 71. AugmentationY.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
    72. 72. AugmentationY.augment = function (to, from, force, whitelist, config)Y.augment(Y.HistoryBase, Y.EventTarget, null, null, { emitFacade : true, prefix : history, preventable: false, queueable : true});
    73. 73. Y.augment() PROs• Defers constructor overhead• Can augment with multiple classes• Supports class or instance augmentation• No YUI class requirement
    74. 74. Y.augment() CONs• First augmented method call is costly• instanceof is false for augmenting classes• Consumes more memory• Limited control of constructor invocation
    75. 75. 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
    76. 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 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 */ });
    77. 77. PluginsA a a a a
    78. 78. Plugins var overlay = new Y.Overlay({ ... }); overlay.plug(Y.Plugin.Drag); overlay.dd.set(lock, true); overlay.unplug(dd);
    79. 79. Plugins var overlay = new Y.Overlay({ ... }); overlay.plug(Y.Plugin.Drag); overlay.dd.set(lock, true); overlay.unplug(dd); Overlay Constructor Attributes x y
    80. 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. 81. 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
    82. 82. 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
    83. 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. 84. 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
    85. 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 dd Attributes Constructor Attributes lock ATTRS x x ATTRS y y lock
    86. 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. 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. 88. 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
    89. 89. The requirementsHost class • Y.Plugin.Host (free in Y.Base, or add with Y.augment)Plugin class • Static NS property
    90. 90. The requirementsHost class • Y.Plugin.Host (free in Y.Base, or add with Y.augment)Plugin class • Static NS property That’s it
    91. 91. Plugins (instance) Y.Plugin.Host.prototype.plug = function (Plugin, config) { ... if (Plugin && Plugin.NS) { config.host = this; this[Plugin.NS] = new Plugin(config); } };
    92. 92. 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);
    93. 93. The contractSHOULD✓ Expect an object constructor argument with ‘host’ property
    94. 94. The contractSHOULD MAY✓ Expect an object ✓ Provide namespaced API constructor argument ✓ Modify core behavior via with ‘host’ property events or AOP
    95. 95. The contractSHOULD MAY✓ Expect an object ✓ Provide namespaced API constructor argument ✓ Modify core behavior via with ‘host’ property events or AOPMUST✓ Remove all traces when unplugged
    96. 96. The contractSHOULD MAY✓ Expect an object ✓ Provide namespaced API constructor argument ✓ Modify core behavior via with ‘host’ property events or AOPMUST MUST NOT✓ Remove all traces ✓ Modify host directly when unplugged other than add the namespace
    97. 97. 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);
    98. 98. 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
    99. 99. Plugin CONs• Fragments API• Plugin contract to restore host can add code weight• Difficult to manage competing plugins• plug() could use a little sugar
    100. 100. 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?)
    101. 101. Class Extensions B Y.Base A C
    102. 102. Class extensionsY.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: { ... } });
    103. 103. Class extensionsY.extend = function (SubClass, SuperClass, proto, static)Y.SubClass = Y.extend( NAME: ‘subsub’, /* NAME */ ‘subsub’, /* extends */ Y.Base { someProperty: ‘booga!’, someMethod : function () { ... } }, { ATTRS: { ... } });
    104. 104. Class extensionsY.extend = function (SubClass, SuperClass, proto, static)Y.SubClass = Y.extend( NAME: ‘subsub’, /* NAME */ ‘subsub’, /* extends */ Y.Base [], // <-- class extensions! { someProperty: ‘booga!’, someMethod : function () { ... } }, { ATTRS: { ... } });
    105. 105. Class extensionsY.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: { ... } });
    106. 106. Class extensionsY.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 */ });
    107. 107. Class extensionsY.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: { ... } });
    108. 108. Class extensionsY.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. 109. 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
    110. 110. 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
    111. 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 Constructor ATTRS ATTRS Constructor Prototype Prototype ATTRS Prototype
    112. 112. 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
    113. 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 styles type type Prototype Prototype Prototype
    114. 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 direction Prototype type Prototype Prototype
    115. 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. 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. 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 Prototype Prototype Prototype draw drawLines
    118. 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. 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 Prototype draw Prototype draw drawLines draw drawLines drawSeries
    120. 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 draw initializer initializer drawLines initializer initializer initializer initializer
    121. 121. Class extensions Y.LineSeries = Y.Base.create(lineSeries, Y.CartesianSeries, [ Y.Lines ], { ... }); var series = new Y.LineSeries({ ... });1. Constructors are called2. Attributes are set3. initializers are called
    122. 122. Two types of extensions 1. Class decoration Add feature APIs and Attributes 2. Core functionality Satisfy abstract class implementation
    123. 123. Class extensionsY.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]);
    124. 124. Class extensionsY.Base.mix = function(Class, ext)Y.Slider = Y.Base.create(slider, Y.SliderBase, [Y.SliderValueRange]);Y.Base.mix(Y.Slider, [Y.ClickableRail]);
    125. 125. Extensions PROs• Promotes code reuse across environments• Feature APIs are added to the prototype• Can be used to mimic MVC breakdown
    126. 126. 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
    127. 127. 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
    128. 128. MVC
    129. 129. MVCGo see Eric’s talk tomorrow
    130. 130. There ain’t just one way to do it.
    131. 131. You owe it to future-you to structure your code
    132. 132. Try out plugins and extensions
    133. 133. Invest in the future
    134. 134. Invest in the future (and use Y.Base)
    135. 135. Invest in the future (and use Y.Base) (and join us in #yui)
    136. 136. Thank you Luke Smith @ls_n

    ×