एपेक्स - ट्रिगर डिज़ाइन पैटर्न

हमारे कोड को अधिक कुशल बनाने और गवर्नर की सीमा से टकराने से बचने के लिए डिज़ाइन पैटर्न का उपयोग किया जाता है। अक्सर डेवलपर्स अक्षम कोड लिख सकते हैं जो वस्तुओं के दोहराए जाने का कारण बन सकता है। इसके परिणामस्वरूप अक्षम, खराब प्रदर्शन करने वाला कोड और संभावित रूप से गवर्नर की सीमा का उल्लंघन हो सकता है। यह आमतौर पर ट्रिगर्स में होता है, क्योंकि वे रिकॉर्ड के एक सेट के खिलाफ काम कर सकते हैं।

हम इस अध्याय में कुछ महत्वपूर्ण डिजाइन पैटर्न रणनीतियों को देखेंगे।

थोक ट्रिगर डिजाइन पैटर्न

वास्तविक व्यापार के मामले में, यह संभव होगा कि आपको एक बार में हजारों रिकॉर्ड संसाधित करने की आवश्यकता हो। यदि आपका ट्रिगर ऐसी स्थितियों को संभालने के लिए डिज़ाइन नहीं किया गया है, तो यह रिकॉर्ड को संसाधित करते समय विफल हो सकता है। कुछ सर्वोत्तम प्रथाएँ हैं जिन्हें आपको ट्रिगर्स को लागू करते समय पालन करने की आवश्यकता है। सभी ट्रिगर डिफ़ॉल्ट रूप से थोक ट्रिगर होते हैं, और एक समय में कई रिकॉर्ड की प्रक्रिया कर सकते हैं। आपको हमेशा एक समय में एक से अधिक रिकॉर्ड संसाधित करने की योजना बनानी चाहिए।

एक व्यवसाय के मामले पर विचार करें, जिसमें, आपको बड़ी संख्या में रिकॉर्ड संसाधित करने की आवश्यकता है और आपने नीचे दिए अनुसार ट्रिगर लिखा है। यह वही उदाहरण है जो हमने इनवॉइस रिकॉर्ड को डालने के लिए लिया था जब ग्राहक स्थिति निष्क्रिय से सक्रिय में बदल जाती है।

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

अब आप देख सकते हैं कि लूप ब्लॉक के लिए डीएमएल स्टेटमेंट लिखा गया है जो केवल कुछ रिकॉर्ड को प्रोसेस करते समय काम करेगा लेकिन जब आप कुछ सैकड़ों रिकॉर्ड प्रोसेस कर रहे हैं, तो यह डीएमएल स्टेटमेंट की सीमा प्रति ट्रांजैक्शन तक पहुंच जाएगा जो कि है governor limit। हम बाद के अध्याय में गवर्नर लिमिट पर विस्तृत नज़र रखेंगे।

इससे बचने के लिए, हमें एक बार में कई रिकॉर्ड को संसाधित करने के लिए ट्रिगर को कुशल बनाना होगा।

निम्नलिखित उदाहरण आपको वही समझने में मदद करेंगे -

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

यह ट्रिगर केवल 1 डीएमएल स्टेटमेंट को फायर करेगा क्योंकि यह एक सूची पर काम कर रहा होगा और सूची में सभी रिकॉर्ड हैं जिन्हें संशोधित करने की आवश्यकता है।

इस तरह, आप डीएमएल स्टेटमेंट गवर्नर की सीमा से बच सकते हैं।

ट्रिगर हेल्पर क्लास

ट्रिगर में पूरे कोड को लिखना भी एक अच्छा अभ्यास नहीं है। इसलिए आपको एपेक्स क्लास को कॉल करना चाहिए और नीचे दिखाए गए अनुसार ट्रिगर से प्रोसेसिंग को एपेक्स क्लास को सौंपना चाहिए। ट्रिगर हेल्पर वर्ग वह वर्ग है जो ट्रिगर के लिए सभी प्रसंस्करण करता है।

आइए हम अपने चालान रिकॉर्ड निर्माण उदाहरण पर फिर से विचार करें।

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

इसमें, सभी प्रोसेसिंग को हेल्पर क्लास को सौंप दिया गया है और जब हमें एक नई कार्यक्षमता की आवश्यकता होती है, तो हम ट्रिगर को संशोधित किए बिना हेल्पर क्लास में कोड जोड़ सकते हैं।

प्रत्येक sObject पर सिंगल ट्रिगर

प्रत्येक ऑब्जेक्ट पर हमेशा एक ट्रिगर बनाएं। एक ही ऑब्जेक्ट पर कई ट्रिगर गवर्नर की सीमा तक पहुंचने पर संघर्ष और त्रुटियों का कारण बन सकते हैं।

आप आवश्यकता के अनुसार सहायक वर्ग से विभिन्न तरीकों को कॉल करने के लिए संदर्भ चर का उपयोग कर सकते हैं। हमारे पिछले उदाहरण पर विचार करें। मान लीजिए कि हमारी 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<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
   }
}