第十七篇的Trigger用法為通過Handler方式實現Trigger的封裝,此種好處是一個Handler對應一個sObject,使本該在Trigger中寫的代碼分到Handler中,代碼更加清晰。
十七篇鏈接:salesforce 零基礎學習(十七)Trigger用法
有的時候對於sObject的trigger處理復雜的情況下,比如一個sObject的before update要實現功能1,2.....n功能情況下,Handler中需要在before update寫實現功能1--n的代碼。然而有些時候,我們在執行update情況下只需要讓他觸發功能i的功能代碼,使用上述Handler方法也可以搞定,只不過處理起來比較尷尬,此篇針對trigger中對於不同業務分成模塊進行處理。
一.Triggers基類
Triggers基類主要有以下內容:
1.枚舉:封裝的枚舉包含了Trigger中的所有情況;
2.Handler接口:此接口中聲明了一個方法handle,所有實現此接口的類都需要重寫次方法;
3.bind方法,用於綁定事件以及實現Handler接口的類,即綁定的事件會使用實現Handler接口的類進行業務邏輯處理;
4.execute方法,用於執行triggers中綁定的Handler。
代碼如下:

1 public class Triggers { 2 3 public enum Evt 4 { 5 AfterDelete, 6 AfterInsert, 7 AfterUndelete, 8 AfterUpdate, 9 BeforeDelete, 10 BeforeInsert, 11 BeforeUpdate 12 } 13 14 15 public interface Handler 16 { 17 void handle(); 18 } 19 20 Map<String, List<Handler>> eventHandlerMapping = new Map<String, List<Handler>>(); 21 22 public Triggers bind(Evt event, Handler eh) 23 { 24 List<Handler> handlers = eventHandlerMapping.get(event.name()); 25 if (handlers == null) 26 { 27 handlers = new List<Handler>(); 28 eventHandlerMapping.put(event.name(), handlers); 29 } 30 handlers.add(eh); 31 return this; 32 } 33 34 public void execute() 35 { 36 Evt ev = null; 37 if(Trigger.isInsert && Trigger.isBefore) 38 { 39 ev = Evt.beforeinsert; 40 } 41 else if(Trigger.isInsert && Trigger.isAfter) 42 { 43 ev = Evt.afterinsert; 44 } 45 else if(Trigger.isUpdate && Trigger.isBefore) 46 { 47 ev = Evt.beforeupdate; 48 } 49 else if(Trigger.isUpdate && Trigger.isAfter) 50 { 51 ev = Evt.afterupdate; 52 } 53 else if(Trigger.isDelete && Trigger.isBefore) 54 { 55 ev = Evt.beforedelete; 56 } 57 else if(Trigger.isDelete && Trigger.isAfter) 58 { 59 ev = Evt.afterdelete; 60 } 61 else if(Trigger.isundelete) 62 { 63 ev = Evt.afterundelete; 64 } 65 List<Handler> handlers = eventHandlerMapping.get(ev.name()); 66 if (handlers != null && !handlers.isEmpty()) 67 { 68 for (Handler h : handlers) 69 { 70 h.handle(); 71 } 72 } 73 } 74 }
二.相關的實現Handler接口的類
此處例舉兩個類,分別實現Triggers.Handler並且實現相關的Handle方法
1.F1Handler
1 public without sharing class F1Handler implements Triggers.Handler { 2 public void Handle(){ 3 List<Company_Info__c> companyInfoList = trigger.new; 4 //TODO 5 //do something start 6 system.debug('===============executeF1Handler'); 7 //do something end 8 } 9 }
2.F2Handler
1 public with sharing class F2Handler implements Triggers.Handler { 2 public void Handle(){ 3 List<Company_Info__c> companyInfoList = trigger.new; 4 //TODO 5 //do something start 6 system.debug('===============executeF2Handler'); 7 //do something end 8 } 9 }
三.相關Trigger中Handler是否執行的Helper類
有的時候業務需要不同地方的入口進行相同的操作,需要執行不同的trigger業務模塊,比如在controller正常的更新需要全部執行trigger方法模塊,在其他trigger中更新此sObject則只需要一部分模塊,這個時候需要相關Helper類方法來控制是否執行哪塊邏輯。
1 public without sharing class TriggerExecutionHelper { 2 public static Boolean enableExecuteF1 { 3 get{ 4 if(enableExecuteF1 == null) { 5 enableExecuteF1 = true; 6 } 7 return enableExecuteF1; 8 } 9 set; 10 } 11 12 public static Boolean enableExecuteF2{ 13 get{ 14 if(enableExecuteF2 == null) { 15 enableExecuteF2 = true; 16 } 17 return enableExecuteF2; 18 } 19 set; 20 } 21 22 }
四.Trigger代碼部分
trigger代碼部分用來判斷是否需要執行哪些情況trigger
1 trigger CompanyInfoTrigger on Company_Info__c (after delete, after insert, after undelete, after update, before delete, before insert, before update) { 2 3 Triggers companyInfoTrigger = new Triggers(); 4 if(TriggerExecutionHelper.enableExecuteF1) { 5 companyInfoTrigger.bind(Triggers.Evt.BeforeInsert, new F1Handler()); 6 } 7 8 if(TriggerExecutionHelper.enableExecuteF2) { 9 companyInfoTrigger.bind(Triggers.Evt.BeforeInsert, new F2Handler()); 10 } 11 12 companyInfoTrigger.Execute(); 13 14 }
效果展示:
1.通過系統頁面插入一條數據,默認走全部的trigger內容
相關log可以查看執行結果
2.通過匿名塊執行insert則只執行trigger中一個業務模塊代碼
總結:如果業務邏輯特別清晰並且可以分模塊處理,則可以使用此種方法,達到的效果為業務清晰明了,后期人員也便於維護。缺點為如果相關模塊的Handler都對一個字段進行處理,則會有相關先后處理的問題以及出bug調試時間增多等,具體使用哪種還是看具體的業務以及個人使用習慣,業務簡單直接寫在trigger中也未嘗不可。篇中有問題地方歡迎指出,有不懂的歡迎留言。