¿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.
 
 
 
 Entradas
Entradas
 
 
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