Axis
Technical Skills
Subject
Salesforce Coding Standards
Type
Best Practices
Goal
Adopt Best Practices while coding
Language
English
Copyright © 2020 EI-Technologies-Lebanon SAL.
VERSIONS
Version Date de Validation Description du Changement Auteur
3.0 2020-09-24 Design Refactoring Rana Rizk
3.1 2020-12-02 Additions Elie Nassif
3.2 2021-01-02 Trigger handler Framework Joseph Msallem
Copyright © 2020 EI-Technologies-Lebanon SAL.
SUMMARY
Apex Coding Best Practices 5-11
Apex Coding Best Practices – Test Classes 12 - 15
Comments 16 - 17
Visualforce Pages coding Best Practices 18
Lightning Components coding Best Practices 19 - 20
Naming rules 22-24
Naming rules Custom Labels 25
Naming rules Objects and Fields 26
SALESFORCE CODING STANDARDS 28 - 34
SALESFORCE CODING ARCHITECTURE Triggers 35 - 41
SALESFORCE CODING ARCHITECTURE Apex Utils Class 42
SALESFORCE CODING ARCHITECTURE Lightning components 43 - 44
Copyright © 2020 EI-Technologies-Lebanon SAL.
01 Best Practices
02 Naming Rules
03 Salesforce Coding Standards
Copyright © 2020 EI-Technologies-Lebanon SAL.
BEST PRACTISES
Apex Coding Best Practices 1/5
• Bulkifying Apex code refers to the concept of making sure the code
properly handles more than one record at a time. When a batch of
records initiates Apex, a single instance of that Apex code is
Bulkify your code executed, but it needs to handle all of the records in that given
batch.
• Example on how to bulkify your code
• There is a governor limit that enforces a maximum number of
SOQL queries. There is another that enforces a maximum number
Avoid SOQL Queries or of DML statements (insert, update, delete, undelete). When these
DML statements inside operations are placed inside a for loop, database operations are
invoked once per iteration of the loop making it very easy to reach
FOR Loops these governor limits
• Example on how to avoid SOQL or DML inside FOR Loops
Using Collections, • It is important to use Apex Collections to efficiently query data and
store the data in memory. A combination of using collections and
Streamlining Queries, streamlining SOQL queries can substantially help writing efficient
and Efficient For Loops Apex code and avoid governor limits.
Copyright © 2020 EI-Technologies-Lebanon SAL.
BEST PRACTISES
Apex Coding Best Practices 2/5
• If returning a large set of queries causes you to exceed your heap
Use SOQL query for limit, then a SOQL query for loop must be used instead. It can
Loops process multiple batches of records
• SOQL FOR Loops Example
Use @future Methods for • Only use Synchronous Apex callouts or webservices callouts when
necessary. The differences between synchronous and
Asynchronous asynchronous Apex can be found Governors in Apex
transactions • Code#Synchronous_vs_Asynchronous_Apex
• It is key to have test methods that verify that all Apex code is
Writing Test Methods to properly designed to handle larger datasets and that it does not
Verify Large Datasets exceed governor limits
• Testing Examples
Copyright © 2020 EI-Technologies-Lebanon SAL.
BEST PRACTISES
Apex Coding Best Practices 3/5
• Methods in Apex should not exceed 100 lines. For large logic
Limit the size of your methods use multiple methods (or helper methods). Apex classes
classes and methods should not exceed 1000 lines. For large logic classes, use multiple
classes (or helper classes)
• It is essential to avoid hardcoding IDs in the Apex code. By doing
so, if the record IDs change between environments, the logic can
Do not hardcode IDs dynamically identify the proper data to operate against and not
fail. Use custom labels instead
• Example of how to avoid hardcoding IDs
Use comments in your • Your code should be well commented for others to easily
code understand the logic you worked on
Copyright © 2020 EI-Technologies-Lebanon SAL.
BEST PRACTISES
Apex Coding Best Practices 4/5
• The safe Navigation Operator allows you to have fewer lines of
Safe Navigation code, and avoid the NullPointerException Error. This exists also in
Operator Javascript
Copyright © 2020 EI-Technologies-Lebanon SAL.
Example: String accountName = null;
if(account != null) {
Before (if): }
accountName = account.Name;
Before (ternary): String accountName = null;
if(account != null) {
accountName = account.Name;
}
After: String accountName = account?.Name;
It also allows for safe method access:
Before (if): Integer count = 0;
if(account != null) {
count = account.getCount();
}
After: Integer count = anObj?.getCount();
Copyright © 2020 EI-Technologies-Lebanon SAL.
BEST PRACTISES
Apex Coding Best Practices 5/5
• It is possible to customize (add value from a variable for example)
to a custom label.
• Sometimes we used multiple Custom Labels to form a message:
Customizing a Custom “Impossible to add the account” + accountName + “ to the
Label in Apex contact”
• The String class in Apex proposes a method to use a single Custom
Label to generate such text.
Copyright © 2020 EI-Technologies-Lebanon SAL.
Creation of Custom Label:
“Impossible to add the account {0} to the contract.” We
can add multiple variables, by using {1}, {2} and so on.
Customization: List<Object> parameterList = new List<Object> { account.Name };
String completeMessage = String.format(System.Label.MyLabelName, parametersList);
Example:
Copyright © 2020 EI-Technologies-Lebanon SAL.
BEST PRACTISES
Apex Coding Best Practices – Test Classes
• Every Apex class must have an Associated Test Class.
• Avoid testing a class “AccountHelper” in “User_TEST”.
• Every PUBLIC method must be tested.
• Test = Verify that the code is functional.
• At least one System.assert(Equals) per method.
Rules to follow • Theoretically, we assert functionalities in the method.
• We execute the test as the end user (System.runAs)
• We test exceptions as soon as possible (give an Id before
Insertions, or a Name that is too long, which will generate a
DMLException).
• Coverage target is 90%.
Copyright © 2020 EI-Technologies-Lebanon SAL.
BEST PRACTISES
Apex Coding Best Practices – Test Classes
• Every test class must have @testSetup.
• Use this to initialize your data once in the DB, all records
necessary for the test execution.
• As soon as a record (Contract, User, Account) is needed, we
place it in the @testSetup.
• Do not insert into the DB a record that you will modify
afterwards. Use a method allowing the creation of the record
Performance without inserting it, modify it, then save it to the DB.
• The TestDataFactory must respect these practices:
• This class is modifiable by everyone.
• It has to be validated by your tech lead before deploying it into
production.
• Bulkify (again) to the maximum (insert lists rather than single
records).
Copyright © 2020 EI-Technologies-Lebanon SAL.
BEST PRACTISES
Apex Coding Best Practices – Test Classes
• The tests must be executed on every deployment stage:
• Dev sandbox
• Test sandbox
• Preprod
• Prod
• A failing test in one of these orgs prevents the deployment
Verification on the following org.
• An apex class that does not have enough coverage prevents
the deployment on the following org.
• On each execution, we verify that the execution time is not slow
(maximum 5 seconds per method)
• Use Test suites for large projects.
Copyright © 2020 EI-Technologies-Lebanon SAL.
BEST PRACTISES
Apex Coding Best Practices – Test Classes
• Test Classes: we add _TEST to the end of the class we are
testing (AccountHelper_TEST)
• If the name is too long, we truncate the class name, not the
_TEST.
Naming rules • Test methods: name of the method we are testing, followed by
Test (getAccountTest)
• Class Names: in UpperCamlCase
• Method names: in camelCase
Copyright © 2020 EI-Technologies-Lebanon SAL.
BEST PRACTISES
Comments Examples 1/2
Documentation: Below is an example of what a method comment should look like.
It specifically describes its use and inputs and outputs where appropriate:
/**
* @company name
* @author
* @date
* @description
* @param List
* @return List
* @history
*/
Documentation: for standard class definitions the following is an example header that might be used:
/**
* @company name
* @author
* @date
* @description
*/
Copyright © 2020 EI-Technologies-Lebanon SAL.
BEST PRACTISES
Comments Examples 2/2
Documentation: for custom controllers and extensions the following header should be used:
/**
* @author Author Name
* @date 3/14/2016
* @description A list of Visualforce pages that use the controller/extension
*/
Copyright © 2020 EI-Technologies-Lebanon SAL.
BEST PRACTISES
Visualforce Pages coding Best Practices
1. Use <apex:actionStatus> to inform the user that the page is loading
2. Use indentation to format your code and Visualforce tags in order to facilitate the code readability
3. Avoid using static values in Visualforce pages code. Use custom labels instead
4. Avoid putting JS or CSS code in the Visualforce code. Upload the .js or .css files as Static Resources
instead
5. Avoid using an HTML ID in your Visualforce code. Use the variable $Component to access server
generated IDs
6. Use Visualforce components for complicated Visualforce Pages. Avoid having too many lines in one
Visualforce page
7. Use URLFOR function to reference action, s-control, Visualforce page, or a file in a static resource
archive in a Visualforce page
Copyright © 2020 EI-Technologies-Lebanon SAL.
BEST PRACTISES
Lightning Components coding Best Practices 1/2
1. Think about Reusability. Your Lightning component should be, whenever it’s possible, reusable
on other projects by other developers. Avoid referencing project related fields or variable in
your Lightning Component. Make sure your input parameters are dynamic ‘attributes’ and not
‘static’ values.
2. Before making a call to the server, make sure there’s no other option to obtain the data
3. Use attributes, events, or methods to pass data between rather than retrieving the same data in
different components
4. When making a call to the server, limit the columns and rows of the result set:
• Only SELECT the columns you need.
• Set a LIMIT on the query and provide a paging mechanism if needed. Don’t return huge
numbers of rows at once.
Copyright © 2020 EI-Technologies-Lebanon SAL.
BEST PRACTISES
Lightning Components coding Best Practices 2/2
5. Whenever possible, use the Base Lightning Components (components in
the lightning namespace) instead of <ui> components. Base Lightning Components.
6. To enable/disable debug mode: Setup > Custom Code > Lightning Components
7. To enable/disable component caching: Setup > Security > Session Settings > Caching, and
uncheck Enable secure and persistent browser caching to improve performance
8. Upload your .js or .css libraries as Static Resources and reference them in your Lightning
Components. Static resources in Lightning Components.
9. Use multiple inner Lightning Components for complex Lightning Components. Always make
sure that your component is readable and understandable.
Copyright © 2020 EI-Technologies-Lebanon SAL.
01 Best Practices
02 Naming Rules
03 Salesforce Coding Standards
Copyright © 2020 EI-Technologies-Lebanon SAL.
NAMING RULES
Part 1/3
Object Type Naming Convention Example
Record Type
Record Type <LABEL> 6 - Proposition & Win
Record Name <OBJECT>_<Shorten LABEL> OPP_6_PropositionWin
Record Type Description <DESCRIPTION> Stage 6 of sales cycle - proposition is sent
and oppty is won
Custom Object
Custom Object Label <LABEL> Account Planning
Custom Object Name <Shorten LABEL functional Area APL_AccPlan
(3 characters)>_<Shorten LABEL>
Custom Object Description <DESCRIPTION> Account Plans management for Key
Account
Validation Rule
Rule Name <OBJECT>_VR<xy>_<FIELD Validation ACC_VR01_CityShouldBeFilledIfStreetIs
Rule
LABEL without blank or underscore>
Validation Rule Description <DESCRIPTION> City is required if Street is filled.
Error Message <MESSAGE LABEL> Please fill City as this field is required if
Street is filled.
Custom Buttons and Links
Custom Buttons/Links Label <LABEL> Opportunities linked to this account
Custom Buttons/Links Name <OBJECT>_<Shorten LABEL> ACC_AccountOppties
Copyright © 2020 EI-Technologies-Lebanon SAL.
NAMING RULES
Part 2/3
Object Type Naming Convention Example
Workflows & Processes
Workflow Rule Name <OBJECT> _WF<xy>_<LABEL> ACC_WF01_UpdateStandardCity
Workflow Rule Name with at least one <OBJECT> _WF<xy>_E_<LABEL> ACC_WF01_E_InformOwner
email alert
Workflow Rule Description <DESCRIPTION> When custom city field changed, update
Account Standard City Field.
Approval Process Name <OBJECT> _AP<xy>_<LABEL> OPP_AP01_DeletionProcess
Approval Process Unique Name <OBJECT> _AP<xy>_<LABEL> OPP_AP01_DeletionProcess
Approval Process Description <DESCRIPTION> Validate Opportunity Deletion with a double
approval
Workflow Task Subject <LABEL> Call Customer
Workflow Task Unique Name <OBJECT>_<LABEL> ACC_CallCustomer
Workflow Email Alert Description <OBJECT>_<LABEL> ACC_OwnerNotification
Workflow Email Alert Unique Name <OBJECT>_<LABEL> ACC_OwnerNotification
Field Update Name <OBJECT>_<LABEL> ACC_UpdateCity
Field Update Unique Name <OBJECT>_<LABEL> ACC_UpdateCity
Field Update Unique Description <DESCRIPTION> Update Billing City with custom City (due to
account hierarchy requirement).
Outbound Message Name <OBJECT>_<LABEL> OPP_ExternalSystemNotif
Copyright © 2020 EI-Technologies-Lebanon SAL.
NAMING RULES
Part 3/3
Object Type Naming Convention Example
Trigger
Name <Object Name><Event> OpportunityBeforeInsert
Class
Trigger Class AP<xy><Object> AP03_Opportunity
Visualforce Controller class VFC<xy>_<PageName> VFC01_OpportunityMassEdit
Webservice Class WS<xy>_<ServiceName> WS04_AccountOwnerField
Test Class <ClassName>_TEST AP03_Opportunity_TEST
Batch Class BATCH<xy>_<BatchName> BATCH01_ShareAccounts
Scheduler Class SCHD<xy>_<SchedulerName> SCHD01_ScheduleShareAccounts
Lightning Component Controller <LightningComponentName>_Controller LC01_SearchAccounts_Controller
VF Page
Wizard VF Page VFP<xy>_<ProcessName><StepNumber> VFP02_ProductLineCreate01
Other VF Page VFP<xy>_<PageName> VFP01_OpportunityMassEdit
Email Template VF Page EmailTemplate<xy>_<Name> EmailTemplate03_WarningEmail
Visualforce Component
Label C<xy>_<ComponentName> C02_OpportunityMassEdit
Name C<xy>_<ComponentName> C02_OpportunityMassEdit
Description <DESCRIPTION> Opportunity Mass Edit Component
Lightning Component
Lightning Component Bundle LC<xy>_<LightningComponentName> LC01_SearchAccounts
Copyright © 2020 EI-Technologies-Lebanon SAL.
NAMING RULES
Custom Labels
Principal:
•Do not use them to hold text that will break if translated to other languages.
Naming convention:
It is best to name custom labels in UPPER_SNAKE_CASE (full capital letters, with “_” between words).
Some rules are to be respected:
ML_XXX (for labels used in email templates)
•UI_XXX (for labels used in the ui, displayed to the user)
•SL_XXX (for labels used by the system) -- do not translate these
Copyright © 2020 EI-Technologies-Lebanon SAL.
NAMING RULES
Recap & notes
On every creation (object, field, record type, process builder, flow, or any declarative option,
except custom labels) we use an Upper Camel Case format for the API name:
• Remove the _ between words.
• Use only English in the naming (labels) Unless otherwise precised by the client
• In case you did use french labels, do not forget to replace the underscores by corresponding
letters. (Passé => Pass___c => Passe__c)
Copyright © 2020 EI-Technologies-Lebanon SAL.
01 Best Practices
02 Naming Rules
03 Salesforce Coding Standards
Copyright © 2020 EI-Technologies-Lebanon SAL.
SALESFORCE CODING STANDARDS
Part 1/7
<access> class <name> { • The class name must follow the
//static block PascalCase naming convention in
{ which the first letter of each word in
//static variable
a compound word is capitalized
//static method
} Ex: MyClass
//Non-static variables • The use of underscore is not allowed.
//Constructors • It is not recommended to use
abbreviations.
//Getter & Setter Methods
//Action methods
//Logical methods
//Inner classes & functions
}
Copyright © 2020 EI-Technologies-Lebanon SAL.
SALESFORCE CODING STANDARDS
Part 2/7
<access> <return> <name>() { • The method name must follow the camelCase
code_block naming convention in which the first letter is lower
}
case and the first letter of each word in a compound
<access> <return> <name>(param1, param2) { word is capitalized
code_block Ex: startsWithLowerCase
}
• The use of underscore is not allowed.
public String Property { get ; set }
• It is not recommended to use abbreviations.
public String property; • NOTE (check the old)
public String getProperty() {
return this.property;
}
public void setProperty(String value) {
this.property = value;
}
Copyright © 2020 EI-Technologies-Lebanon SAL.
SALESFORCE CODING STANDARDS
Part 3/7
for (init_stmt; exit_condition; increment_stmt) {
Traditional syntax
code_block
}
for (variable : list_or_set) {
code_block list or set iteration
}
for (variable : [soql_query]) {
code_block SOQL for loop
}
for (variable_list : [soql_query]) {
code_block SOQL for loop
}
Copyright © 2020 EI-Technologies-Lebanon SAL.
SALESFORCE CODING STANDARDS
Part 4/7
while (condition) {
code_block Do not remove the curly braces
}
if (condition) {
code_block
}
if (condition) {
code_block
} else {
code_block
}
if (condition) {
code_block
} else if (condition) {
code_block
} else {
code_block
}
Copyright © 2020 EI-Technologies-Lebanon SAL.
SALESFORCE CODING STANDARDS
Part 5/7
longName1 = longName2 * (longName3 + longName4
- longName5) + 4 * longName6; ☹
longName1 = longName2 * (longName3 + longName4 - longName5)
+ 4 * longName6; ☺
If ((condition1 && condition2) ||
(condition3 && condition4))
|| (condition5 && condition6)) { doSomething(); } ☹
If ((condition1 && condition2)
|| (condition3 && condition4))
|| (condition5 && condition6)) { ☺
doSomething();
}
someMethodCall(longName1, longName2, longName3,
longName4, longName5);
☺
Copyright © 2020 EI-Technologies-Lebanon SAL.
SALESFORCE CODING STANDARDS
Part 6/7
• Indent appropriately. An indentation of 4 spaces per tab should be
Indentation used in VSCode, for all file types (Apex, JS, HTML)
• In queries between fields SELECT Name, Id
• Before and after operators: obj.Name = ‘Some Name’;
Respect the spaces • Between method parameters: void submit (String name, Integer
value)
• In the IF ELSE and FOR around the operators: if(name == ‘foo’)
• Between the keywords SELECT / FROM / WHERE / AND / OR / …
Line breaks in queries • If the SELECT contains many fields, prevent horizontal scrolls by
limiting the number of fields to 4 per line.
Copyright © 2020 EI-Technologies-Lebanon SAL.
SALESFORCE CODING STANDARDS
Part 7/7
• Capitalize every keyword in queries:
Keywords in queries SELECT FROM WHERE AND OR IN NOT LIMIT OFFSET LIKE
• Do not leave any System.Debug() or console.log() before
Cleanup the code deploying to production.
Update API Versions • When modifying a class, do not hesitate to update the API Versions
Copyright © 2020 EI-Technologies-Lebanon SAL.
SALESFORCE CODING ARCHITECTURE
Triggers
• We are using salesforce trigger handler framework
• The trigger must contain only line to run the dispatcher
• We need to create for each Sobject one trigger handler named
Triggers <SObjectName>TriggerHandler
• We also include PAD ByPass while verifying the DML. We can also
bypass by method.
Copyright © 2020 EI-Technologies-Lebanon SAL.
SALESFORCE CODING ARCHITECTURE
Triggers
01 Each trigger must be implemented in a custom setting that allows the trigger to be
active/inactive from UI
Copyright © 2020 EI-Technologies-Lebanon SAL.
SALESFORCE CODING ARCHITECTURE
Triggers
02 Create a record for each trigger
Copyright © 2020 EI-Technologies-Lebanon SAL.
SALESFORCE CODING ARCHITECTURE
Triggers
03 Create a Trigger Handler Interface
02 Lorem
Public Ipsum ITriggerHandler{
interface
void beforeInsert();
void afterInsert();
void beforeUpdate();
03
void afterUpdate();
void beforeDelete();
Lorem
void Ipsum
afterDelete();
void afterUnDelete();
Boolean isDisabled();
}
04 Lorem Ipsum
Copyright © 2020 EI-Technologies-Lebanon SAL.
SALESFORCE CODING ARCHITECTURE
Triggers
04 Create the dispatcher
02 Lorem Ipsum
03 Lorem Ipsum
This is a part of the dispatcher code
You can check the complete code from the link below:
https://github.com/kevinohara80/sfdc-trigger-framework
04 Lorem Ipsum
Copyright © 2020 EI-Technologies-Lebanon SAL.
SALESFORCE CODING ARCHITECTURE
Triggers
05 Create the SObject Trigger Handler extending the Trigger Handler and implementing the Trigger
Handler Interface
public class SObjectNameTriggerHandler extends TriggerHandler implements ITriggerHandler{
private Map<Id, SObject> newMap;
private Map<Id, SObject> oldMap;
private List<SObject> triggerNew;
private List<SObject> triggerOld;
public SObjectNameTriggerHandler(){
Lorem Ipsum
this.newMap
this.oldMap
= (Map<Id, SObject>) Trigger.newMap;
= (Map<Id, SObject>) Trigger.oldMap;
this.triggerNew= (List<SObject>) Trigger.New;
this.triggerOld= (List<SObject>) Trigger.Old;
}
public static Boolean TriggerDisabled = false;
public Boolean isDisabled(){
return TriggerDisabled;
}
Lorempublic
Ipsumoverride void beforeInsert() {}
public override void afterInsert() {}
public override void beforeUpdate() {}
public override void afterUpdate() {}
public override void beforeDelete() {}
Lorempublic
Ipsumoverride void afterDelete() {}
public override void afterUnDelete() {}
Copyright © 2020 EI-Technologies-Lebanon SAL.
SALESFORCE CODING ARCHITECTURE
Triggers
06 Create the Sobject’s trigger
/*
@Author : TMA JMS
@CreatedDate : 11-02-2021
@Description : SObjectName Trigger.
*/
trigger SObjectNameTrigger on SObject(before insert, after insert, before update, after update, before delete, after
delete, after unDelete) {
new SObjectNameTriggerHandler().run();
}
07
Copyright © 2020 EI-Technologies-Lebanon SAL.
SALESFORCE CODING ARCHITECTURE
Apex Utils Class
• These classes must group generic methods that can be used for
diverse functionalities, for example: a method that verifies if a
Nature given date is before or after the current date, string manipulations,
getting the type of connected user, etc…
• We can have multiple utils classes depending on the nature of
treatments: DateUtils, StringUtils, CommunityUtils, UserUtils, …
How? the class names must always have an explicit name at the start, to
easily identify them, and end with Utils
Copyright © 2020 EI-Technologies-Lebanon SAL.
SALESFORCE CODING ARCHITECTURE
Lightning components
• The component architecture for Aura and LWC is similar, in terms
of performance gain, it is best to have a single component per page
Performance ( the Content component). This component will perform most of
the JS and Apex calls, to limit the number of transactions slowing
down the performance.
• In the component Content, we should group the Javascript code
and Apex calls susceptible to re-suability and redundancy in
underlying components, to pass the results as parameters for
these components.
How? • Do not overcharge the code of the parent component with code
that is very specific to a child component.
• Once code is found in two child components, it should be moved to
the parent component if they are considered siblings, or added to a
shared JS file.
Copyright © 2020 EI-Technologies-Lebanon SAL.
SALESFORCE CODING ARCHITECTURE
Lightning components example
LWC naming: the first word starts with
lowercase, the following words start with
uppercase (contractHeader).
Aura naming: every word starts with a
capital letter, this helps us quickly identify
LWC and Aura components
For generic components, they should start
with generic followed by the description
of functionality (genericTable,
genericAutoCompleteInput)
For components specific to an object or
record type, the rule is to start with the
object name, followed by record type if
needed, and finally the functionality
(accountSubscriberHeader)
Copyright © 2020 EI-Technologies-Lebanon SAL.