📅  最后修改于: 2020-11-05 03:18:50             🧑  作者: Mango
设计模式用于使我们的代码更有效,并避免达到调控器限制。开发人员通常可以编写效率低下的代码,从而导致对象的重复实例化。这可能会导致效率低下,性能不佳的代码,并有可能违反调控器限制。这最常见于触发器,因为它们可以针对一组记录进行操作。
我们将在本章中看到一些重要的设计模式策略。
在实际的业务案例中,您可能需要一次性处理成千上万条记录。如果触发器并非旨在处理此类情况,则在处理记录时可能会失败。实施触发器时,您需要遵循一些最佳实践。默认情况下,所有触发器都是批量触发器,并且可以一次处理多个记录。您应该始终计划一次处理多个记录。
考虑一个业务案例,其中您需要处理大量记录,并且已编写了如下所示的触发器。这与我们在“客户状态”从“非活动”更改为“活动”时插入发票记录所采用的示例相同。
// 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语句,该语句仅在处理少量记录时有效,但是在处理数百条记录时,它将达到每个事务的DML语句限制,即限制者限制。在下一章中,我们将对限速器限制进行详细介绍。
为避免这种情况,我们必须使触发器高效,一次可处理多个记录。
以下示例将帮助您理解相同的内容-
// Modified Trigger Code-Bulk Trigger
trigger Customer_After_Insert on APEX_Customer__c (after update) {
List InvoiceList = new List();
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
}
此触发器将仅触发1条DML语句,因为它将在一个List上操作,并且该List具有所有需要修改的记录。
通过这种方式,您可以避免DML语句调控器限制。
在触发器中编写整个代码也不是一个好习惯。因此,您应该调用Apex类,并将处理从Trigger委托给Apex类,如下所示。触发器帮助器类是为触发器执行所有处理的类。
让我们再次考虑我们的发票记录创建示例。
// Below is the Trigger without Helper class
trigger Customer_After_Insert on APEX_Customer__c (after update) {
List InvoiceList = new List();
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
customerList, Map oldMapCustomer) {
List InvoiceList = new Listvapex_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
}
}
在此过程中,所有处理都委托给了helper类,当我们需要新功能时,我们可以简单地将代码添加到helper类中,而无需修改触发器。
始终在每个对象上创建一个触发器。如果同一对象上的多个触发器达到调速器限制,则可能导致冲突和错误。
您可以根据需要使用上下文变量从帮助程序类调用不同的方法。考虑我们前面的例子。假设仅当记录更新且发生多个事件时才应调用我们的createInvoice方法。然后我们可以控制执行如下-
// 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 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
}
}