Apex - Mẫu thiết kế kích hoạt
Các mẫu thiết kế được sử dụng để làm cho mã của chúng tôi hiệu quả hơn và tránh đạt đến giới hạn thống đốc. Thông thường các nhà phát triển có thể viết mã không hiệu quả có thể gây ra lặp lại các đối tượng. Điều này có thể dẫn đến mã không hiệu quả, hoạt động kém và có khả năng vi phạm các giới hạn của thống đốc. Điều này thường xảy ra nhất trong các trình kích hoạt, vì chúng có thể hoạt động dựa trên một tập hợp các bản ghi.
Chúng ta sẽ xem một số chiến lược thiết kế mẫu quan trọng trong chương này.
Mẫu thiết kế kích hoạt hàng loạt
Trong trường hợp kinh doanh thực tế, có thể bạn cần phải xử lý hàng nghìn bản ghi trong một lần. Nếu trình kích hoạt của bạn không được thiết kế để xử lý các tình huống như vậy, thì nó có thể bị lỗi khi xử lý hồ sơ. Có một số phương pháp hay nhất mà bạn cần tuân theo khi triển khai các trình kích hoạt. Tất cả các trình kích hoạt đều là trình kích hoạt hàng loạt theo mặc định và có thể xử lý nhiều bản ghi cùng một lúc. Bạn nên luôn có kế hoạch xử lý nhiều bản ghi cùng một lúc.
Hãy xem xét một trường hợp kinh doanh, trong đó, bạn cần xử lý số lượng lớn hồ sơ và bạn đã viết trình kích hoạt như được đưa ra bên dưới. Đây là ví dụ tương tự mà chúng tôi đã lấy để chèn bản ghi hóa đơn khi Trạng thái khách hàng thay đổi từ Không hoạt động thành Hoạt động.
// 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
}
}
}
Bây giờ bạn có thể thấy rằng Tuyên bố DML đã được viết trong khối vòng lặp sẽ hoạt động khi chỉ xử lý một số bản ghi nhưng khi bạn đang xử lý một số hàng trăm bản ghi, nó sẽ đạt đến giới hạn Tuyên bố DML cho mỗi giao dịch là governor limit. Chúng tôi sẽ có một cái nhìn chi tiết về Giới hạn của Thống đốc trong một chương tiếp theo.
Để tránh điều này, chúng tôi phải làm cho trình kích hoạt hiệu quả để xử lý nhiều bản ghi cùng một lúc.
Ví dụ sau sẽ giúp bạn hiểu như vậy -
// 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
}
Trình kích hoạt này sẽ chỉ kích hoạt 1 câu lệnh DML vì nó sẽ hoạt động trên một Danh sách và Danh sách có tất cả các bản ghi cần được sửa đổi.
Bằng cách này, bạn có thể tránh các giới hạn thống đốc câu lệnh DML.
Lớp trình trợ giúp kích hoạt
Viết toàn bộ mã trong trình kích hoạt cũng không phải là một thực hành tốt. Do đó, bạn nên gọi lớp Apex và ủy quyền xử lý từ Trigger sang lớp Apex như hình dưới đây. Lớp Trigger Helper là lớp thực hiện tất cả các xử lý cho trigger.
Hãy để chúng tôi xem xét lại ví dụ tạo bản ghi hóa đơn của chúng tôi.
// 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ớp người trợ giúp
public class CustomerTriggerHelper {
public static void createInvoiceRecords (List<apex_customer__c>
customerList, Map<id, apex_customer__c> oldMapCustomer) {
List<apex_invoice__c> 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
}
}
Trong điều này, tất cả quá trình xử lý đã được ủy quyền cho lớp người trợ giúp và khi chúng ta cần một chức năng mới, chúng ta có thể chỉ cần thêm mã vào lớp người trợ giúp mà không cần sửa đổi trình kích hoạt.
Kích hoạt đơn trên mỗi sObject
Luôn tạo một trình kích hoạt duy nhất trên mỗi đối tượng. Nhiều trình kích hoạt trên cùng một đối tượng có thể gây ra xung đột và lỗi nếu nó đạt đến giới hạn của thống đốc.
Bạn có thể sử dụng biến ngữ cảnh để gọi các phương thức khác nhau từ lớp trợ giúp theo yêu cầu. Hãy xem xét ví dụ trước của chúng tôi. Giả sử rằng phương thức createInvoice của chúng ta chỉ nên được gọi khi bản ghi được cập nhật và trên nhiều sự kiện. Sau đó, chúng tôi có thể kiểm soát việc thực thi như bên dưới:
// 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
}
}