設(shè)計(jì)模式用于使我們的代碼更高效,并避免達(dá)到調(diào)節(jié)器限制。開(kāi)發(fā)人員通常會(huì)編寫(xiě)無(wú)效的代碼,導(dǎo)致對(duì)象的重復(fù)實(shí)例化。這可能導(dǎo)致效率低下,性能不佳的代碼,并可能違反調(diào)節(jié)器限制。這通常發(fā)生在觸發(fā)器中,因?yàn)樗鼈兛梢葬槍?duì)一組記錄進(jìn)行操作。
我們將在本章中討論一些重要的設(shè)計(jì)模式策略。
在真實(shí)的業(yè)務(wù)案例中,您可能需要一次處理成千上萬(wàn)條記錄。如果觸發(fā)器未設(shè)計(jì)為處理此類(lèi)情況,那么在處理記錄時(shí)可能會(huì)失敗。在實(shí)現(xiàn)觸發(fā)器時(shí),您需要遵循一些最佳做法。默認(rèn)情況下,所有觸發(fā)器都是批量觸發(fā)器,并且可以一次處理多個(gè)記錄。您應(yīng)該計(jì)劃一次處理多個(gè)記錄。
思考一個(gè)業(yè)務(wù)案例,其中你想要處理大量的記錄,你已經(jīng)寫(xiě)下面的觸發(fā)器。這與我們?cè)诳蛻?hù)狀態(tài)從非活動(dòng)更改為活動(dòng)時(shí)插入發(fā)票記錄時(shí)所采用的示例相同。
//Bad Trigger Example trigger Customer_After_Insert on APEX_Customer__c (after update) { for (APEX_Customer__c objCustomer: Trigger.new) { if (objCustomer.APEX_Customer_Status__c == 'Active' && trigger.oldMap.get(objCustomer.id).APEX_Customer_Status__c == 'Inactive') {//condition to check the old value and new value APEX_Invoice__c objInvoice = new APEX_Invoice__c(); objInvoice.APEX_Status__c = 'Pending'; insert objInvoice;//DML to insert the Invoice List in SFDC } } }
如果你仔細(xì)看看,那么你可以看到DML語(yǔ)句已經(jīng)寫(xiě)在for循環(huán)塊中,這將在處理只有少數(shù)記錄時(shí)工作,但是當(dāng)你處理幾百條記錄時(shí),它將達(dá)到每個(gè)事務(wù)的DML語(yǔ)句限制 是調(diào)速器極限。 我們將在后面章節(jié)詳細(xì)介紹Governor Limits。
為了避免這種情況,我們必須使觸發(fā)器有效地一次處理多個(gè)記錄。
下面是相同的最佳實(shí)踐范例:
//Modified Trigger Code-Bulk Trigger trigger Customer_After_Insert on APEX_Customer__c (after update) { List<apex_invoice__c> InvoiceList = new List<apex_invoice__c>(); for (APEX_Customer__c objCustomer: Trigger.new) { if (objCustomer.APEX_Customer_Status__c == 'Active' && trigger.oldMap.get(objCustomer.id).APEX_Customer_Status__c == 'Inactive') {//condition to check the old value and new value APEX_Invoice__c objInvoice = new APEX_Invoice__c(); objInvoice.APEX_Status__c = 'Pending'; InvoiceList.add(objInvoice);//Adding records to List } } insert InvoiceList;//DML to insert the Invoice List in SFDC, this list contains the all records which need to be modified and will fire only one DML }此觸發(fā)器將僅觸發(fā)1個(gè)DML語(yǔ)句,因?yàn)樗鼘?duì)列表進(jìn)行操作,并且列表具有需要修改的所有記錄。
通過(guò)這種方式,可以避免DML語(yǔ)句的調(diào)節(jié)器限制。
在觸發(fā)器中編寫(xiě)整個(gè)代碼也不是一個(gè)好的做法。 因此,您應(yīng)該調(diào)用Apex類(lèi),并將處理從Trigger委派給Apex類(lèi),如下所示。 觸發(fā)器助手類(lèi)是執(zhí)行觸發(fā)器的所有處理的類(lèi)。
讓我們?cè)俅尾扇∥覀兊陌l(fā)票記錄創(chuàng)建示例。
//Below is the Trigger without Helper class trigger Customer_After_Insert on APEX_Customer__c (after update) { List<apex_invoice__c> InvoiceList = new List<apex_invoice__c>(); for (APEX_Customer__c objCustomer: Trigger.new) { if (objCustomer.APEX_Customer_Status__c == 'Active' && trigger.oldMap.get(objCustomer.id).APEX_Customer_Status__c == 'Inactive') {//condition to check the old value and new value APEX_Invoice__c objInvoice = new APEX_Invoice__c(); objInvoice.APEX_Status__c = 'Pending'; InvoiceList.add(objInvoice); } } insert InvoiceList;//DML to insert the Invoice List in SFDC } //Below is the trigger with helper class //Trigger with Helper Class trigger Customer_After_Insert on APEX_Customer__c (after update) { CustomerTriggerHelper.createInvoiceRecords(Trigger.new, trigger.oldMap);//Trigger calls the helper class and does not have any code in Trigger }
輔助類(lèi):
public class CustomerTriggerHelper { public static void createInvoiceRecords (List<apex_customer__c> customerList, Map<id, apex_customer__c> oldMapCustomer) { List<apex_invoice__c> InvoiceList = new List<apex_invoice__c>(); for (APEX_Customer__c objCustomer: customerList) { if (objCustomer.APEX_Customer_Status__c == 'Active' && oldMapCustomer.get(objCustomer.id).APEX_Customer_Status__c == 'Inactive') {//condition to check the old value and new value APEX_Invoice__c objInvoice = new APEX_Invoice__c(); //objInvoice.APEX_Status__c = 'Pending'; InvoiceList.add(objInvoice); } } insert InvoiceList;//DML to insert the Invoice List in SFDC } }
在這里,所有的處理被委托給助手類(lèi),當(dāng)我們需要一個(gè)新的功能,我們可以簡(jiǎn)單地添加代碼到助手類(lèi),而不修改觸發(fā)器。
始終在每個(gè)對(duì)象上創(chuàng)建單個(gè)觸發(fā)器。 同一對(duì)象上的多個(gè)觸發(fā)器可能會(huì)導(dǎo)致沖突和錯(cuò)誤,如果它達(dá)到控制器限制。
您可以使用上下文變量根據(jù)需求從輔助類(lèi)調(diào)用不同的方法。 考慮我們前面的例子。 假設(shè)我們的createInvoice方法只有在更新記錄和多個(gè)事件時(shí)才被調(diào)用。 然后我們可以控制執(zhí)行如下:
//Trigger with Context variable for controlling the calling flow trigger Customer_After_Insert on APEX_Customer__c (after update, after insert) { if (trigger.isAfter && trigger.isUpdate) {//This condition will check for trigger events using isAfter and isUpdate context variable CustomerTriggerHelper.createInvoiceRecords(Trigger.new);//Trigger calls the helper class and does not have any code in Trigger and this will be called only when trigger ids after update } } //Helper Class public class CustomerTriggerHelper { //Method To Create Invoice Records public static void createInvoiceRecords (List<apex_customer__c> customerList) { for (APEX_Customer__c objCustomer: customerList) { if (objCustomer.APEX_Customer_Status__c == 'Active' && trigger.oldMap.get(objCustomer.id).APEX_Customer_Status__c == 'Inactive') {//condition to check the old value and new value APEX_Invoice__c objInvoice = new APEX_Invoice__c(); objInvoice.APEX_Status__c = 'Pending'; InvoiceList.add(objInvoice); } } insert InvoiceList;//DML to insert the Invoice List in SFDC } }
更多建議: