第十七篇的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中也何尝不可。篇中有问题地方欢迎指出,有不懂的欢迎留言。