In this article, we will read about Salesforce Apex Best Practices.
Best Practices for Triggers:
1.Each object should have one trigger . You just need one Apex Trigger for one specific object.
If you create many triggers for a single object, there is no way to regulate the order of execution if those triggers can execute simultaneously.
/* * @description: Apex Best Practices * @author: sfdc4u.com */ trigger AccountTrigger on Account(before insert, after insert, before update, after update, before delete, after delete, after undelete) { switch on Trigger.operationType { when BEFORE_INSERT { //Invoke before insert trigger handler system.debug('Before Insert'); } when AFTER_INSERT { //Invoke after insert trigger handler system.debug('After Insert'); } when BEFORE_UPDATE { //Invoke before update trigger handler system.debug('Before Update'); } when AFTER_UPDATE { //Invoke after update trigger handler system.debug('After Update'); } when BEFORE_DELETE { //Invoke before delete trigger handler system.debug('Before Delete'); } when AFTER_DELETE { //Invoke after delete trigger handler system.debug('After Delete'); } when AFTER_UNDELETE { //Invoke after undelete trigger handler system.debug('After Undelete'); } } }
2. Triggers without Logic
Methods that you include in your triggers cannot be exposed for testing. You cannot also make logic available for reuse elsewhere in your organization.
3. Context-specific handler methods should be created in trigger handlers.
4. Bulkify the code.
Making sure the code correctly handles more than one record at a time is known as bulkifying Apex code.
Take a look at the code below – this is a bad example of code that has not been bulkified. Salesforce Data Loader tool is used to upload the bulk records. This code can only process a single record in a chunk of 200 records.
/* * @description: Apex Best Practices * @author: sfdc4u.com */ Trigger AccountTrigger on Account (before insert, before update) { Account acc = Trigger.new[0]; if(acc.Name.contains('Test')) { acc.Name = 'Bad'+acc.Name; } }
The code below has been bulkified so that it can process your logic for all records.
/* * @description: Apex Best Practices * @author: sfdc4u.com */ trigger AccountTrigger on Account (before insert, before update) { for(Account acc :Trigger.new){ if(acc.Name.contains('Test')) { acc.Name = 'Bad'+acc.Name; } } }
5. Prevent using DML or SOQL queries inside Loops FOR
There is a governor limit of 100 SOQL queries per Apex request before it is exceeded.
The governor limit will raise a runtime error if this trigger is triggered by a batch of more than 100 account records.
Bad example: DML statement written in the for a loop. The governor limit will be exceeded if there are more than150 account records to update.
The example code below demonstrates how to write DML outside of a for loop.
6. Making Use of Collections, Simplifying Queries, and Effective for Loops
Apex Collections should be used to efficiently query data and store it in memory.
Writing efficient Apex code and avoiding governor constraints can be greatly improved by combining the use of collections and optimizing SOQL queries.
7. Queries on Big Data Sets
A request’s maximum number of records that SOQL queries can return is 50,000. A SOQL query for loop must be used in place of returning a big group of queries if doing so leads you to go over your heap limit. Through the use of internal calls to query and query More, it can handle numerous batches of records.
8. Use @future appropriately as needed.
It is crucial to write your Apex code to effectively handle large numbers of records at once.
The @future keyword-annotated asynchronous Apex functions are likewise true of this. you may learn about the differences between synchronous and asynchronous Apex.
9. Prevent Hard Coding of IDs
It’s crucial to avoid hardcoding IDs in Apex code when moving between sandbox and production environments or downloading Force.com AppExchange packages.
If you run the above code in different environments, it will fail. The code snippet below is the best way to implement this type of requirement.
By doing this, the logic can dynamically select the appropriate data to work against and not fail, even if the record IDs vary between environments.
A few other best practices for triggers
1.Each object should have a single trigger.
2.Prevent complicated logic triggers. Triggers should delegate to Apex classes that contain the actual execution logic in order to facilitate testing and reuse.
3.Bulkify any “helper” classes and/or methods.
4.”Bulkified” triggers that can process up to 200 records per call should be available.
5.Execute DML statements with collections rather than one record for each DML statement.
6.Use Collections in SOQL “WHERE” clauses to retrieve all records back in single query.
7.Make sure to include the object name in your naming conventions (e.g. AccountTrigger)
Best Practices for Test classes:
Please adhere to salesforce best practices for test classes as mentioned below:
- The best test-taking strategy is: Test classes must begin with @is. If the class’s class version is more than 25, run an annotation test.
- The test environment includes support for @testVisible and @testSetUp.
- Unit testing determines whether a specific piece of code is functioning correctly.
- Unit test method takes no argument, commits no data to database, sends no email, and is marked with the keyword test Method.
- At least 75% code coverage is needed before deploying to production.
- System.debug statements are not included in the allotted amount of apex code.
- The code restriction does not include test methods or test classes.
- Rather than concentrating on the percentage of code coverage, we should make sure that all use cases—positive, negative, bulk, and single record—are covered.
- User Restricted: -Test whether a user with restricted access used in your code.
- Test class should be annotated with @isTest.
- The test Method keyword is equal to the @isTest annotation with test method.
- The test method must be static and not have a void return type.
- Test class and method default access is private; access specifiers are not required.
- Interfaces or enums cannot be classes with the @isTest annotation.
- Non-test requests cannot call the code of a test method.
- With the Salesforce API version 28.0, test methods cannot be contained within non-test classes.
- The @Testvisible annotation makes internal test class private methods visible.
- Web-service call out cannot be tested using test technique. Use call out mock, please.
- Testmethod is unable to send emails.
- We can access Apex Pages without (seeAllData=true) for User, Profile, Organization, AsyncApexjob, Corn trigger, Record Type, Apex Class, and Apex Component.
- The API 23 version earlier does not support SeeAllData=true.
- Use the function Object () {[native code] } CreateTestFactoryclasswith@isTestannotationtoexcludefromorganizationcodesizelimit.
- @testSetup to utilize every test method in the test class and create test records once in a method.
- We can run unit tests using the Force.com IDE, the Console, and the API for Salesforce.
- Your organization’s test classes cannot be multiplied by more than 500 or 10 times in a 24-hour period.
- Because Apex operates in system mode, record sharing and authorization are not taken into consideration. Therefore, in order to ensure record sharing, we must utilise system.runAs.
- User permissions or field level permissions are not enforced by System.runAs.
- Each test that is run counts against the total number of DMLs that were issued throughout the process.
Best Practices for Visual Force Pages:
The ideal method for visual force pages is:
1. Reduce the Number of Database Queries & Records being Used
If your page is working with data make sure that your SOQL is using Indexed Fields in the where clause to speed up SOQL queries, and using any additional filters to reduce the amount of data.
2. Take Advantage of Browser Caching
By storing as much of the JavaScript and CSS in static resources, we can take advantage of the browser’s caching mechanism and decrease the number of resources that need to be downloaded to make the page work correctly.
3. Avoid SOQL Queries in get methods
4. Reduce the Size of the View State
View State is basically a lot of extra data that will be transmitted with every request. A maximum of 135kb can be transmitted per request, which doesn’t sound like a lot but it can really add up.
5. Reduce the Use of Visualforce Components
Not only do visualforce components potentially increase the size of the view state, but they can also dramatically change how long it takes to render a page.
Read more : Apex Design Patterns
1 thought on “Salesforce Apex Best Practices”