Не мастак я придумывать красивые заголовки, но в этом случае придумал бы с удовольствием. Потому как опять про Qooxdoo.

Я, наверное, потихоньку влюбляюсь в этот продукт и этих ребят. Первый раз их увидел когда еще писал на PHP (да, я раньше был извращенцем, но я исправился). Тогда я повосхищался их кнопочками и менюшечками, показал знакомым программерам... В общем знакомство состоялось. Второй раз я за них взялся уже более-менее всерьез, скачал дистрибутив, поковырялся и написал мини-обзор о том как состыковать Qooxdoo и Ruby on Rails (его даже проанонсировали в официальном блоге Qooxdoo). Однако, при попытке создать более-менее рабочее приложение, я наткнулся на весьма неприятный баг с отправкой POST-форм (я об этом писал в старой версии журнала, которая лежит где-то на Majordomo). И вот, наконец, я в третий раз прихожу к ним - и как раз к моменту выхода Qooxdoo 0.7 alpha2.

Здесь, наверное, стоит завершить лирику и перейти к сути. Приближающаяся версия 0.7 несет нам ряд нововведений, которые я бы назвал знаковыми. Самое знаковое - это переработка механизма ООП и работы с классами. Прямо скажем, это нечто. При работе с Qooxdoo версии 0.6 меня сильно смутила некоторая громоздкость структур и нетривиальность работы с классами. Т.к. опыт работы с JavaScript у меня на тот момент был практически нулевой, вьехать в систему прототипов было ой-ой-ой как непросто. Собственно, этим не только Qooxdoo грешит. Я, например, до сих пор с трудом въезжаю в устройство классов Prototype, хотя пользуюсь им можно сказать каждый день.

В новой версии разработчики Qooxdoo планируют достаточно сильно упростить работу с классами. Предполагается что структура класса будет выглядеть примерно так:

qx.Class.define("my.cool.Class", {                           
  /* Наследование от класса */
  extend : my.great.SuperClass,           

  /* Интерфейсы а-ля Java*/                  
  implement : [my.cool.IInterface, my.other.cool.IInterface],

  /* Миксины а-ля Ruby */
  include : [my.cool.MMixin, my.other.cool.MMixin],          

  /* Конструктор */
  construct : function() {                                   
    this.base(arguments, x);                                 
    ...
  },        

  /* Деструктор */                                               
  destruct : function() {                                    
    ...
  },     

  /* Статичные методы класса */                                                    
  statics :                                                  
  {                                                          
    PI : 3.141,                                              
    bar : function() {}                                      
  },    

  /* Методы экземпляра класса */                                                     
  members:                                                   
  {                                                          
    foo : VALUE,                                             
    circumference : function(radius) {                       
      /* Вызов статичного метода класса */                   
      return 2 * this.self(arguments).PI * radius;           
    },                                                       

    bar : function(x) {                                      
      /* Вызов метода родительского класса */                
      this.base(arguments, x);                               
    },                                                       

    _protectedMember: function(x) { ... },                   

    __privateMember: function(x) { ... },                     

    browserSpecific: qx.Variant.select("qx.client",          
    {                                                        
      "mshtml|opera": function() {                           
         // Internet Explorer or Opera                       
      },                                                     
      "default": function() {                                
         // All other browsers                               
      }                                                      
    })
  },     

  /* События */                                                    
  events :                                                   
  {                                                          
    /*  Вызывается при кликепо объекту */                   
    "click": "qx.event.type.MouseEvent"
  }                                                          
});

Это сборная солянка из сравнения возможностей ООП в Qooxdoo 0.6 и 0.7. Мило, не правда ли? Вполне себе читаемо и поддается осмыслению без выворачивания мозгов наизнанку. Прямо как в номральных языках программирования. Особенно две примечательных вещи - это интерфейсы и миксины. Интерфейсы, насколько я понимаю, предполагаются по аналогии с Java (однако зачем они нужны - для меня пока загадка, я в джаве не силен). Миксины - как попытка затащить в JavaScript частичку мощи Ruby, а именно разработку абстрактного функционала, который может быть подключен к любому классу. Едва взглянув на эту задумку, я готов преклонить голову перед разработчиками за смелость и заботу о прогрессивном человечестве.

В новой версии предполагается еще много разных фич, о которых стоило бы написать отдельно. С нетерпением ждем выхода новой версии. Может быть, я еще чего-нибудь успею написать до релиза 0.7.