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

2019-10-26 16:26 更新

設(shè)計模式用于使我們的代碼更高效,并避免達到調(diào)節(jié)器限制。開發(fā)人員通常會編寫無效的代碼,導(dǎo)致對象的重復(fù)實例化。這可能導(dǎo)致效率低下,性能不佳的代碼,并可能違反調(diào)節(jié)器限制。這通常發(fā)生在觸發(fā)器中,因為它們可以針對一組記錄進行操作。


我們將在本章中討論一些重要的設(shè)計模式策略。


批量觸發(fā)器設(shè)計模式

在真實的業(yè)務(wù)案例中,您可能需要一次處理成千上萬條記錄。如果觸發(fā)器未設(shè)計為處理此類情況,那么在處理記錄時可能會失敗。在實現(xiàn)觸發(fā)器時,您需要遵循一些最佳做法。默認情況下,所有觸發(fā)器都是批量觸發(fā)器,并且可以一次處理多個記錄。您應(yīng)該計劃一次處理多個記錄。


思考一個業(yè)務(wù)案例,其中你想要處理大量的記錄,你已經(jīng)寫下面的觸發(fā)器。這與我們在客戶狀態(tài)從非活動更改為活動時插入發(fā)票記錄時所采用的示例相同。

//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
		}
	}
}	

如果你仔細看看,那么你可以看到DML語句已經(jīng)寫在for循環(huán)塊中,這將在處理只有少數(shù)記錄時工作,但是當(dāng)你處理幾百條記錄時,它將達到每個事務(wù)的DML語句限制 是調(diào)速器極限。 我們將在后面章節(jié)詳細介紹Governor Limits。


為了避免這種情況,我們必須使觸發(fā)器有效地一次處理多個記錄。


下面是相同的最佳實踐范例:

//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個DML語句,因為它將對列表進行操作,并且列表具有需要修改的所有記錄。

通過這種方式,可以避免DML語句的調(diào)節(jié)器限制。


觸發(fā)助手類

在觸發(fā)器中編寫整個代碼也不是一個好的做法。 因此,您應(yīng)該調(diào)用Apex類,并將處理從Trigger委派給Apex類,如下所示。 觸發(fā)器助手類是執(zhí)行觸發(fā)器的所有處理的類。


讓我們再次采取我們的發(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
}

輔助類:

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
    }
}

在這里,所有的處理被委托給助手類,當(dāng)我們需要一個新的功能,我們可以簡單地添加代碼到助手類,而不修改觸發(fā)器。


每個sObject上的單個觸發(fā)器

始終在每個對象上創(chuàng)建單個觸發(fā)器。 同一對象上的多個觸發(fā)器可能會導(dǎo)致沖突和錯誤,如果它達到控制器限制。


您可以使用上下文變量根據(jù)需求從輔助類調(diào)用不同的方法。 考慮我們前面的例子。 假設(shè)我們的createInvoice方法只有在更新記錄和多個事件時才被調(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)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號