Всем привет!
Довольно часто в непосредственной практике работы с клиентом мы слышим просьбы и/или требования клиентов создать именно «универсальное решение». Или же уполномоченный «технический представитель» клиента, заказчика, может нам гарантировать и утвердить только 90% архитектуры решения, а об оставшихся десяти процентах мы можем услышать что-либо вроде: «точно можно сказать лишь то, что ничего не ясно и все будет еще меняться».
В данных случаях всегда, конечно, можно написать собственный «универсальный» мини-фреймворк, реализующий все возможные варианты метаморфоз чайника Рассела (при наличии времени до дедлайна, средств у клиента и вдохновения у программистов и архитекторов), но в данном цикле статей рассмотрим варианты менее радикального подхода. А именно, как возложить бремя доказательства дать возможность расширения функциональности самому клиенту.
1. «И в начале было флоу, аутолончд флоу» (ц, неизвестный автор).
Самый простой и очевидный шаг - вынести часть функциональности в флоу. Который сам по себе является обожаемым и знакомым инструментом для большинства админов на стороне клиента (читай, штатных) или, по крайней мере, не настолько ужасным, «как этот ваш апекс код».
Использование флоу в качестве расширения функциональности апекс кода позволит клиенту самостоятельно, без необходимости вносить правки в код, адаптировать поведение запрограммированного решения под свои нужды.
Для использования в качестве примера в данной статье, аутолончд флоу будет создан пока что простейший, а именно возвращающим нам ровно то, что мы ему и скормили передали в качестве входных параметров. Естественно, будем сразу же опираться на best practice и использовать bulkification там, где это необходимо:
Собственно, на рисунке выше представлен базовый вид менеджера ресурсов. Было создано две коллекции объектов (не забываем правильно расставлять чек-боксы available for input / output):
-
одна коллекция для входящих параметров
-
еще одна - для возвращаемых значений
В качестве «опорного» объекта был выбран Case (не судите строго, так исторически сложилось). И, собственно, наш несложный флоу в виде процесса:
И конечный вариант менеджера ресурсов:
2. Теперь вкусное код:
Для запуска флоу из апекс кода нам будет необходим класс Flow.Interview, который даст нам всю необходимую функциональность для того, чтобы использовать флоу в качестве расширения функциональности нашего кода.
Мы можем воспользоваться возможностью заранее закрепить в коде использование четко определенного флоу по его имени, например, объявив переменную класса где-то так:
Flow.Interview.Awesome_Super_Flow myMarvelousFlow {get; set;}
Но поскольку наша цель — универсальность, глядя в будущее с оптимизмом, так мы делать не будем. Вместо этого мы воспользуемся методом класса Flow.Interview createInterview(String flowName, Map<String, Object> inputVariables) для создания экземпляра нашего флоу. Еще нам понадобятся две коллекции Map<String, Object> для входных и результирующих параметров.
Пример кода:
Данный “базовый” код, совместно с “базовым” флоу, дают нам следующий вывод в дебаг-логах:
Summary:
Плюсы:
- часть функциональности вынесена в флоу (например, логика «фильтрации» записей, которые, будучи отфильтрованными, в дальнейшем обрабатываются уже апекс логикой, что достигается простым изменением самого базового флоу).
- флоу в связке с апексом хорошо поддается bulkification и нативно работает с коллекциями записей.
Минусы:
- имя флоу и переменных все еще содержатся в нашем классе, а значит мы привязаны к одному единственному флоу в качестве расширения нашей функциональности.
В следующей статье мы попробуем увеличить число плюсов, сократить число минусов, а также привнести немного больше универсальности в наше «базовое» решение.