Salesforce Apex – как первый язык программирования. Плюсы и минусы

    Моим первым языком программирования стал Apex. Это Java-подобный язык, который автоматизирует backend-логику в приложения на платформе Salesforce.com

    Нельзя сказать, что я до этого не был знаком с ООП или другими языками. Мое знакомство ограничивалось теоретическими знаниями, полупройденными курсами на Codecademy или лабораторными работами в институте. Естественным образом все тонкости технологии, синтаксис языка, его возможности и ограничения быстро выветривались из памяти, поскольку практического применения этим навыкам я не находил. 

     В 2019 году я пришёл в Accenture как специалист по поддержке и доработке CRM Salesforce. Диапазон задач сначала был очерчен недостаточно чётко, поэтому я стал изучать инструменты как администрирования, так и разработки на Salesforce. 

    Сейчас мой опыт разработки на Apex около года, я стал сертифицированным разработчиком Salesforce. Могу подвести первые итоги. 

    Будет полезно для:

    • новичков в программировании

    • администраторов Salesforce, которые хотят освоить разработку

    • опытных разработчиков, которые хотят узнать о разработке на платформе Salesforce

    Ниже я кратко приведу все плюсы и минусы Apex, с точки зрения выбора его как языка для обучения. Затем подробнее рассмотрю каждый пункт.

    Плюсы Apex: 

    1. Apex приучает к написанию оптимального, ресурсоэффективного кода 

    2. Apex приучает к юнит-тестированию и к test-driven разработке 

    3. Apex имеет единую и обновляемую документацию, собранную на портале Salesforce 

    4. Apex имеет out-of-the-box доступ к БД (не нужно писать коннекторов) 

    5. Apex – это на 90% Java. Вы с легкостью сможете понимать Java-код после разработки на Apex 

    6. Salesforce поставляет собственную онлайн IDE Developer Console, которая позволяет новичку быстро начать программировать без погружения в мир кастомных IDE 

    7. Apex можно осваивать в Trailhead-песочницах, без установки и настройки дополнительного софта.  

    8. Trailhead обучает программированию на Apex с полного нуля. Trailhead-модули обучают вас концепциям ООП и синтаксису Apex на языке простых смертных (к сожалению, только на английском) 

    Минусы Apex: 

    1. Мало материалов на русском языке (почти нет) 

    2. Немногочисленное русскоязычное сообщество 

    3. Применимость только для продуктов на платформе Salesforce 

    Apex приучает к написанию оптимального, ресурсоэффективного кода

    Ресурсоэффективный код в Apex – это не блажь и не рекомендация, а почти необходимое условие. Поскольку Salesforce – это облачная платформа, программные ресурсы у каждого клиента платформы ограничиваются лицензией. Иными словами, ресурсы, которые есть у вас в распоряжении, как разработчика, ограничены лимитами Salesforce

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

    Этот пункт я считаю плюсом Apex, поскольку вы с самого начала привыкаете писать оптимальный код, который экономно распоряжается облачными ресурсами. Это формирует полезный для разработчика способ мыслить. 

    Apex приучает к юнит-тестированию и к test-driven разработке 

    Покрытие кода юнит-тестами на 75% – обязательное условие для переноса этого кода на PROD-среду. Поэтому вы с самого начала учитесь создавать тест-классы. Это полезный навык – менять ментальный ракурс, с которого вы смотрите на свой код, таким образом, чтобы написать тест. 

    Salesforce в этом вопросе идет дальше и пропагандирует при разработке начинать с написания юнит-тестов. Это помогает лучше осознать все пользовательские сценарии, которые должен обрабатывать ваш будущий код. Поэтому Apex, как первый язык программирования, не оставляет вам выбора: вы сразу учитесь лучшим практикам и осознанному подходу к процессу разработки. 

    Пример класса и тест-класса в Apex

    Класс:

    public class TVRemoteControl { 
    
        // Volume to be modified 
    
        Integer volume; 
    
        // Constant for maximum volume value 
    
        static final Integer MAX_VOLUME = 50;     
    
         
    
        // Constructor 
    
        public TVRemoteControl(Integer v) { 
    
            // Set initial value for volume 
    
            volume = v; 
    
        } 
    
             
    
        public Integer increaseVolume(Integer amount) { 
    
            volume += amount; 
    
            if (volume > MAX_VOLUME) { 
    
                volume = MAX_VOLUME; 
    
            }  
    
            return volume; 
    
        } 
    
         
    
        public Integer decreaseVolume(Integer amount) { 
    
            volume -= amount; 
    
            if (volume < 0) { 
    
                volume = 0; 
    
            }   
    
            return volume; 
    
        }     
    
         
    
        public static String getMenuOptions() { 
    
            return 'AUDIO SETTINGS - VIDEO SETTINGS'; 
    
        } 
    
            
    
    } 

     

    Тест-класс: 

    @isTest 
    
    class TVRemoteControlTest { 
    
        @isTest static void testVolumeIncrease() { 
    
            TVRemoteControl rc = new TVRemoteControl(10); 
    
            Integer newVolume = rc.increaseVolume(15); 
    
            System.assertEquals(25, newVolume); 
    
        } 
    
         
    
        @isTest static void testVolumeDecrease() { 
    
            TVRemoteControl rc = new TVRemoteControl(20); 
    
            Integer newVolume = rc.decreaseVolume(15); 
    
            System.assertEquals(5, newVolume);         
    
        }  
    
             
    
        @isTest static void testVolumeIncreaseOverMax() { 
    
            TVRemoteControl rc = new TVRemoteControl(10); 
    
            Integer newVolume = rc.increaseVolume(100); 
    
            System.assertEquals(50, newVolume);         
    
        } 
    
         
    
        @isTest static void testVolumeDecreaseUnderMin() { 
    
            TVRemoteControl rc = new TVRemoteControl(10); 
    
            Integer newVolume = rc.decreaseVolume(100); 
    
            System.assertEquals(0, newVolume);         
    
        } 
    
         
    
        @isTest static void testGetMenuOptions() { 
    
            // Static method call. No need to create a class instance. 
    
            String menu = TVRemoteControl.getMenuOptions(); 
    
            System.assertNotEquals(null, menu); 
    
            System.assertNotEquals('', menu); 
    
        } 
    
    } 

    Apex имеет единую и обновляемую документацию, собранную на портале Salesforce

    Salesforce развивает Apex как основной язык для разработки на своей проприетарной платформе, поэтому все обновления и вся документация содержатся на едином официальном портале Apex Developer Guide.

    На ней собраны все системные классы и методы, подробно описано их назначение и применение.  Можно найти однозначный ответ на большинство вопросов. А вопросов при обучении всегда много. 

    Apex имеет out-of-the-box доступ к базе данных

    Большим плюсом для начинающего разработчика Apex считаю простоту обращения в базу данных из кода. В базу данных можно обратиться из любого места в коде, для этого не нужно дополнительных настроек и соединений. 

    Вот несколько примеров обращения к базе данных из кода: 

    Account A = new Account(Name='xxx');
    insert A;
    Account B;
    
    // A simple bind
    B = [SELECT Id FROM Account WHERE Id = :A.Id];
    
    // A bind with arithmetic
    B = [SELECT Id FROM Account 
         WHERE Name = :('x' + 'xx')];
    
    String s = 'XXX';
    
    // A bind with expressions
    B = [SELECT Id FROM Account 
         WHERE Name = :'XXXX'.substring(0,3)];
    
    // A bind with an expression that is itself a query result
    B = [SELECT Id FROM Account
         WHERE Name = :[SELECT Name FROM Account
                        WHERE Id = :A.Id].Name];
    
    Contact C = new Contact(LastName='xxx', AccountId=A.Id);
    insert new Contact[]{C, new Contact(LastName='yyy', 
                                        accountId=A.id)};
    
    // Binds in both the parent and aggregate queries
    B = [SELECT Id, (SELECT Id FROM Contacts
                     WHERE Id = :C.Id)
         FROM Account
         WHERE Id = :A.Id];
    
    // One contact returned
    Contact D = B.Contacts;
    
    // A limit bind
    Integer i = 1;
    B = [SELECT Id FROM Account LIMIT :i];
    
    // An OFFSET bind
    Integer offsetVal = 10;
    List<Account> offsetList = [SELECT Id FROM Account OFFSET :offsetVal];
    
    // An IN-bind with an Id list. Note that a list of sObjects
    // can also be used--the Ids of the objects are used for 
    // the bind
    Contact[] cc = [SELECT Id FROM Contact LIMIT 2];
    Task[] tt = [SELECT Id FROM Task WHERE WhoId IN :cc];
    
    // An IN-bind with a String list
    String[] ss = new String[]{'a', 'b'};
    Account[] aa = [SELECT Id FROM Account 
                    WHERE AccountNumber IN :ss];
    

     

    Apex – это на 90% Java. Вы с легкостью сможете понимать Java-код после разработки на Apex

    Salesforce создавала Apex на основе синтаксиса Java. Есть небольшие исключения, обусловленные спецификой Salesforce. Все отличия собраны на этой странице.

    Но, если посмотреть на методы работы с примитивами и коллекциями, то они работают аналогично Java. 

    Сравните, к примеру, методы работы со String в Apex и String в Java.

    Выходит, что обучаясь Apex вы во многом обучаетесь и Java. Это правило работает и наоборот. 

    Если вы решите перейти в Java-разработчики, вам не придется начинать с нуля. А полезные парадигмы мышления из Apex-разработки дадут вам хороший фундамент для написания ресурсоэффективного Java-кода. 

    Salesforce поставляет собственную онлайн IDE Developer Console

    Developer Console позволяет новичку быстро начать программировать без погружения в мир кастомных IDE.

    Я помню, как раньше делал попытки самостоятельно учить Python, C#. И начинать нужно было с установки IDE, ее настройки. Разобраться, как работает эта IDE – отдельная история. Много папок, много кнопок, много пунктов меню, много панелей. Это было серьёзным барьером на пути начинающего разработчика. 

    С Apex ничего подобного не было, поскольку любой инстанс Salesforce содержит в себе встроенную IDE, которая называется Developer Console. Устанавливать ничего не нужно, достаточно открыть в браузере Developer Console и сразу писать код. Код можно запустить сразу и проверить его работу в реальном (или «песочном») приложении. 

    Да, более опытные разработчики Salesforce предпочитают работать в Visual Studio Code или Eclipse, но для начинающих Developer Console – то, что нужно.  

    Developer Console выглядит так: 

    Apex можно осваивать в Trailhead-песочницах, без установки и настройки дополнительного софта

    Salesforce разработал собственную платформу для обучения – trailhead.salesforce.com. Она великолепна геймификацией процесса обучения и тем, что создавать тестовые среды можно непосредственно со страницы практического задания: 

    В рамках обучения можно иметь одновременно до 10 (!) активных песочниц. Песочницы можно удалять и создавать новые для каждой следующей задачи, а можно работать в одной песочнице по нескольким заданиям сразу. Любая новая песочница создаётся с уже предзаполненными данными, чтобы вы могли сразу начать эксперементировать и не тратить время на заполнение тестовыми данными.  

    Trailhead обучает программированию на Apex с полного нуля 

    В Trailhead множество обучающих модулей и «троп» (последовательностей модулей). Главный плюс для начинающего в том, что для обучения программированию можно выбрать «тропу», которая предназначена для учеников с нулевым опытом или только с админским опытом. В таком случае обучение начнется с самых основ ООП, а в качестве примеров будет использоваться Apex-код. 

    Примеры обучающих модулей по разработке на Apex для администраторов
    Примеры обучающих модулей по разработке на Apex для администраторов

    Все модули Trailhead написаны на английском языке. Авторы модулей стараются максимально просто описывать концепции, поэтому языковой барьер быстро перестает чувствоваться.  

    Текст часто снабжается забавными примерами и просто шутками. Типичный пример на рисунке ниже: 

    В изучении Apex есть и минусы. Ниже рассмотрю их подробнее.

    Мало материалов на русском языке (почти нет)

    На русский язык не переведены такие официальные ресурсы, как: 

    1. Trailhead

    2. Apex Developer Guide

    Это затрудняет обучение ребятам, которые не знают английский язык. 

    Немногочисленное русскоязычное сообщество

    Количество разработчиков из России и СНГ относительно небольшое, поэтому достаточно трудно найти блоги и обсуждение Apex на русском языке. Вот, например, как выглядят профессиональные сообщества Salesforce-специалистов ВКонтакте 

    Надо заметить, что в Беларуси разработка на Salesforce стремительно популяризуется. В русскоязычном Youtube появляется всё больше качественных видео про Salesforce и Apex (пример). Количество специалистов растёт, но работы всё ещё больше, чем людей. 

    Этот минус можно конвертировать в преимущество вас как специалиста на рынке труда. Чем меньше специалистов, тем они дороже. 

    Применимость только для продуктов на платформе Salesforce

    В отличие от Java, Python и других кроссплатформенных языков, Apex может использоваться только для разработки на платформе Salesforce.com. Несмотря на многообразие продуктов Salesforce, вы ограничены этим стеком. 

    Заключение

    Apex прекрасно подходит для обучения программированию. Правила и рекомендации Salesforce с самого начала научат вас лучшим практикам ООП, которые применимы к коду на любом другом языке.  

    Однако, лучше посмотреть в сторону других языков для старта, если: 

    • Вы не планируете профессионально развиваться в качестве специалиста Salesforce; 

    • Вы плохо владеете английским языком. Это затруднит вам изучение любого языка программирования, но Apex - в особенности. 

    Accenture
    Accenture Russia

    Комментарии 24

      +1
      Из статьи складывается впечтатление, что Apex это язык для обучения программированию. Но ведь это же не так?
        0
        Apex — это язык для разработки логики на платформе CRM Salesforce. Но экосистема обучения Apex выстроена так, что язык легко осваивать.
        +3
        Apex это песочница аля 1c язык.
        Его учить не надо если вы не планируете программировать на Salesforce!

        Пусть откроют исходники Apexa\ может тогда кто-то захочет писать на нем!
          0
          Именно так, спасибо за дополнение. Apex ограничен этой платформой.
          Salesforce — это ведущая CRM в мире. В России рынок пока небольшой, но работы всё-таки больше чем специалистов. Есть возможность запрыгнуть в первый вагон и стать одним из первых разработчиков на растущем российском рынке.
          +2
          Не советую брать этот apex. Пробовал. Платформа макаронная. SQL код вперемешку с основным кодом это жесть хаха.
          А работу найдёте только на salesforce. Язык этот только для одной платформы. Вы не получите норм вакансию на java зная лишь этот apex.

          Зачем выбирать ограниченную платформу в ущерб себе?
            0
            Да, мне тоже смесь Java и SQL синтаксисов режет глаза. Логичнее тогда уж, как было в FoxPro. Там хоть синтаксис единый для всего: для запросов данных, для их отработки и для интерфейсов.
              0
              Там еще и IDE номальную нужно прикручивать через одно место. И код по дефолту не через VCS перекидывается, а с помощью пакетов с энва на энв. Очень «удобно» мерджить и отслеживать ревизии
                0
                Не совсем так. Точнее, совсем не так. Код выгружается в source control и прекрасно мерджится. Вот с метаданными в SObjects все не так радужно.

                А так, из плюсов Apex
                1. Прекрасный тулинг (SFDX, плагин для VSCode, IlluminatedCloud 2 для Idea)
                2. Великолепная OO база данных
                3. Кодировать можно хоть на iPad

                Из минусов
                1. Apex был форкнут с Java 6. 15 лет прогресса в Java-мире прошли мимо. Язык кажется outdated. Конечно, не на столько outdated как Go, но все-таки
                2. Невозможность нормальной работы с бинарными данными. Даже zip расзиппить — это либо в браузере через JS, либо через Base64 представление
                  0
                  Спасибо за дополнение!
                –1
                Ни к чему не призываю. Освещаю свой опыт.
                Моё мнение: Salesforce растет семимильными шагами, параллельно растет потребность в разработчиках. Поэтому без хлеба не останетесь :)
                  +1
                  обычная java не просто так является одним из самых популярных. Переходите к нам )
                    0
                    просто порог входа для apex разработчиков ниже…
                0
                В статье не описан такой важный момент, что форсовый разработчик скорее всего работает не только с бэком, но и с фронтом.

                Не понял комментаторов выше, которые транслируют очевидную мысль, мол, apex годится только для разработки внутри salesforce. Об этом ведь и написано в заключении. Другое дело, что внутри их экосистемы есть несколько векторов развития, поэтому при наличии скиллов работу можно найти даже в России, а уж при наличии английского — и за ее пределами.
                  0
                  Спасибо за комментарий.
                  В статье делал упор именно на бэкенд разработке для Salesforce — т.е. именно на Apex.

                  Вы правы насчет фронтенда: понятие Salesforce-разработчик шире, чем Apex-разработчик. Salesforce разработка включает в себя не только Apex, но и HTML, CSS, JavaScript на фронтенде.
                    0
                    А как, кстати в Apex workflow делается? В смысле если надо что-то считать на сервере, потом спросить пользователя, потом что-то в зависимости от его ответа опять считать на сервере, опять спросить пользователя и т.д. То есть существует разделение на клиент и сервер? Где клиентские действия (типа открытия формы или сообщения), можно выполнять только на клиенте (или другими словами с сервера обращаться к клиенту).
                      0
                      Не на самом Apexе, а средствами платформы. Тут есть 3 варианта:
                      1. Родной Flow. По сути дела визуальный workflow
                      2. Vlocity OmniScript, часть предпоследнего приобретения Salesforce. Этот компонент еще и формбилдер предоставляет
                      3. Ну и при желании на смеси Apex и Visualforce/LWC можно свое workflow написать, если очень хочется
                        0
                        А можно пример кода где-нибудь увидеть? Что-то вроде, при нажатии кнопки, проверить если инвойсе сумма больше 100, спросить у пользователя поручителя, проверить что у поручителя лимит не превышен, спросить у пользователя подтверждение, перевести инвойс в следующий статус.
                  0
                  Мне кажется APEX это тупиковый путь — он хорош для выполнения каких-либо простых задач, и совершенно не подходит для выполнения сложных задач.
                  Как пример — надо было мне сделать «lead routing», правила «роутинга» были описаны в кастомных записях, так чтобы обычные пользователи могли их менять. В APEX коде эти записи транслировались в некие правила и меппиги на основе которых и происходило назначение lead owner. Изначально правила были простые и все работало, потом правила начали усложняться, их объем вырос в несколько раз, добавился нечеткий поиск и т.д.
                  Как итог пару раз в день я вижу: Apex CPU time limit exceeded.

                  С какими проблемами я столкнулся:
                  1. Трансляция «человеческих» записей во внутренние правила для роутинга отъедают порядочную часть «Maximum CPU time». Изменяются эти правила довольно редко — так что логично было хранить их где то заранее подготовленными, но в APEX не возможно создать что-то, что переживет контекст транзакции. Время жизни статических структур — это время жизни транзакции. В итоге я воспользовался Cache.Org, который в свою очередь тоже ни чего не гарантирует.
                  2. Лимиты на ресурсы действуют на всю транзакцию целиком. В SalesForce были установленны 3rd-party пакеты которые так же потребляют ограниченный «CPU time».
                  developer.salesforce.com/docs/atlas.en-us.salesforce_app_limits_cheatsheet.meta/salesforce_app_limits_cheatsheet/salesforce_app_limits_platform_apexgov.htm

                  Сейчас я рассматриваю перенос ресурсоемких задач из APEX в микросервисы (API лимит позволяет). Heroku connect предоствляет БД с двусторонней синхронизацией с SalesFoce, но я пока не понял сколько это стоит.

                  Apex – это на 90% Java. Вы с легкостью сможете понимать Java-код после разработки на Apex

                  Это или какая-то очень старая версия, может 1.4 или максимальна упрощенная 1.5. Да тут нет даже дженериков!

                  Покрытие кода юнит-тестами на 75% – обязательное условие для переноса этого кода на PROD-среду. Поэтому вы с самого начала учитесь создавать тест-классы.

                  За годы работы я повидал много кода и чаще всего я вижу:
                  1. Юнит тесты нацеленные просто на покрытие кода, без каких либо Assert
                  2. Или подобные конструкции

                  static void testCoverage() { 
                  
                          Integer c = 0;
                          c++;
                          c++;
                          ... // тут может быть несколько тысяч строк 
                          c++;
                  
                      } 

                    0
                    Кстати еще один вопрос, а как в SalesForce Apex с прикладными абстракциями вроде Ledger'ов? Они в языке, в виде стандартизированных библиотек или вообще на разработчике? И как с визуальным программированием этих и других прикладных абстракций? Конструкторами или кодом в основном все делается (имеется в виду на практике, а не в презенташках)?
                      –1

                      Бросилось в глаза:


                      `
                      public Integer decreaseVolume(Integer amount) {


                          volume -= amount; 
                      
                          if (volume < 0) { 
                      
                              volume = 0; 
                      
                          }   
                      
                          return volume; 
                      
                      }     `

                      А здесь не будет переполнения типа и вместо нуля — максимум? Зачем так рисковать? Почему не


                      `public Integer decreaseVolume(Integer amount) {


                          if (volume - amount <= 0) { 
                              volume = 0; 
                          }   else {
                      volume -= amount; 

                      }


                          return volume; 
                      
                      }     `
                        0

                        Если язык не просто так похож на Java — то не будет. При изначально неотрицательном volume после вычитания может получиться минимум -2147483647, который всё ещё влезает в Integer.

                          0

                          Да, но зачем привыкать так писать? Оптимизация неочевидна, а нарваться на ошибку легко, если по привычке на другом похожем языке так написать. Или если на какой-нибудь платформе это окажется беззнаковый тип.

                            0

                            Я за то, чтобы привыкать внимательно следить какие типы данных используются.


                            Кстати, ваш вариант (volume - amount <= 0) тоже мог бы быть подвержен переполнению, правильная проверка выглядит как volume <= amount.

                              0
                              Да, вы абсолютно правы про вариант. А типы данных тут не совсем явно видны, отсюда и у меня ошибка.

                      Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                      Самое читаемое