Думаю, что вы уже знакомы с такой конструкцией как switch . Она примется во многих языках программирования. С недавних пор язык Apex перестал быть исключением и тоже обзавёлся таким дополнением.
Не будем останавливаться на принципах и синтаксисе работы Switch. Перейдём у сути.
Взаимодействие Switch и Trigger
До того как начнём, стоит обратить внимание на новую переменную из контекста триггера.
Довольно долго в Trigger классе было 7 булевых переменных для определения контекста вашего триггера (before/after and insert/update/delete/undelete). Но для передачи этой информации о состоянии триггера придётся передавать каждое состояние отдельно, или же создавать собственную структуру. Более лёгкий путь немного ниже.
Trigger.operationType
Итак, теперь у нас есть просто способ для определения состояния триггера. Все 7 переменных были завёрнуты в переменную enum типа названую Trigger.operationType .
BEFORE_INSERT
AFTER_INSERT
BEFORE_UPDATE
AFTER_UPDATE
BEFORE_DELETE
AFTER_DELETE
AFTER_UNDELETE
Если объединить эту переменную и Apex switch, то код нашего триггера станет куда лучше.
Switch и Enum в триггере
Предположим, существует триггер и мы следуем лучшей практике: один триггер для одного типа объекта. Нам необходимо имплементировать следующий функционал в нём:
- Создать related записи в after insert и after update контексте
- В before insert задать некоторые значения
- В некоторых случаях предотвратить удаление данных в before delete
trigger AccountTrigger on Account (before insert, after insert, before update, after update, before delete, after delete, after undelete) {
if (Trigger.isAfter) {
if (Trigger.isInsert || Trigger.isUpdate) {
//create related records
} else if (Trigger.isDelete){
//prevent deletion of sensitive data
}
} else {
if (Trigger.isInsert) {
//set value on record create
}
}
}
Эта логика будет работать нормально, но в будущем будет сложно понять с первого взгляда, что за чем происходит.
Теперь давайте попробуем приметь наш новый метод. Последуем старой практике и передадим переменную в статический метод класса хендлера.
trigger AccountTrigger on Account (before insert, after insert, before update, after update, before delete, after delete, after undelete) {
AccountTriggerHandler.handleTrigger(Trigger.new, Trigger.old, Trigger.operationType);
}
В этом небольшом примере мы вызываем метод handleTrigger и передаем ему переменную Trigger.operationType . Далее хендлер сможет узнать всё о состоянии триггера. Давайте посмотрим детальнее, что происходит внутри хендлера:
public with sharing class AccountTriggerHandler {
public static void handleTrigger(List<Account> newRecords, List<Account> oldRecords, System.TriggerOperation triggerEvent ) {
switch on triggerEvent {
when AFTER_INSERT, AFTER_UPDATE {
//create related records
}
when BEFORE_INSERT {
//set value on record create
}
when AFTER_DELETE {
//prevent deletion of sensitive data
}
when else {
//do nothing for AFTER_UNDELETE, BEFORE_DELETE, or BEFORE_UPDATE
}
}
}
}
Так понятнее, верно ?