Apex Code Best Practices

Apex Code Best Practices

Abstract

Apex code is the Force.com on-demand programming language for developers interested in building the next generation of business applications. Apex enables developers to add business logic to most system events, including button clicks, related record updates, and Visualforce pages. Apex Code can be initiated by Web service requests and from triggers on objects. Some key best practices with any programming language that helps you write efficient and scalable code. This blog is about Apex Code Best Practices.

In this article, we’ll discuss the below mentioned best practices to write and design Apex Code in Salesforce :

#1: Bulkify your Code

Bulkifying?Apex code means making sure your code handles more than one record at a time.

Example of poorly written code that handles only one record at a time.

trigger accountTest on Account (after update) {
?
? ?//This only handles the first record in the Trigger.new collection
? ?Account acc = Trigger.new[0];
? ?List<Contact> contacts = [select id, firstname, lastname, email 
                             from Contact where accountId = :acc.Id]; 
 }        

Below is the bulkified code written.

trigger accountTest on Account (after update) {
?
? ?//Create List Collection
   
   List<Id> accIds= new List<Id>();

   //Loop through all records in the Trigger.new collection
? ?for(Account acc: Trigger.new) {
       accIds.add(acc.Id);
   }

? ?List<Contact> contacts = [select id, firstname, lastname, email 
                             from Contact where accountId IN :accIds]; 
 
}        

The above version of code iterates across the entire “Trigger.new” collection with for loop. If this Trigger is invoked with up to 200 Accounts, all records are properly processed.

#2: Avoid SOQL Queries or DML statements inside FOR Loops

Governor limits are calculated at runtime. After the request is initiated, any Apex code executed in that transaction applies and shares the governor limits.

Per-transaction Apex Limits

Total number of SOQL Queries: 100 (Sync) | 200 (Async)

Total number of records retrieved: 50K

Total number of DML statements: 150

Total number of records processed by DML: 10K

Maximum SOQL query runtime before Salesforce cancels the transaction: 120 seconds

Poor Code :

trigger GetContacts on Accounts (after insert, after update) {
		for(Account a : Trigger.new){
			List c = [SELECT Id FROM Contact WHERE AccountId = a.Id];
        }
}        

Optimal Way :

trigger GetContacts on Accounts (after insert, after update) {
		Set ids = Trigger.newMap.keySet();
		List c = [SELECT Id FROM Contact WHERE AccountId in :ids];
}        

#3: Never call @future/asynchronous methods inside for loop

The @future annotation methods cannot be used in Visualforce controls in GetMethodName or setMethodName methods, not in constructor also. Plans with the future annotation cannot take objects as arguments; it always takes id as argument.

The @future method should be invoked with?the batch of records so that it is only invoked once for all documents it needs to process:

trigger accountAsyncTrigger on Account (after insert, after update) {
? ? //By passing the @future method a set of Ids, it only needs to be
? ? //invoked once to handle all of the data.
? ? someClass.processAccount(Trigger.newMap.keySet());
}        

And now the @future records is designed to receive forms:

global class someClass{
  @future
? public static void processAccount(Id accountId) {
? // some code here
? ? ? ? ? }
}        

#4: Avoid Hardcoding IDs

In Salesforce, Hardcode IDs should be avoided, the code should be written to fetch the record IDs dynamically. If the record ID’s are changed between two different environments, the logic can dynamically identify the correct data without failure.

Example of Code with Dynamic Id:

#5: Use a single Trigger on the object

Combine all possible triggers on a specific object into just one Trigger. Instead of coding your logic directly inside a trigger, you code it separately in a class. Then in your Trigger, you create an object of the course, then run your records through its logic.

#6: Querying objects having more than 50,000 records.

The total number of records fetched by SOQL query is 50,000 records. If we query more than 50,000 records, we exceed the heap limit, and a runtime exception is thrown.

//Runtime Exception will be thrown for following queey if records > 50K
Account[] accts = [SELECT id,name FROM account];
        

To avoid this, for loop can be used, and SOQL query can be written outside for loop in the

following way.

for(List<Account> acct :[SELECT id, name FROM account WHERE name LIKE 'Test'])?
{
? ? // Write your logic here
}        

Published by


Ashwin Dhole

Salesforce Consultant at CloudPrism Solutions || Certified Platform Developer I?|| 2x Salesforce Certified|| PICT’19

Post navigation



Driving Successful Digital Transformation with the Right Tech Implementation Partner


Salesforce Reports that can be automatically filtered by users role

要查看或添加评论,请登录

CloudPrism Solutions的更多文章