bringing classical oop into javascript

22
Bringing classical OOP into JavaScript By Dmitry Sheiko

Upload: dmitry-sheiko

Post on 06-May-2015

1.630 views

Category:

Technology


0 download

DESCRIPTION

Any diligent developer is constantly working on improving his or her code. There are plenty of books telling how to make your code better. However most of them use the language of class-based OOP. Reader must have enough of experience to reflect those classical design patterns on JavaScript. Thus, many and many developers give up on the language before mastering its true power. On the other hand, JavaScript is an incredible impressive language. I wonder if JavaScript was originally designed as a foundation on which you build your own language. About 2 years ago I had worked out a solution which developed by now into a light-weight library which brings into JavaScript everything I miss in the language as a follower of class-based OOP. All about how it is implemented and how can be used is on the slides.

TRANSCRIPT

Page 1: Bringing classical OOP into JavaScript

Bringing classical OOP into JavaScript

By Dmitry Sheiko

Page 2: Bringing classical OOP into JavaScript

Who's the dude?

I'm Dmitry Sheiko, a web developer, blogger, open source contributor.

http://dsheiko.com

@sheiko

https://github.com/dsheiko

Page 3: Bringing classical OOP into JavaScript

Eager to be a better coder?

Reading helps…

Page 4: Bringing classical OOP into JavaScript

Reflecting learned patterns on JavaScript

What the hell?! Where are all the classes, interfaces, members visibility, namespaces, mixins?!

Page 5: Bringing classical OOP into JavaScript

JavaScript is a class-free language

“JavaScript: The World's Most Misunderstood Programming Language”

Page 6: Bringing classical OOP into JavaScript

Yet JavaScript is incredibly expressive

“The expressiveness of JavaScript

provides an enormous amount of power.

Even though the language lacks certain

useful built-in features, its flexibility

allows you to add them yourself…”

Ross Harmes, Dustin Diaz. Pro JavaScript Design Patterns

Page 7: Bringing classical OOP into JavaScript

Make of JavaScript the language you need

As a class-based OOP programmer I would bring to JavaScript following : •classes with private/public members•classical inheritance (abstract class -> class -> .. -> final class) •interfaces•mixins (traits) •type hinting •entry point validators

Page 8: Bringing classical OOP into JavaScript

What look like objects in JavaScript

Somehow clumsy, isn’t it?

var o, SuperTypeConstruct = function() {}, ConstructorFunc = function() { var _privateMember = "private member"; this.publicMember = "public member"; this.privilegedMethod = function() { return _privateMember; }}ConstructorFunc.prototype = new ConstructorFunc();o = new ConstructorFunc();

Page 9: Bringing classical OOP into JavaScript

What I want it to look like

var ConcreteClass = function() { // Constructor's job var _privateMember = "private member"; return { __extends__: AbstractClass, __implements__: [Countable, Traversable], __mixin__: [Trait], publicMember: "public member", privilegedMethod: function() { return _privateMember; } }}

Page 10: Bringing classical OOP into JavaScript

Can it inherit?

With a factory it can:Function.prototype.createInstance = function () { var key, module = this, members = module.apply(this, arguments), Fn = function () {}; members.hasOwnProperty( "__extends__" ) && members[ "__extends__" ] && (module.prototype = members[ "__extends__" ].createInstance()); Fn.prototype = module.prototype; // Link to the supertype for (key in members) { // Mix in members if (members.hasOwnProperty(key)) { Fn.prototype[key] = members[key]; } } return new Fn(); };

Page 11: Bringing classical OOP into JavaScript

What about interfaces, mixins and so on?

We add with a hook any object creation control flow that we wish. Let’s just change a bit the factory:

Function.prototype.createInstance = function () { ... instance = new Fn(); jsa.Hook.invokeAll( instance, arguments ); return instance;};

Page 12: Bringing classical OOP into JavaScript

JSA Way

JSA is a light-weight library comprising factory plugins to “make of JavaScript the language I want”. Let’s see what they are.

Page 13: Bringing classical OOP into JavaScript

Widget foundation class

As good programmers we learn from the great ones, don’t we? So, let’s borrow from YUI guys some ideas of abstract widget (http://yuilibrary.com/yui/docs/widget/) . Videlicet:• Common bootstrap interface• Consistent node referencing • Built-in progressive enhancement support

Page 14: Bringing classical OOP into JavaScript

Widget abstract layer in JSA

Widget plugin declares BaseAbstract class, which makes the factory (via a hook) to auto-call bootstap methods (init, renderUI, syncUI) of every class extending this one.

The plugin also declares WidgetAbstract, which makes the factory to populate node property with node references given in HTML_PARSER property of extending class

+syncUI()

-__extends__-HTML_PARSER-settings

WidgetAbstract

+init()+renderUI()+syncUI()

BaseAbstract

+init()+renderUI()+syncUI()

-__extends__-node-settings

ConcreteModule

Page 15: Bringing classical OOP into JavaScript

Usage example(function( $, jsa ) {Widget = function( settings ) { // event handlers _handler = { onclick : function(e) { // do something } }; return { __extends__ : jsa.WidgetAbstract, HTML_PARSER : { toolbar : 'div.toolbar' }, syncUI : function() { this.node.toolbar.find( 'li' ).bind( 'click.intro', this, _handler.onclick ); } }; }; $(document).bind( 'ready.app', function () { // Document is ready Widget.createInstance({ boundingBox: $('div.intro') }); });})( jQuery, jsa );

Page 16: Bringing classical OOP into JavaScript

Mixins

Mixins provide aggregation (has-a) relation between objects, which is easy to implement especially is JavaScript. Mixin plugin only assigns a hook, which makes factory mix public members of objects given in mixin property

Mixin

+init()+renderUI()+syncUI()

-__extends__-__mixin__

ConcreteClass

1

*

Page 17: Bringing classical OOP into JavaScript

Usage example

var MixinA = { propertyA: "propertyA" }, MixinB = { propertyB: "propertyB" }, Silo = function() { return { __mixin__: [MixinA, MixinB ], ownPropery: "Own property" } },o = Silo.createInstance();console.log(o.ownPropery !== undefined ); // trueconsole.log(o. propertyA !== undefined ); // trueconsole.log(o. propertyB !== undefined ); // true

Page 18: Bringing classical OOP into JavaScript

Interfaces

Interface plugin assigns a hook, which checks if the newly born object meets the requirements of the interfaces enlisted in implement property. In order to make sure arguments match type hints, the plugin wrap the method with cross-cutting functionality, which does the check on entry point.

-__implements__

ConcreteClass

Interface

*

Page 19: Bringing classical OOP into JavaScript

Usage example

var ConcreteInterface = { requeriedMethod : ["string”] }, StrictModule = function() { return { __implements__: ConcreteInterface, requeriedMethod : function() { } } }, o = StrictModule.createInstance();// Test Module.requeriedMethod('a string'); // OKModule.requeriedMethod(555); // throws TypeError exception

Page 20: Bringing classical OOP into JavaScript

Design by Contract

Design by Contract approach provides another and more sophisticated solution of defining requirements for the objects of a type. By a contract we can define entry/exit point conditions.

-__contract__

ConcereClass

Contract

*

var Contract = { methodName: { onEntry: [ "number", aClass ], // type hints validators: [ function( arg ) { return arg > 10; }, secondArgValidator ], onExit: "string" }}

Page 21: Bringing classical OOP into JavaScript

Usage example

var ConcreteContract = { methodA : { onEntry: [ "number" ], validators: [ function(arg){ return arg > 10; } ], onExit: "string" }},EmployedModule = function() { return { __contract__: ConcreteContract, aMethod : function() { return "a string"; } }}, o = EmployedModule.createInstance();o.aMethod( 50 ); // OKo.aMethod( 1 ); // Validator fails, RangeError exception is thrown

Page 22: Bringing classical OOP into JavaScript

Fork me!

JSA project page:

Articles relevant to JSAhttp://dsheiko.com/weblog/js-application-designhttp://dsheiko.com/weblog/prototypal-inheritance-in-javascript-for-moduleshttp://dsheiko.com/weblog/design-by-contract-and-js