Upload
guest2ee5e2c
View
5.909
Download
1
Embed Size (px)
DESCRIPTION
Aaron Newton's slides from SF JS #4 on Pattern Programming and MooTools.
Citation preview
Programming To Patterns
How I used to write
How I used to write
ClassesDatePicker
FormValidatorFx
RequestSlideshow
etc...
How I used to writevar myApp = { init: function(){ myApp.apples() myApp.orange() myApp.lemons() }, apples: function(){ $$(‘div.apple’).each(function(apple) { var form = apple.getElement(‘form’); form.addEvent(‘submit’, funciton(event){ ....}); }); }, orange: function(){ $(‘orange’).getElements(‘li’).each... },
etc...
ClassesDatePicker
FormValidatorFx
RequestSlideshow
etc...
How I used to writevar myApp = { init: function(){ myApp.apples() myApp.orange() myApp.lemons() }, apples: function(){ $$(‘div.apple’).each(function(apple) { var form = apple.getElement(‘form’); form.addEvent(‘submit’, funciton(event){ ....}); }); }, orange: function(){ $(‘orange’).getElements(‘li’).each... },
etc...
ClassesDatePicker
FormValidatorFx
RequestSlideshow
etc...
This tends to get out of hand
Banging it out...<script>
window.addEvent(‘domready’, function(){
$(‘myForm’).addEvent(‘submit’, function(evt){
evt.preventDefault();
this.send({
onComplete: function(result){ ... },
update: $(‘myContainer’)
});
});
});
</script>
This is very tempting.
Pros•Writing the logic for a specific app is fast
and furious
•The test environment is the app
Pros•Writing the logic for a specific app is fast
and furious
•The test environment is the app
& Cons•It’s much harder to maintain
•A high percentage of code you write for the app isn’t reusable
Using Classes
Using Classes
var Human = new Class({isAlive: true,energy: 1,eat: function(){
this.energy++;}
});
Human
This is how MooTools does it
Using Classes
var Human = new Class({isAlive: true,energy: 1,eat: function(){
this.energy++;}
});
Human
bob
var bob = new Human();//bob.energy === 1
bob.eat();//bob.energy === 2
This is how MooTools does it
Extending Classes
Extending Classesvar Human = new Class({
initialize: function(name, age){this.name = name;this.age = age;
},isAlive: true,energy: 1,eat: function(){
this.energy++;}
});
Extending Classesvar Human = new Class({
initialize: function(name, age){this.name = name;this.age = age;
},isAlive: true,energy: 1,eat: function(){
this.energy++;}
});
var Ninja = new Class({Extends: Human,initialize: function(side, name, age){
this.side = side;this.parent(name, age);
},energy: 100,attack: function(target){
this.energy = this.energy - 5;target.isAlive = false;
}});
Extending Classesvar Human = new Class({
initialize: function(name, age){this.name = name;this.age = age;
},isAlive: true,energy: 1,eat: function(){
this.energy++;}
});
var Ninja = new Class({Extends: Human,initialize: function(side, name, age){
this.side = side;this.parent(name, age);
},energy: 100,attack: function(target){
this.energy = this.energy - 5;target.isAlive = false;
}});
Extending Classes
var bob = new Human('Bob', 25);
var Human = new Class({initialize: function(name, age){
this.name = name;this.age = age;
},isAlive: true,energy: 1,eat: function(){
this.energy++;}
});
var Ninja = new Class({Extends: Human,initialize: function(side, name, age){
this.side = side;this.parent(name, age);
},energy: 100,attack: function(target){
this.energy = this.energy - 5;target.isAlive = false;
}});
Extending Classes
var bob = new Human('Bob', 25);
var Human = new Class({initialize: function(name, age){
this.name = name;this.age = age;
},isAlive: true,energy: 1,eat: function(){
this.energy++;}
});
var Ninja = new Class({Extends: Human,initialize: function(side, name, age){
this.side = side;this.parent(name, age);
},energy: 100,attack: function(target){
this.energy = this.energy - 5;target.isAlive = false;
}});
var blackNinja = new Ninja('evil', 'Nin Tendo', 'unknown');//blackNinja.isAlive = true//blackNinja.name = 'Nin Tendo'
blackNinja.attack(bob);//bob never had a chance
Implementing Classes
Implementing Classesvar Human = new Class({
initialize: function(name, age){this.name = name;this.age = age;
},isAlive: true,energy: 1,eat: function(){
this.energy++;}
});
Implementing Classesvar Human = new Class({
initialize: function(name, age){this.name = name;this.age = age;
},isAlive: true,energy: 1,eat: function(){
this.energy++;}
});
var Warrior = new Class({energy: 100,kills: 0,attack: function(target){
if (target.energy < this.energy) {target.isAlive = false;this.kills++;
}this.energy = this.energy - 5;
}});
Implementing Classesvar Ninja = new Class({
Extends: Human,Implements: [Warrior],initialize: function(side, name, age){
this.side = side;this.parent(name, age);
}});
var Human = new Class({initialize: function(name, age){
this.name = name;this.age = age;
},isAlive: true,energy: 1,eat: function(){
this.energy++;}
});
var Warrior = new Class({energy: 100,kills: 0,attack: function(target){
if (target.energy < this.energy) {target.isAlive = false;this.kills++;
}this.energy = this.energy - 5;
}});
var Samurai = new Class({Extends: Human,Implements: [Warrior],side: 'good',energy: 1000
});
When to write a class...
When to write a class...
When to write a class...
When to write a class...
When to write a class...
Key Aspects of JS Classes
Key Aspects of JS Classes
•Shallow inheritance works best.
Key Aspects of JS Classes
•Shallow inheritance works best.
•Break up logic into small methods.
Key Aspects of JS Classes
•Shallow inheritance works best.
•Break up logic into small methods.
•Break up functionality into small classes.
Key Aspects of JS Classes
•Shallow inheritance works best.
•Break up logic into small methods.
•Break up functionality into small classes.
•Build ‘controller’ classes for grouped functionality.
Key Aspects of JS Classes
•Shallow inheritance works best.
•Break up logic into small methods.
•Break up functionality into small classes.
•Build ‘controller’ classes for grouped functionality.
•Use options and events liberally.
Key Aspects of JS Classes
•Shallow inheritance works best.
•Break up logic into small methods.
•Break up functionality into small classes.
•Build ‘controller’ classes for grouped functionality.
•Use options and events liberally.
•Don’t be afraid to refactor, but avoid breaking the interface.
Let’s look at that earlier example again
...
<script>
$(‘myForm’).addEvent(‘submit’, function(evt){
evt.preventDefault();
this.send({
onComplete: function(result){ ... },
update: $(‘myContainer’)
});
});
</script>
Program a Patternvar FormUpdater = new Class({
initialize: function(form, container, options) {this.form = $(form);this.container = $(container);this.request = new Request(options);this.attach();
},attach: function(){
this.form.addEvent(‘submit’,this.send.bind(this));
},send: function(evt){
if (evt) evt.preventDefault();this.request.send({
url: this.form.get(‘action’),onComplete: this.onComplete.bind(this)
});},onComplete: function(responseTxt){
this.container.set(‘html’, responseTxt);}
});new FormUpdater($(‘myForm’), $(‘myContainer’));
...and then extend itvar FormUpdater.Append = new Class({
Extends: FormUpdater,onComplete: function(responseTxt){
this.container.adopt(new Element(‘div’, {html: responseTxt})
);}
});new FormUpdater.Append($(‘myForm’), $(‘myTarget’));
How I write now
How I write nowvar myApp = { init: function(){ myApp.apples() myApp.orange() myApp.lemons() }, apples: function(){ new AppleGroup($$(‘div.apple’)); }, orange: function(){ new Orange($(‘orange’) },
etc...
ClassesDatePicker
FormValidatorFx
RequestSlideshow
AppleAppleGroup
Orangeetc...
How I write nowvar myApp = { init: function(){ myApp.apples() myApp.orange() myApp.lemons() }, apples: function(){ new AppleGroup($$(‘div.apple’)); }, orange: function(){ new Orange($(‘orange’) },
etc...
ClassesDatePicker
FormValidatorFx
RequestSlideshow
AppleAppleGroup
Orangeetc...
I write as little of this as possible
Pros• Small, reusable, readable, generic classes
• Only the variables are managed in a specific application
• The footprint between a specific app and your generic codebase is as small as possible - only instantiation calls
Pros• Small, reusable, readable, generic classes
• Only the variables are managed in a specific application
• The footprint between a specific app and your generic codebase is as small as possible - only instantiation calls
• Requires a bit more skill.
• Can often mean more bytes of code in the short term.
• Test driven development is a must.
& Cons
I use MooTools
I use MooTools•MooTools makes JavaScript easier (as do
all frameworks).
I use MooTools•MooTools makes JavaScript easier (as do
all frameworks).
•It encourages you to reuse your work, and to write your code to be flexible for future use.
I use MooTools•MooTools makes JavaScript easier (as do
all frameworks).
•It encourages you to reuse your work, and to write your code to be flexible for future use.
•It is designed to be extended.
I use MooTools•MooTools makes JavaScript easier (as do
all frameworks).
•It encourages you to reuse your work, and to write your code to be flexible for future use.
•It is designed to be extended.
•These are qualities of JavaScript really; MooTools just makes the interface more accessible.