¿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