17 мар. 2021 г.

Что не так с VBA?

Автор: Mathieu Guindon
Источник: What’s Wrong With VBA?

Самый ужасный язык

В ежегодном опросе разработчиков на Stack Overflow VBA всегда входил в группу “самых ужасных” языков. В  этом году по какой-то причине VB6 и VB.NET нет в списке, но VBA находится наверху, по мнению 75.2% респондентов.

VBA - входной язык – во всяком случае, так было для меня. Он решает задачу и выдаёт шаблонный код, о котором вам действительно  не стоит беспокоиться, чтобы решить задачу. До некоторой степени этого вполне достаточно. Пока это работает. Код пишется, чтобы выполняться, верно? А если бы мы писали код, чтобы его читали? Код, который легко понять, легче обслуживать и расширять, не "сломав" его. Хорошо организованный код с небольшими повторно используемыми компонентами, которые можно тестировать независимо друг от друга…просто объективно лучше. И VBA не говорит, что так не может быть.

С VBA всё в порядке. Непонятный код со странными именами переменных, запутанный код, который тяжело читать и ещё тяжелее сопровождать, можно написать на любом языке программирования, который есть сегодня или будет придуман в будущем.

VBA - это версия “классического” Visual Basic (VB5, VB6), встроенная в приложение. Несколько лет Microsoft продавала VBA Software Development Kit (SDK), с помощью которого можно встроить VBA в свой продукт, чтобы писать сценарии с использованием своих COM API / объектной библиотеки: можно написать ERP-систему (Enterprise Resource Planning), CAD-программу, векторный редактор, что угодно – и обеспечить расширяемость посредством VBA SDK. Это были золотые годы Visual Basic: все знали VB. Я в это время учился в колледже, и курс Programming I включал изучение VB6. Тогда это также был входной язык: “настоящие программисты” писали на C++.

Visual Basic появился через несколько лет после QBasic, который следовал за BASIC. Эдсгер Дейкстра сказал о BASIC: 

Студентов, ранее изучавших Бейсик, практически невозможно обучить хорошему программированию. Как потенциальные программисты они подверглись необратимой умственной деградации.

Прошли годы, а BASIC всё ещё жив благодаря VBA и VB.NET. Плохой код порождается программистом, а не языком. Если вы хотите учиться, то будете учиться: не позволяйте никому убедить себя в обратном. Каждый программист когда-то был новичком, и неважно, пишете ли вы на VBA, Java, C++, C#, PHP, или модном Javascript; стоит избавиться  от фигурных скобок и точек с запятой, как они станут похожи, если на них писал один человек: игнорируйте погромистов, которые думают, что их язык лучше вашего. Вы деградировали не больше, чем они.

VBA полноценный, зрелый язык программирования, который многократно проверен за последние 20 лет. Это не просто процедурный код: проекты Visual Basic могут определять свои классы и создавать COM-объекты; объекты, которые могут представлять несколько интерфейсов, генерировать и обрабатывать события, и эти возможности открывают двери, о которых не мечтает ни один игрушечный язык. “Но в нём нет наследования классов! Это не настоящее объектно-ориентированное программирование!” – конечно, есть ограничения; наследование классов это замечательно, однако им часто и легко злоупотребляют. Композиция предпочтительнее наследования по многим причинам, и VBA позволяет компоновать объекты. Наследование хорошо тем, что можно рассматривать производные классы как общий базовый класс, что приводит к полиморфизму: Car, Plane, и Boat могут рассматриваться как Vehicle, и каждый объект может по-своему реализовать метод Move. Код VBA также может сделать это с помощью интерфейсов. В большинстве случаев вы сами определяете степень ограниченности VBA.

Среди полезных вещей, которыми не располагает VBA, мы обнаружим отражение: возможность писать код, который исследует сам себя – например, найти в библиотеке типов проекта VBA отдельный тип Enum и сохранить имена членов и соответствующих значений в словаре. Отражение возможно в .NET посредством подробной системы типов, которой не располагает VBA: написание соответствующего API для VBA не является невозможным, но требует глубоких знаний о том, как работают пользовательский код и типы VBA, и доступа к внутренним указателям структур данных COM. Отражение - крайне мощное средство, за которое надо платить: обычно его избегают в тех местах, где важна производительность.

VBA не поддерживает делегаты, и не рассматривает функции как объекты первого класса: нельзя передать функцию в другую процедуру VBA; вместо этого передаётся результат функции. Из-за этого трудно реализовать, к примеру, структуры данных, для которых можно использовать запросы и/или фильтры: для запросов и фильтрации нужны явные циклы, что делает код более многословным по сравнению с аналогом на C# или VB.NET, где подобные вещи могут быть выполнены с помощью LINQ или другой современной технологии. Однако лямбда-выражения в Java появились относительно недавно, и популярность Java в их отсутствие не снижалась десятки лет – делегаты .NET невероятно полезный инструмент, но можно прекрасно справиться и без него, хотя код будет чуть более многословным. И знаете что? Модный код LINQ может быть очень элегантным (при правильном использовании… но также может быть кошмарным), однако программисты .NET стараются избегать его в местах, где важна скорость.

Обработка ошибок VBA связана с глобальным состоянием и операторами On Error, которые по сути задают условные переходы GoTo. В других языках есть исключения и блоки try/catch… которые по сути задают условные переходы GoTo. Конечно, исключения замечательны и могут упростить обработку ошибок. Но это не серебряная пуля, многие “настоящие программисты”  используют их для управления потоком выполнения или  просто глотают их и двигаются дальше… плохая обработка исключений на любом языке ничем не лучше плохой обработки ошибок на VBA.

Своей репутацией VBA и VB6 как язык, также и, возможно, главным образом, обязан редактору Visual Basic (VBE). VBE как среда разработки (IDE) просто не поддерживается на должном уровне, и была… практически заброшена. На Stack Overflow есть закрытый вопрос  о наличии средств рефакторинга для VBA. Самый популярный ответ-пинок старому редактору сообщал, что единственным известным рефакторингом является поиск/замена  (Ctrl+H). Кажется, что сам редактор активно препятствует написанию полноценного объектно-ориентированного кода VBA, или просто хорошо читаемого кода: все классы валяются в единственной папке “Class Modules” с алфавитной сортировкой… так что вы прибегаете к причудливым схемам именования, чтобы сделать визуальную группировку по функционалу. Возможно, вы уже поиграли с интерфейсами, но их кодирование (т.е. абстракций, а не конкретных типов; принцип инверсии зависимостей) делает невозможным переход к фактическому коду, реализующему интерфейс. Нет встроенной поддержки модульных тестов и фиктивной реализации, нет рефакторинга, нет статического анализа кода, метрик кода, …список можно продолжать бесконечно.

У языка есть мелкие раздражающие недостатки (как и у всех языков), у некоторых повсеместно используемых библиотек типов (наподобие Excel)  есть свои раздражающие моменты – но это не повод обвинять VBA как язык за особенности некоторых библиотек типов, даже разработанных Microsoft.

С VBA всё в порядке. А вот с редактором Visual Basic нет. Если бы только была надстройка VBIDE, которая сделала бы работу с VBA приятнее…

Комментариев нет:

Отправить комментарий