Skip to content

Instantly share code, notes, and snippets.

@vstarck
Created August 10, 2012 15:58
Show Gist options
  • Save vstarck/3315222 to your computer and use it in GitHub Desktop.
Save vstarck/3315222 to your computer and use it in GitHub Desktop.
exercise.js
var app = {
uid: (function() {
var seed = 0;
return function() {
return seed++;
};
})(),
create: function(model, opts) {
var instance = new app.model[model](opts);
instance.id = app.uid();
app.merge(instance, opts);
return instance;
},
merge: function(target) {
var merge = [].slice.call(arguments, 1);
merge.forEach(function(current) {
for(var p in current) {
if(current.hasOwnProperty(p)) {
target[p] = current[p];
}
}
});
},
xetterize: function(o, fields) {
fields.forEach(function(current) {
var name = current.replace(/./, function(c) { return c.toUpperCase() });
o['set' + name] = function(value) {
this[current] = value;
return this;
};
o['get' + name] = function() {
return this[current];
};
});
},
extend: function(f, parent) {
var p = new parent;
f.prototype = p;
f.prototype.constructor = f;
f.prototype.super = p;
},
model: function(name, opts) {
var C = function() {
if(this.super && this.super.init) {
this.super.init.apply(this, arguments);
}
if(this.init) {
this.init.apply(this, arguments);
}
};
if(opts.extend) {
app.extend(C, opts.extend);
}
opts.fields = opts.fields || [];
opts.fields.push('id');
app.xetterize(C.prototype, opts.fields);
app.merge(C.prototype, opts.body || {});
app.merge(C, opts.static || {});
app.model[name] = C;
return this;
}
};
app.model('Company', {
fields: ['name', 'employees'],
body: {
init: function(opts) {
this.employees = [];
},
addEmployee: function(employee) {
if(!(employee instanceof app.model.Employee)) {
throw new Error('Invalid employee: ' + employee);
}
this.employees.push(employee);
return this;
},
setEmployees: null,
getEmployees: function() {
return this.employees.concat();
},
findEmployees: function(fn) {
return this.getEmployees().reduce(function(memo, current) {
if(fn(current)) {
memo.push(current);
}
return memo;
}, []);
},
getEmployeeById: function(id) {
return this.findEmployees(function(current) {
return current.getId() == id;
})[0] || null;
}
}
});
app.model('Employee', {
fields: ['name', 'lastName', 'age', 'type'],
body: {
setType: function(type) {
if(!this.constructor.TYPE[type]) {
throw new Error('Invalid type: ' + type);
}
this.type = type;
return this;
}
}
});
app.model('Developer', {
extend: app.model.Employee,
static: {
TYPE: {
PHP: 'PHP',
PYTHON: 'PYTHON',
JAVASCRIPT: 'JAVASCRIPT'
}
}
});
app.model('Designer', {
extend: app.model.Employee,
static: {
TYPE: {
WEB: 'WEB',
GRAPHIC: 'GRAPHIC'
}
}
});
//--------------------------------------------
var summa = app.create('Company', {
name: 'Summa'
});
// Add employees
summa
.addEmployee(
app.create('Developer', {
name: 'Agustin',
lastName: 'Didiego',
age: 38,
type: app.model.Developer.TYPE.PHP
})
)
.addEmployee(
app.create('Developer', {
name: 'Valentin',
lastName: 'Starck',
age: 25,
type: app.model.Developer.TYPE.JAVASCRIPT
})
)
.addEmployee(
app.create('Developer', {
name: 'Jose',
lastName: 'De los Palotes',
age: 21,
type: app.model.Developer.TYPE.PYTHON
})
);
var aDesigner = app.create('Designer');
aDesigner.setName('Brenda');
aDesigner.setLastName('Herrada');
aDesigner.setAge(26);
try {
aDesigner.setType(1);
} catch(e) {} //Error: Invalid type: 1
aDesigner.setType(app.model.Designer.TYPE.WEB);
summa.addEmployee(aDesigner);
summa.getEmployees().length // 4
// Find employees
summa.findEmployees(function(employee) {
return employee.getAge() < 30;
}).length; // 3
summa.getEmployeeById(2).getName(); // "Valentin"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment