You are on page 1of 44

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.

You might also like