Визуальный программинг: Конструируем приложения с помощью HiAsmДля того, чтобы написать полезное приложение, необязательно знать какой-то сложный язык программирования. Несложную сетевую утилиту, панель для управления роутером, удобный парсер информации и многое другое можно создать без единой строчки кода. Если под рукой есть конструктор приложений. Все когда-то начиналось с Ассемблера. Машинный язык мнемонических команд был полностью завязан на архитектуру процессора, под который писалась программа, но при этом стал одним из первых общеиспользуемых языков программирования. Позже появились языки высокого уровня, абстрагирующие программиста от аппаратной части: Basic, Pascal, C и другие. Гораздо больше времени потребовалось на осмысление, понимание и реализацию объектно-ориентированного подхода (ООП) в программировании, которое позволило еще проще описывать объекты реального мира терминами мира виртуального и породило букет языков следующего поколения, в том числе Delphi и C++. Среды для этих языков впервые стали вводить в обиход понятие «визуальное программирование», которое использовалось исключительно в конструкторах форм и интерфейсов. Наконец, последней волной стало появление сред, позволяющих визуализировать все этапы разработки ПО – от проектирования внешнего вида до реализации программного ядра – LabView, HiAsm, SoftWire и прочие. Как это выглядит? Сейчас разберемся. Знакомьтесь – HiAsmHiAsm – среда визуального программирования, программы в которой не пишутся, как это делается в классических языках, а проектируются из кубиков и линий связей между ними. Каждый такой кубик представляет собой элемент, который выполняет какое-то достаточно простое и узкоспециализированное действие (например, копирует файл, проигрывает звук, складывает два числа, качает файл из Internet и т.д. и т.п.). Горизонтальные линии между элементами (или просто «связи») определяют логику будущей программы (то есть последовательность вызова событий и методов, если выражаться терминами классических языков программирования). Вертикальные же связи указывают элементам на то, какие данные откуда брать. Также у каждого элемента есть набор уникальных свойств, которые определяют особенности его функционирования (к примеру, у элемента «Кнопка» есть свойства, определяющие его положение на форме, заголовок, используемый шрифт, текст выводимой подсказки и прочие). Поэтому весь процесс конструирования сводится к расстановке элементов, протягиванию связей между ними и настройке (если необходимо) их свойств. Посмотрим, как выглядит нарисованная таким образом программа классического «Hello world!», которая при нажатии кнопки выводит на экран соответствующее сообщение. Внешний вид схемы, реализующей данный функционал, представлен на рисунке. Собранное приложение состоит из двух элементов: Кнопка (Button) и Сообщение (Message), одной связи между ними (проложенную от события нажатия кнопки к методу показа сообщения) и одного измененного свойства Message (с текстом «Hello world!»). Мы не пишем ни одной строчки кода, но если заглянуть в исходник, то увидим исходник, который сгенерировала HiAsm:
Сгенерированный код написан на языке Object Pascal, но есть и другие варианты. По сути, HiAsm представляет собой не более чем графический векторный редактор. А все его возможности по созданию приложений определяются уставленными пакетами и компиляторами. На текущий момент времени самым мощным из них является пакет Windows, использующий в качестве целевого языка Object Pascal для компиляторов FPC и Delphi. Помимо этого существуют следующие пакеты:
Также в статусе «just for fun» существует online-версия HiAsm (hion.hiasm.com), с помощью которой можно поучиться составлять схемы, имея под рукой лишь браузер. Пишем тестер веб-сервераМы возьмем самый стандартный пакет под Windows (на сайте hiasm.com сейчас доступна версия 4.4) и попробуем написать упрощенный аналог утилиты ab из пакета приложений apache-tools. Основная задача этой утилиты – отправка запросов веб-серверу на получение данных по указанному URL и измерение времени, которое потребовалось на их выполнение. В примере ниже мы будем отправлять по 100 последовательных запросов на адрес http://ya.ru и измерять время, которое на это ушло. Итак, первый этап. Для начала соберем простую схему, которая по нажатию кнопки на форме отправит только один запрос и выведет его содержимое на экран. Для этого откроем HiAsm и создадим новый проект: «Файл –> Новый...», далее выбираем «Windows –> Приложение Windows». После нажатия «ОК» переходим в режим редактирования формы «Вид –> Редактор формы». Вытаскиваем на форму с вкладки «Интерфейс» элементы «Кнопка» и «Редактор текста», после чего с помощью редактора форм размещаем их так, как нам это удобно. Теперь вытащим элемент, который умеет хранить многострочный текст. Он находится на вкладке «Строки» и называется «Список строк». В его свойство Strings запишем текст HTTP-запроса для получения содержимого корня сайта:
Обрати внимание на то, что в конце запроса должны стоять две пустые строки. Теперь осталось соединить все эти элементы так, как показано на рисунке. В схеме был также использован элемент «Разветвитель (Hub)», который находится на вкладке «Инструменты» и занимается только тем, что последовательно вызывает два события справа при вызове метода слева. Теперь запускаем программу и убеждаемся, что после нажатия кнопки нам приходит ответ от сервера, который должен начинаться со строки «HTTP/1.1 200 OK». Теперь попробуем понять, что и как у нас происходит в схеме после нажатия кнопки на форме:
Следует обратить внимание на то, что методы элементов могут принимать данные как со своих верхних точек, так и из потока. В грамотно спроектированной схеме большинство методов читает нужные им данные именно из потока, что избавляет от необходимости прокладывать дополнительные связи и визуально разгружает схему. Скажем, в примере выше текст запроса можно было поместить в свойство Data элемента «Кнопка», а элемент «Список строк» удалить совсем. При таком включении событие onClick выдало бы эти данные в поток, которые, пройдя через «Разветвитель», попали бы на doSend. В более сложных схемах всегда бывает по несколько возможных правильных вариантов включения элементов, решающих определенную задачу, и выбор какого-то одного из них будет зависеть от достигнутого компромисса между читабельностью схемы и ее размером. Заставляем все это работатьУдаляем элемент «Редактор текста» – он нам больше не нужен. Достаем с вкладки «Инструменты» элемент «Счетчик времени». С помощью него мы будем измерять время, которое ушло на соединение с сервером, отправку запроса и получение данных. Для этого ставим счетчик между кнопкой и хабом (onClick –> doStart и onStart –> doEvent1), а его метод doStop соединяем с событием onDisconnect элемента «TCP-клиент». При таком включении в тот момент, когда сервер закроет соединение с нашим приложением, произойдет событие onDisconnect, которое и остановит счетчик. При этом измеренное время (то есть количество миллисекунд, которое прошло с момента вызова события doStart до момента вызова события doStop) будет выдано счетчиком в поток вместе с событием onStop. Выведем содержимое потока с этого события, например, в элемент «Надпись», расположенный на вкладке «Интерфейс» (его лучше всего ставить в режиме Редактора форм). В итоге получим схему, представленную на иллюстрации. После запуска приложения убеждаемся, что оно отображает время одного запроса. Последнее, чего не хватает в схеме для выполнения нашей задачи – это отправка запроса 100 раз подряд. Для этого после наступления onDisconnect нужно вызывать повторное подключение к серверу и отправку запроса до тех пор, пока это событие не произойдет сотый раз. В решении этой проблемы нам помогут два новых элемента, находящихся на вкладке «Логика». Это элемент «Арифметика», который умеет производить простые математические операции, и элемент «Условный блок», который умеет сравнивать между собой два произвольных значения. Первым мы будем считать количество произошедших событий onDisconnect, а вторым – сравнивать это количество с 100. Если номер итерации меньше 100, то программа продолжит запросы к серверу, в противном случае – отобразит время выполнения задачи. Для этого необходимо соединить элементы так, как показано на рисунке. Элемент «Арифметика» соединен сам с собой точками Op1 и Result, что позволяет в качестве первого аргумента использовать ранее вычисленное значение и, таким образом, вести счет вызова события onDisconnect. На простом языке программирования это можно было бы записать одной строкой: x = x + 1. После вычисления следующего значения счетчика результат передается в поток вместе с событием onResult, которое соединено с методом doCompare элемента «Условный блок». Его второй аргумент задан в свойствах и равен 100, то есть данный участок схемы эквивалентен следующему коду:
Также можно заметить, что между счетчиком и надписью появился еще один хаб со связью, идущей к точке doClear элемента «Арифметика». При таком включении метод doClear будет обнулять счетчик вызова событий onDisconnect всякий раз после вывода времени на форму, что позволит нажимать кнопку отправки запросов несколько раз подряд без рестарта приложения. Еще один не столь приметный элемент в виде стрелки, который появился на последнем рисунке, расположен между событием onStart счетчика времени и методом doEvent1 хаба. Этот элемент по своему назначению почти полностью эквивалентен элементу «Разветвитель», с той лишь разницей, что у него может быть всего три входящих потока и один исходящий. Он автоматически ставится на схему в тот момент, когда ты тянешь связь от точки элемента (от onDisconnect, к примеру) и сбрасываешь ее на уже существующую связь между двумя другими точками. Последний штрих в нашей схеме – размещение плашек-комментариев для большей наглядности происходящего. Это ведь тоже код, хоть и графический, а любой код нужно комментировать. Когда это можно использовать?Вот так просто мы создали несложное, но полезное сетевое приложение. Собственно, в этом и заключается главное достоинство HiAsm (ради которого, собственно, и был создан конструктор) – в возможности собирать свои собственные программы без знания каких-либо языков программирования. Поскольку в HiAsm приложение строится из готовых блоков и связей между ними, то понятия «синтаксическая ошибка», как такового, тут нет – при любом расположении и соединении элементов схема будет скомпилирована и запущена. Будет ли она при этом работать – это уже совсем другой вопрос :). Часть элементов палитры реализует уже готовый функционал для выполнения конкретной часто встречающейся задачи (скажем, для закачки файла из интернета и сохранения его на диске), за счет чего многие схемы в HiAsm создаются за гораздо меньшее время, чем аналогичные программы в других языках и средах программирования. Если же готового элемента нет, то велика вероятность того, что нужная схема (или близкая к ней) уже есть в примерах, и пользователю останется только слегка изменить ее. Но, как это часто бывает, все недостатки конструктора вытекают из его достоинств. Так, отсутствие необходимости в знании языка программирования совершенно не исключает необходимость в знании основ работы операционной системы, сетевых протоколов, форматов и стандартов, математики и физики, то есть основ той предметной области, для которой создается программа. Иногда это является неожиданным сюрпризом для пользователя, который с самого начала привык получать готовое решение в два клика без заморочек с хелпом и прочими доками. Отсутствие каких-либо ограничений на расположение и связывание элементов выливается в то, что схему из 10 кубиков можно легко превратить в хаос, с ходу разобраться в котором не сможет даже опытный разработчик. Не исключены также схемы со множеством лишних связей и элементов, которые никак не влияют на работу программы, но оставлены в ней только потому, что «и так все работает». Это, однако, не означает, что такого не бывает в обычных языках – просто визуальное конструирование к этому располагает в гораздо большей степени. Производительность получаемого приложения в пакете Windows (именно он рассматривается в данной статье) хоть и сильно зависит от используемого набора элементов, но все же в среднем ниже производительности аналогичного решения на компилируемом языке программирования. Маленький советHiAsm идеально подходит для конструирования простых утилит. Но при этом, как и любой другой механизм графического программирования, не годится для решения задач, в которых требуется производить много расчетов, сравнений, операций со строками и прочих «микро» процедур. Помимо этого есть другое ограничение, связанное с максимально возможной сложностью проекта, для которого в качестве среды разработки выгодно выбирать HiAsm. Несмотря на то, что в палитре пакета есть множество инструментов для масштабирования схемы (разбивка на модули, вкладывания в контейнеры и т.д.), начиная с определенного момента дальнейшее наращивание функционала (и, как следствие, количества элементов) ведет к сильному падению читабельности схемы и пониманию ее работы из-за образования большого числа связей. Это значит, что для разработки более-менее сложных приложений конструктор программ не подходит. Могу дать следующий совет: если ты считаешь, что схема приложения будет состоять из примерно 500-1000 элементов, то лучше обратиться к традиционным средам программирования. Впрочем, точная цифра целиком и полностью зависит от самого разработчика: так, например, официальный сайт и форум HiAsm «нарисован» в нем самом и состоит из примерно 7000 элементов. Основные элементыНиже привожу несколько основных элементов, без которых не обходится почти ни одна схема. Инструменты:
Логика:
WWW
INFOПроект HiAsm (или Конструктор программ) – это открытое программное обеспечение, разрабатываемое сообществом русских программистов, известных под никами dilma (Дмитрий Власов, ведущий проекта), nesco (Евгений Носов), iarspider (Иван Разумов), nic (Николай Березников) и другие. Неоценимый вклад в развитие проекта вносят и простые пользователи, регулярно посещающие форум и предлагающие идеи, часть которых реализуется в последующих версиях конструктора. |