第十七篇的Trigger用法爲經過Handler方式實現Trigger的封裝,此種好處是一個Handler對應一個sObject,使本該在Trigger中寫的代碼分到Handler中,代碼更加清晰。html
十七篇連接:salesforce 零基礎學習(十七)Trigger用法app
有的時候對於sObject的trigger處理複雜的狀況下,好比一個sObject的before update要實現功能1,2.....n功能狀況下,Handler中須要在before update寫實現功能1--n的代碼。然而有些時候,咱們在執行update狀況下只須要讓他觸發功能i的功能代碼,使用上述Handler方法也能夠搞定,只不過處理起來比較尷尬,此篇針對trigger中對於不一樣業務分紅模塊進行處理。ide
一.Triggers基類post
Triggers基類主要有如下內容:學習
1.枚舉:封裝的枚舉包含了Trigger中的全部狀況;this
2.Handler接口:此接口中聲明瞭一個方法handle,全部實現此接口的類都須要重寫次方法;spa
3.bind方法,用於綁定事件以及實現Handler接口的類,即綁定的事件會使用實現Handler接口的類進行業務邏輯處理;debug
4.execute方法,用於執行triggers中綁定的Handler。3d
代碼以下:調試
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中也何嘗不可。篇中有問題地方歡迎指出,有不懂的歡迎留言。