¿Para qué otro framework más?
Existen en la red multitud de frameworks para facilitar la tarea del desarrollador Web (tarea, por otro lado, bastante ingrata sin el uso de alguno o varios de estos frameworks). En general, la mayoría de ellos se centran en facilitar el acceso al DOM, las llamadas AJAX, e incluso ofrecer un entorno para desarrollo de interfaces de usuario. Sin embargo, Joose se distingue de sus alternativas por enfocarse en el área quizá mas pobre de JavaScript, la orientación a objetos. A pesar de que otros frameworks como Prototype o Dojo ofrecen sus propios métodos para conseguir "más o menos" orientación a objetos en JavaScript, ninguno se acerca a la funcionalidad y organización de Joose. Según los propios desarrolladores, Joose ofrece "orientación a objetos postmoderna" en JavaScript.
Características básicas
No os voy a aburrir con detalles de implementación o documentación exhaustiva (la página os puede proporcionar mucha información), pero os cuento cosas que me han sorprendido gratamente:
- Mecanismos habituales en la OO, como herencia (múltiple), interfaces, clases abstractas, singletons, etc, pero bien hecho.
- Getters y Setters automáticos
- Paquetes (espacios de nombres)
- Roles (interfaces con esteroides)
- Filosofía cercana a la orientación a aspectos
- Persistencia automática de objetos con el storage de HTML5 y (creo) con recursos remotos usando AJAX
- Reflexión de código y otras cosas chungas que sólo Sebas comprende
Show me the code!
Role (interfaz) Printable, que requiere implementar el toString:
Role("Printable", {
requires: "toString"
});
Clase Abstracta Exp, con un método estático (de clase). Implementa Printable:
Class("Exp", {
does: Printable,
methods: {
toString: function(){},
count4: function(){},
getValue: function(){}
},
classMethods: {
findExpresion(number) {
// Resuelvelo tu
}
}
});
Clase Op, que hereda de Exp:
Class("Op", {
isa: Exp,
has: {
_operand: {is: "rw"},
_left: {is: "rw"},
_right: {is: "rw"}
},
override: {
toString: function() {
return "(" + this._left.toString() + this._operand + this._right.toString() + ")"
},
count4: function() {
return this._left.count4() + this._right.count4()
},
getValue: function() {
var result;
switch(this._operand) {
case "+":
result = this._left.getValue() + this._right.getValue();
break;
case "-":
result = this._left.getValue() - this._right.getValue();
break;
case "*":
result = this._left.getValue() * this._right.getValue();
break;
case "/":
if (this._left.getValue() % this._right.getValue() == 0) {
result = this._left.getValue() / this._right.getValue();
} else {
throw "ValueError";
}
break;
}
return result;
}
}
});
Clase Num, que también hereda de Exp:
Class("Num", {
isa: Exp,
has: {
_value: {is: "rw"}
},
override: {
toString: function() {
return this._value
},
count4: function() {
var stringifiedNumber = this._value + "";
return countOcurrences(stringifiedNumber, '4');
},
getValue: function() {
return this._value;
}
}
});
Por último,una pequeña prueba de unidad (se usa el console.log que ofrece Firebug). Además, una función auxiliar que siendo puristas habría que haber metido en una clase.
countOcurrences = function(text, character) {
return (text.length - text.replace(new RegExp(character,"g"), '').length / text.length);
}
var exp = new Op({
operand: '-',
left: new Num({value: 44}),
right: new Op({
operand: '*',
left: new Num({value:4}),
right: new Num({value:4})})});
console.log(exp.toString());
console.log(exp.count4());
console.log(exp.getValue());
Esto es todo por hoy, espero que os haya gustado, y procuraré postear más a menudo.
Javi, supongo que los títulos los prefieres grandes pero, ¿no deberías usar h4 en lugar de h2 para las secciones dentro de un h3?
ResponderEliminar@Sebas: Corregido, es lo que pasa cuando no sabes que el título principal es un h3.
ResponderEliminar