Apex Coding Standards
Coding guidelines 1|P a ge
Contents
Introduction 3
Naming Convention 4
1. Classes 4
Generic Classes 4
Batch Apex Class 4
Controller Class 4
Trigger 4
Test Classes 4
Interfaces 4
2. Variables 5
3. Constants 5
4. Methods 5
Code Layout and Formatting 6
1. Wrapping Lines 6
2. Breaking an arithmetic expression 6
3. Indenting method declarations 7
Test Class Best Practices 23
References 25
Coding guidelines 2|P a ge
Introduction
Apex is a strongly typed, object-oriented, proprietary programming language for the
Force.com platform. It lets you execute flow and transaction control statements in conjunction
with calls to the Force.com API. Apex borrows it's syntax from Java and functions like a
database stored procedure.
Unfortunately, there is no official coding convention defined by Salesforce.com that the
developers can follow to create Force.com applications. This has led to developers using a
random coding style. If the developer has previously worked with another language, they
carry over the coding convention of that language to Apex. It's even more chaotic if they
haven't used a programming language before. They just create their coding style. This leads to
inconsistency and becomes frustrating when you are reading an open source code or a code
snippet in a blog post.
This document aims to list a set of coding standards that can be used as a reference
when developing applications on the Force.com platform.
Coding guidelines 3|P a ge
Naming Convention
1. Classes
Generic Classes
As per Object Oriented Programming language rules, class names should be nouns.
They should define or describe a thing or entity.
A class name should be camel-case. The first letter of each word in the class name
should be capitalized. The class name should be simple and descriptive. Acronyms and
abbreviations should be used sparingly.
Do not use underscore or other special characters in a class name except to specify the
type of class (e.g., Batch_XXXXX)
Never use the standard object names as class names:
e.g.: Account, Opportunity, etc
Example of class names:
e.g., IntegrationHelper, Router, etc.
There are a few recommended variations for different types of classes.
Batch Apex Class
The class name should be prefixed by 'Batch_'.
e.g. Batch_AccountRefund, Batch_ValidateOpportunity
Controller Class
The class name is typically suffixed by '_Controller'.
e.g. SolarEnergy_Controller, NewAccount_Controller
Trigger
The trigger class name should be suffixed by '_Trigger', and the handler Class should be
suffixed by '_TriggerHandler'
e.g. Account_Trigger, Account_TriggerHandler
Test Classes
A test class should be prefixed by 'Test_'.
e.g. Test_Account_Trigger, Test_IntegrationHandler
Interfaces
Interface names follow the same rules as Classes and should be prefixed with a capital ‘I’.
e.g. IToken, ICalendar.
Coding guidelines 4|P a ge
Since the interface is describes the ability to be used in a certain way, the interface
name should be an adjective and end with the suffix 'ible' or 'able' e.g. IBatchable
2. Variables
Variable names should be mixed case with a lowercase first letter and each
consecutive word should start with a capital letter. This rule applies to the instance and class
variables. They should not start with an underscore(_), or a dollar sign($), even though both
are allowed. In fact, you should avoid using underscores or special characters in a variable
name. Variable’s names should be short yet meaningful. It should indicate the intent of its use.
Avoid single letter variable names like (i, j, k), unless they are used as a throwaway
variable in a loop.
e.g. string firstName, integer totalRevenue
Collection variables for Map, set, list, etc should be prefixed with the respective
collection type with a meaningful name for the collection.
e.g. mapAccountIdsAndAccount, lstAccounts, setAccountId
Class variables should be prefixed with ‘obj’ and the class name.
e.g. objAccount, objIntegrationHandler.
3. Constants
Constant (i.e. variable defined as static final int) is a special type of variable and a
constant name should be all uppercase with words separated by underscores (_). Avoid any
special characters in a constant name.
e.g MIN_WIDTH, UK_CURRENCY
4. Methods
Method name should be a verb, an action. Like a variable name, it should be mixed
case with a lowercase first letter and the first letter of each internal word capitalized.
Coding guidelines 5|P a ge
Code Layout and Formatting
A well-formatted code increases the readability, understanding, and ultimately
maintainability of the code base. A developer should strive to use a consistent layout and
format. It will make the lives of other developers (who want to read, review, or maintain your
code) a lot easier. I have listed a few guidelines as to how a Force.com developer should
format code.
1. Wrapping Lines
When an expression does not fit on a single line, break it as per these general principles:
Break after a comma.
Break before an operator.
Prefer higher-level breaks to lower-level breaks.
Align the new line with the beginning of the expression at the same level as the
previous line.
If the above rules lead to confusing code or to code that's squished up against
the right margin, just indent 8 spaces instead.
e.g.:
someMethod(longExpression1, longExpression2, longExpression3,
longExpression4, longExpression5);
var = someMethod1(longExpression1,
someMethod2(longExpression2,
longExpression3));
2. Breaking an arithmetic expression
The first is preferred since the break occurs outside the parenthesized expression,
which is at a higher level.
longName1 = longName2 * (longName3 + longName4 - longName5)
+ 4 * longname6; // PREFER
longName1 = longName2 * (longName3 + longName4
- longName5) + 4 * longname6; // AVOID
Coding guidelines 6|P a ge
3. Indenting method declarations
Conventional case:
//CONVENTIONAL INDENTATION
someMethod(int anArg, Object anotherArg, String yetAnotherArg,
Object andStillAnother) {
...
}
Non-Conventional: it indents only 8 spaces.
//INDENT 8 SPACES TO AVOID VERY DEEP INDENTS
private static synchronized horkingLongMethodName(int anArg,
Object anotherArg, String yetAnotherArg,
Object andStillAnother) {
...
}
Line wrapping for if statements should generally use the 8-space rule, since
conventional (4 space)
indentation makes seeing the body difficult. For example:
//DON'T USE THIS INDENTATION
if ((condition1 && condition2)
|| (condition3 && condition4)
||!(condition5 && condition6)) { //BAD WRAPS
doSomethingAboutIt(); //MAKE THIS LINE EASY TO MISS
//USE THIS INDENTATION INSTEAD
if ((condition1 && condition2)
|| (condition3 && condition4)
||!(condition5 && condition6)) {
Coding guidelines 7|P a ge
doSomethingAboutIt();
//OR USE THIS
if ((condition1 && condition2) || (condition3 && condition4)
||!(condition5 && condition6)) {
doSomethingAboutIt();
Here are three acceptable ways to format ternary expressions:
alpha = (aLongBooleanExpression) ? beta : gamma;
alpha = (aLongBooleanExpression) ? beta
: gamma;
alpha = (aLongBooleanExpression)
? beta
: gamma;
Coding guidelines 8|P a ge
Placement
Put declarations only at the beginning of blocks. (A block is any code surrounded by
curly braces "{" and "}".)
Don't wait to declare variables until their first use; it can confuse the unwary
programmer and hamper code portability within the scope.
void myMethod() {
int int1 = 0 ; // beginning of method block
if (condition) {
int int2 = 0 ; // beginning of "if" block
...
The one exception to the rule is indexes of for loops, which in Java can be declared in the
for statement:
for (int i = 0; i < maxLoops; i++) { ... }
Avoid local declarations that hide declarations at higher levels. For example, do not declare
the same variable
name in an inner block:
int count;
...
myMethod() {
if (condition) {
int count = 0; // AVOID!
...
...
Coding guidelines 9|P a ge
}
Header Comments
All files should begin with a c-style comment that lists company, date, author,
description, and history:
/*
* Company
* Date
* Author
* Description
* History
*/
Class and Interface Declarations
When coding Apex classes and interfaces, the following formatting rules should be
followed:
* No space between a method name and the parenthesis "(" starting its parameter list
* Open brace "{" appears at the end of the same line as the declaration statement
* Closing brace "}" starts a line by itself indented to match its corresponding opening
statement,
except when it is a null statement the "}" should appear immediately after the "{"
class Sample extends Object {
int ivar1;
int ivar2;
Sample(int i, int j) {
Coding guidelines 10 | P a g e
ivar1 = i;
ivar2 = j;
int emptyMethod() {}
if, if-else, if else-if else Statements:
The if-else class of statements should have the following form:
if (condition) {
statements;
if (condition) {
statements;
} else {
statements;
if (condition) {
statements;
} else if (condition) {
statements;
} else {
statements;
Coding guidelines 11 | P a g e
}
Note: if statements should always use braces {}. Avoid the following error-prone form:
if (condition) //AVOID! THIS OMITS THE BRACES {}!
statements;
for Loop
A for loop should have the following format:
//traditional for loop
for (initStatement; exitCondition, incrementStatement) {
//code block
//set iteration for loop
for (variable : list_or_set) {
//code block
//SOQL for loop
for (variable : [soql query]) {
//code block
Make sure you break the query into multiple lines if it is a long query.
Coding guidelines 12 | P a g e
try-catch Statements:
A try-catch statement should have the following format:
try {
statements;
} catch (ExceptionClass e) {
statements;
A try-catch statement may also be followed by finally, which executes regardless of
whether or not the try block has been completed successfully.
try {
statements;
} catch (ExceptionClass e) {
statements;
} finally {
statements;
Coding guidelines 13 | P a g e
Blank Lines
Blank lines improve readability by setting off sections of code that are logically related.
Two blank lines should always be used in the following circumstances:
* Between sections of a source file
* Between class and interface definitions
One blank line should always be used in the following circumstances:
* Between methods
* Between the local variables in a method and its first statement
* Before a block or single-line comment
* Between logical sections inside a method to improve readability
Coding guidelines 14 | P a g e
Best Practices
These are the key coding principles and best practices that will ensure we write
efficient, scalable code.
Keep code stupid simple
There should be as little logic in your code as possible. Reusing code in several places,
should be replaced with a single method and reduce the clutter in the code base.
//BAD EXAMPLE
public boolean isTrue(boolean myBool){
if(myBool){
return true;
}else{
return false;
public Map<Id,Contact> getContactMap(){
Map<Id,Contact> contactMap = new Map<Id,Contact>();
List<Contact> contacts = [Select Id From Contact];
if(contacts != null && contacts.size() > 0 && !contacts.isEmpty()){
for(Integer i=0; i < contacts.size(); i++){
contactMap.put(contacts.get(i).Id,contacts.get(i));
return contactMap;
Coding guidelines 15 | P a g e
//GOOD Example
public boolean isTrue(boolean myBool){
return myBool;
public Map<Id,Contact> getContactMap(){
return new Map<Id,Contact>([Select Id From Contact]);
Do not put queries in loops
One of the most stringent governor limits is a SOQL query limit of 100 queries in a
transaction.
To avoid this simply do not put queries in for loops.
//BAD example
List<Account> accList = new List<Account>([Select Id,Name From Account]);
for(Account acc : accList){
Integer numWithEmail = 0;
for(Contact cont : [Select Id,Email From Contact Where AccountId = :acc.Id]){
if(!String.isEmpty(cont.Email)){
numWithEmail++;
Coding guidelines 16 | P a g e
//GOOD Example
List<Account> accList = new List<Account>(
[Select
Id
,Name
,(Select
Email
From
Contacts
From Account]
);
for(Account acc : accList){
Integer numWithEmail = 0;
for(Contact cont : acc.Contacts){
if(!String.isEmpty(cont.Email)){
numWithEmail++;
Coding guidelines 17 | P a g e
Use maps for queries
This is a fundamental technique and trick to use in order to make SOQL queries, DML
transactions, and Apex triggers more efficient. You can get a Map from a list, without a For
Loop.
For example:
Map<Id, sObject> myAwesomeMap = new Map<Id,sObject>(List of sObjects or SOQL
Query);
Use relationships to reduce queries
SOQL allows you to query for parent/children record information.
List<Account> accList = new List<Account>(
[Select
Id
,Name
,(Select
Email
From
Contacts
From Account]
);
Coding guidelines 18 | P a g e
List<Account> accountsToUpdate = new List<Account>();
for(Account acc : accList){
Integer numWithEmail = 0;
for(Contact cont : acc.Contacts){
if(!String.isEmpty(cont.Email)){
numWithEmail++;
acc.Contacts_With_Email_Address__c = numWithEmail;
accountsToUpdate.add(acc);
update accountsToUpdate;
Do not put DML in loops
DML means any insert, update, delete, undelete, merge, convert Lead transaction. To
avoid governor limits. Simply by not putting DML in for loops, and generally speaking, make
sure you're acting on multiple records.
Only use one trigger per object
Having multiple triggers across the same object greatly increases the complexity of
your Salesforce org. By consolidating any triggers, you are less prone to mistakes, and
business processes are easier to maintain.
Keep logic outside of triggers
Triggers should only contain a handful of lines of code, used for calling methods. The
trigger should be used. For managing execution order, and delegate all else to a separate Apex
class such as a trigger helper.
Coding guidelines 19 | P a g e
Have a happy balance between clicks and code
Knowing when to use declarative features rather than jumping straight into an Apex
or Visualforce solution. Will greatly help reduce the complexity of the code base, and improve
performance and maintenance.
Write test code
You should always aim for 100% code coverage. The goal is get as high a code
coverage as is sensible.
Avoid hard-coding IDs
It is paramount to avoid hard-coding IDs in the Apex code. By ensuring no IDs are
stored in the Apex code, you are making the code much more dynamic and flexible, allowing
for safe deployments between environments.
Consider the scenario: you need to always set the Account lookup on a specific record type of
Contact to be a specific account. You may consider hard coding this variable, but that would be
a bad idea!
Hardcoding IDs might work fine and without incident when they are developed, but as soon as
we migrate our code into production, those IDs will no longer reference the correct record.
This is especially true for Record Types created in a sandbox and then migrated into
production. Consider the opposite situation: if we create a sandbox from production, our
hard-coded IDs will no longer point to the correct records.
If we wish to utilize record types, instead we can reference them via their DeveloperName
which will be consistent across environments.
If the ID we wish to use relates to a specific record, we can instead store this ID into custom
metadata and retrieve the value at runtime, allowing us to freely change the value between
environments, or as requirements change.
There is only one scenario where we don’t need to follow one of the two above approaches,
and that is where we are explicitly referencing the Master Record Type. This is the special
default record type and is fixed across all instances. However, just because it is static now
doesn’t mean it always will be, and so we should probably also store it in custom metadata (if
required), just to be on the safe side.
Coding guidelines 20 | P a g e
Bulkify Your Code
Bulkification of your code is the process of making your code able to handle multiple records
at a time efficiently. This is mainly true for triggers, where up to 200 records could be run
through at once, e.g., from a data load. If your code hasn’t been written to take that into
account, it can lead to errors being thrown, or worse, unexpected behavior.
Take a look at the code below – it shows an example of code that hasn’t been written with
bulkification in mind. In trigger, only the first opportunity would be processed, and any others
saved in the same transaction. Depending on the business process, this could be a catastrophic
bug.
Below is the same code set up to handle the full batch of records in the trigger, meaning all
200 records would be correctly processed in a single trigger invocation.
We can also bulkify our code to help improve the performance of a piece of code, where we
can reduce the number of queries or other expensive operations. An example of this is using
Maps to access related data more efficiently about a record during processing.
Coding guidelines 21 | P a g e
Consider use of maps can greatly reduce the complexity and the amount of time it takes your
code to run by reducing the overall lines of code to be executed when compared to iterating
over lists.
The only time you may choose not to bulkify your code is when you can guarantee the number
of records in an invocation will be low – this may be from an API or an Apex action invoke via
a screen flow. However, due to the ease of bulkifying most code, you should probably get into
a good habit of doing it regardless!
Using the with sharing, without sharing and inherited sharing keywords
Use the with sharing or without sharing keywords on a class to specify whether sharing
rules must be enforced. Use the inherited sharing keyword on a class to run the class in the
sharing mode of the class that called it.
Coding guidelines 22 | P a g e
Test Class Best Practices
1. What to test in Apex ?
Unit tests are tests performed by the developers to ensure that the functionality is working as
expected by considering both positive & negative tests. Salesforce recommends the following
components need to be tested.
Single Records: This includes testing to verify that a single record produces
correct, expected result
Bulk Records: Any apex code, whether a trigger, a class or an extension may be
used for 1 to 200 records. We must test bulk records as well.
Positive scenarios: This type of component testing expects a system to save a
record without error.
Negative scenarios: This type of component testing expects a system to give
error.
Restricted User: Test whether a user with restricted access to the objects used
in code sees the expected behavior, i.e whether they can run the code or receive
error messages.
2. Best Practices to follow
To write an effective test cases, a developer needs to ensure to include the below points into
the test class
Test class must start with @isTest annotation.
Focus 90+ : To deploy to production at least 75% code coverage is
required. But always try to focus on 90%+. We should not focus on the
percentage of code coverage, We should make sure that every use case should
covered including positive, negative,bulk and single record.
One Assert Statement per method : Always put assert statements for
negative and positive tests.
System.assert(condition, msg)
System.assertEquals(expected, actual, msg)
System.assertNotEquals(expected, actual, msg)
@testSetup to create test records once in a method and use in every test
method in the test class.
Create TestFactory class with @isTest annotation to exclude from organization
code size limit.
No SeeAllData = true : Always use ( seeAllData = false ) at class or method
level. User, profile, organization, AsyncApexjob, Corntrigger, RecordType,
ApexClass, ApexComponent, ApexPage we can access without (seeAllData =
true).
As apex runs in system mode so the permission and record sharing are not
taken into account . So we need to use System.runAs to enforce record sharing.
Avoid Using Hard Coding Ids anywhere in test Class or any apex class
Coding guidelines 23 | P a g e
Governor limits : Using Test.startTest()gives developers a new set of governor
limits for the act stage of their test. Test.stopTest() then allows them to return
to their previous governor limits. Test classes must test for Governor Limits
using Limits Class
Testing Exception : Any exceptions that are caught in the production methods
should be tested by feeding the test data that throws exception. Exception Type
and error message should be asserted
Exercise bulk trigger functionality – use at least 200 records in your tests
Coding guidelines 24 | P a g e
References
http://www.salesforce.com/us/developer/docs/apexcode/index.html
Coding guidelines 25 | P a g e