Проблема
Большую часть моей роботы с технологиями большой тройки (HTML, CSS, JS) составляет создание простых страниц вроде документации к приложению, визитки для предприятия, и тд. Для таких мелких целей текущая тройка подходит почти идеально. Однако, что если подумать о современных сайтах вроде Facebook, VK, Google Docs, Twitter, Stack Overflow? Они являются скорее полноценными приложениями, чем страницами. В таком случае можно рассматривать эту тройку как тулкит для создания графических приложених, вроде GTK+ или Java AWT. Однаок если открыть код упомянутых выше веб-приложений, можно увидеть кашу из прямолинейного, повторяющегося HTML-кода, неясной JS логики и CSS хаков. Разве это сравнимо с ООП кодом, ответственного за отображение графики, в любом более менее нормальном desktop-приложении? В любом тулките создание меню — вопрос пары строк кода. Переиспользование одного и того же кода? Проще простого! А как насчет большой тройки? С этой точки зрения тройка не выдерживает никакой критики. Она не расчитана на веб-приложения, которые характеризуется нелинейной структурой экрана, высокой динамичностью содержания, требовательностью к ресурсам. Я считаю, что именно с веб-приложениями тройка справляется плохо. Эти технологии были созданы для простых, линейных, статических страниц.
Я решил подумать немного над этим вопросом. Почему в мире desktop программирование есть такие удивительно-функциональные фреймворки, а программисты веб-приложений давятся из рук вон ужасным стандартом? После нескольких дней размышления я решил изложить свои идеи на, как говорится, бумаге. В этой статье я хотел бы очертить стандарт, который мог бы послужить основой замены упомянутой выше тройки. Статья лишь претендует на попытку описать то, как замена тройки может выглядеть. Конструктивная критика и комментарии очень ожидаемы. Кодовое название — JAW, JAW's an Application for Web.
Идеи
После недолгого размышления я определился с основными идеями данной технологии:
- Декларативный подход. Написание простых страниц остается простым при помощи XML.
- ООП подход. Классы, энкапсуляция, наследование и абстракция создают условия для удобного переиспользования одного и того же кода в комплексных веб-приложениях.
- Java байт-код. Классы могут быть описаны при помощи байт-код, что позволяет добавлять комплексную логику и обработку данных.
Страницы веб-приложения
Начнем с простого. Договоримся, что страница — это некая единица, начальная точка доступа к веб-приложению, которая может быть отображена веб-браузером. Для описания некой страницы используется XML, поскольку этот стандарт предоставляет подходящий баланс между читабельностью (простотой) и легкостью машинной обработки (производительностью).
Расмотрим пример простой HTML и JAW веб-страницы:
<html>
<body>
Hello, world!
</body>
</html>
<?xml version="1.0" encoding="UTF-8"?>
<page> <!-- page это корневой элемент XML файла. -->
<canvas> <!-- canvas содержит корневой компонент страницы -->
<block>Hello, world!</block> <!-- block позволяет простой вывод текста и других компонентов -->
<canvas>
</page>
Код получился примерно одного и того же размера, однако за простотой прячется богатый функционал полноценного фреймворка, о чем далее.
Компоненты
Для начала определим, что компонент — это экземпляр (instance) некого класса, который можно отобразить на странице. Каждая страница имеет ровно один корневой компонент, который описывается единственным дочерним элементом элемента canvas. В предидущем примере корневой компонент имеет класс block, встроенный класс имеющий поведение схожее с тегом div. JAW, как и HTML, поддерживает множество базовых классов. Преимущество использования классов заключается в повторном использовании кода. К примеру:
<html>
<body>
<div>Apple</div>
<div>$10</div>
<div>Orange</div>
<div>$5</div>
</body>
</html>
<?xml version="1.0" encoding="UTF-8"?>
<page> <!-- page это корневой элемент XML файла. -->
<classes>
<class name="product" >
<template> <!-- Здесь мы задаем шаблон компонента. Код, создающий экземпляр этого класса, должен будет предоставить значения этих свойств. Свойства могут быть обычным тексом, а могут быть и компонентами. -->
<block><property type="text" key="title"></block>
<block><property type="text" key="price"></block>
</template>
</class>
</classes>
<canvas>
<block>
<product>
<property key="title" value="Apple"> <!-- Первый способ создания компонента. Здесь property - это не дочерний компонент, а специальный элемент. -->
<property key="price" value="$10">
</product>
<product title="Orange" price="$5"> <!-- Второй способ создания компонента, более короткий, но не удобный для большого кол-ва свойств. -->
</block>
</canvas>
</page>
Здесь мы определяем класс product с неким шаблоном, который задан при помощи набора свойтсв. Значения этих свойств должны быть переданы при создании экземпляра класса в файле страницы или программно в байт-коде, о котором далее. Значением свойтсва может быть и компонент, к примеру:
<?xml version="1.0" encoding="UTF-8"?>
<page>
<classes>
<class name="product" >
<template>
<block><property type="component" key="title"></block>
<block><property type="component" key="price"></block>
</template>
</class>
</classes>
<canvas>
<block>
<product>
<b key="title">Apple!!!</b> <!-- Здесь b делает текст жирным, как и в HTML. -->
<i key="price">$10</i> <!-- Аналогично. Аттрибут key указывает название свойства, которым станет этот компонент. -->
</product>
<!-- Второй способ создания компонента в данном случае невозможен. -->
</block>
</canvas>
</page>
Определять класс можно и программно в байт-коде, о чем также позже. JAW код получился длиннее, однако у нас используется шаблон, а значит замена структуры продукта займет меньше времени. Более того в данном случае при использовании второго способа создания компонента JAW код, ответственный за вывод product, будет меньше HTML кода уже при 7 продуктах.
Client-side программирование
Продлогаемую мной идею можно описать следующим образом. Страница может использовать некий класс A, но вместо того, чтобы определять его, она может сослаться на файл содержащий Java байт-код класса А. Веб-браузер в свою очередь будет содержать JVM (Java Virtual Machine) для выполнения этого байт-кода.
Код страницы может содержать код вроде:
<?xml version="1.0" encoding="UTF-8"?>
<page>
<include url="./MyMenu.class" /> <!-- Подключаем класс MyMenu, указывая URL, по которому его можно найти -->
<include url="./myappclasess.jar"/> <!-- Подключаем целый архив классов, запакованых в Java Archive -->
<canvas>
<MyMenu>
<!-- ... -->
</MyMenu>
<canvas>
</page>
Байткод позволяет создавать платформо-независимые приложения, в отличии от обычного бинарного код, который можно запустить лишь на конкретной платформе. К тому же байт-код не предусматривает
никакого конкретного языка. Тобиш у програмистов появляется возможность выбрать из доступных языков тот, который подходит именно для их приложения. Использование байт-кода вместо конкретного языка дает программистам свободу выбора, а также основу для обфускации в целях защиты кода от реверс-инжиниринга.
Байт-код содержит код отображения класса, а так же логику, вроде обработки нажатий мышки в пределах данного компонента, срабатывания таймеров, подсчет неких значений, изменение дочерних компонентов и тд. Стандартная библиотека Java достаточно богата для легкого создания фрейморка работы со страницей. К примеру, AWT уже содержит множество Java классов для работы с компонентами, графикой, событиями. Необходимости писать API фреймворка с нуля не будет. Более того Java библиотека поддерживает работу с массивами, интернет протоколами, XML файлами, процессами, потоками и тд. Это позволит перенести массу кода с сервера на клиент, что улучшить производительность веб-приложений, их гибкость и функционал. Именно байт-код является основным новшеством JAW. Файлы страниц нужны только для декларативного создания простых страниц и точек начала работы с веб-приложением.
Из всех существуещих на сегоднешний день байт-кодов самыми развитыми являются .NET управляемый код и Java байт-код. Поскольку .NET не портирован на другие платформы кроме Windows, его использование становится не возможным в JAW. Единственным вариантом остается Java. Стоить сказать, что существует не малое количество языков, которые можно компилировать в Java байт-код. Среди них C, Ruby, Python, Lua, Pascal, PHP, Scheme, Google Go, Lisp и другие. Не плохой набор для замены JavaScript, не правда ли?
Что дальше?
Как вы наверное заметили, я не упомянул ничего даже похожего на CSS. Мне не пришло в голову ничего радикального, что может улучшить эту технологию, кроме как констант, и байт-код декораторов, которые позволяют создавать свои собственные свойства.
Я также понимаю, что эта статья не описывает технологию даже на 10%, но хотелось бы услышать, правилен ли ход моих мыслей.
Автор: Ganga