Apex - 觸發(fā)設(shè)計(jì)模式

2019-10-26 16:26 更新

設(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ì)模式策略。


批量觸發(fā)器設(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ā)助手類(lèi)

在觸發(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è)sObject上的單個(gè)觸發(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
	}
}


以上內(nèi)容是否對(duì)您有幫助:
在線(xiàn)筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)