73

I've looked in the Apex developer's guide and a saw the Naming Conventions section which has basically only has this:

We recommend following Java standards for naming, that is, classes start with a capital letter, methods start with a lowercase verb, and variable names should be meaningful.

I'm looking for something more in depth, such as end all Controllers with Controller and their tests with ControllerTest, etc.

What is a good set of naming conventions to use when developing on the Force.com platofrm? It would be preferable if the answer has something that handles custom objects, classes, visualforce pages, and components and not just Apex classes.

3
  • 4
    I know it wasn't asked explicitly, but I would love to know people's thoughts on naming conventions for: 1) custom fields on Sobjects (spaces as underscores, or no spaces. Ex. Owner_Name__c vs OwnerName__c). 2) properties inside a class (begin with upper or lowercase letter)
    – anschoewe
    Commented Aug 29, 2012 at 10:35
  • @anschoewe - That's a good one. For instance, if you are adding a set of custom fields to a standard object as part of your application/package, do you prefix them with your package prefix? Commented Aug 29, 2012 at 11:01
  • Was looking for some practices around this. I do prefer CamelCase - no spaces or underscores for Field Api names. Another comment would be wrt Positive and Negative naming for fields eg. for checkbox field the name Active__c will be preferred in my opinion vs. InActive__c - not always make sense but Be positive rather then negative where possible is my rule. :)
    – sfdx bomb
    Commented Apr 14, 2019 at 11:28

6 Answers 6

67

Follow the CamelCase Java conventions, except for VF pages and components start with a lower case letter.

Triggers:

  • <ObjectName>Trigger - The trigger itself. One per object.
  • <ObjectName>TriggerHandler - Class that handles all functionality of the trigger
  • <ObjectName>TriggerTest

Controllers:

  • <ClassName>Controller
  • <ClassName>ControllerExt
  • <ClassName>ControllerTest
  • <ClassName>ControllerExtTest

Classes:

  • <ClassName>
  • <ClassName>Test (These might be Util classes or Service classes or something else).

Visualforce pages and components:

  • <ControllerClassName>[optionalDescription] (without the suffix Controller). There might be multiple views so could also have an extra description suffix.

Object Names and custom Fields

  • Upper_Case_With_Underscores

Variables/properties/methods in Apex

  • camelCaseLikeJava - more easily differentiated from fields

Test methods in test classes

  • test<methodOrFunctionalityUnderTest><ShortTestCaseDesc> - For example, testSaveOpportunityRequiredFieldsMissing, testSaveOpportunityRequiredFieldsPresent, etc.

Working on something that would be used as an app or in some cases just a project? If yes, then do the following:

Prefix all custom objects, apex classes, Visualforce pages and components with an abbreviation so that they are easier to identify (e.g., easier for changesets). For example the WidgetFactory app would have the prefix wf on those. Additionally, when adding custom fields to a standard object they would also be prefixed to identify them as part of the app/package.

The main reason for the Object and Fields Names using Upper_Case_With_Underscores is that when you type in the name field or object with spaces it automatically adds the underscores. Although Apex is case insensitive, always refer to the Objects and Custom Fields in the code as Upper_Case_With_Underscores as well for consistency all around and consistency with what is generated by the SOQL schema browser and other tools. Object and Field Labels (which are generally ignored by code but visible to users) should keep spaces, not underscores.

6
  • 3
    This is great, thanks. For large companies I also advocate "namespacing" app/project/business unit specific code with a prefix e.g. an app called Killer Marketing App might prefix all code specific to that app with "kma_".
    – Wes Nolte
    Commented Apr 8, 2013 at 15:33
  • Surely your trigger names need an event in the name, like: LeadInsertTrigger, LeadUpdateTrigger or do you recommend to put more than one trigger in a file?
    – JannieT
    Commented Nov 26, 2013 at 13:11
  • 2
    @JannieT - In this setup, there would only be a single trigger called LeadTrigger and it would delegate to a handler class. Commented Nov 26, 2013 at 13:19
  • 4
    I find the "Upper_Case_With_Underscores" a bit odd for custom object / field names. It seems like this convention is widely adopted based on the auto-completion/suggestion code alone. Were as for standard objects, SF uses "UpperCaseWithoutUnderscores". I tend to follow the later, but it requires the user to change the default suggestion.
    – dana
    Commented Aug 28, 2014 at 17:06
  • 1
    This is a great summary, and matches what I've felt to be best-practices as well, with the exception of the "Upper_Case_With_Underscores" for Object Names and Custom Fields. As mentioned by @dana, I do aesthetically like matching Salesforce's own standard (no underscores) and personally feel like it looks cleaner. Beyond aesthetics, I find it a little more cumbersome to type with underscores followed by a capital letter, as I'm hard wired to only hold shift for a split second for one character at a time, so I just find it clunky. Realistically, this is just picking nits. Commented Apr 18, 2016 at 15:54
11

I generally subscribe to the following rules:

Apex Classes

  • For a generic class, I just prefix with a capital C, e.g. CSomeClass
  • For those which are test classes I use CTest as the prefix
  • For a Visualforce controller I use the prefix CVFC which means they're all grouped together

Visualforce Pages

  • I tend to use VFP as a prefix, maybe redundant but it helps keep them together when there are pages from other sources involved

Triggers

  • Here, I use the object type followed by an underscore and the trigger type, e.g. Contact_AfterUpdate, Lead_BeforeInsertUpdateDelete

If I'm working with code that all logically sits together in psuedo-package (or a real package) then I tend to also prefix everything with a suitable abbreviation.

1
  • 4
    Yeah, because of the lack of normal foldering/packaging I've also seen a lot of implementations include something like "ProjectName_*".
    – joshbirk
    Commented Aug 27, 2012 at 19:08
8

Update on 2016-02-17

I've evolved the below in a few cases:

  1. For collections, I always make the Collection variable plural, and I don't append the Collection Type as a suffix. Examples:

    • Set<String> cities instead of Set<String> citySet
    • List<Employee__c> employees instead of List<Employee> employeeList
    • (Infrequently Used) Map<Id, Contact> contacts instead of Map<Id, Contact> contactMap
  2. I use the Array notation for all Lists unless contructing a new List from an existing List or Set. This makes it easier to use the Auto-Complete in MavensMate which uses Sublime Text. (Plus it's less characters to type.) Examples:

    • Account[] accounts instead of List<Account> accounts
    • Contact[] contacts = new Contact[]{} instead of List<Contact> contacts = new List<Contact>();
    • Integer[] sizes = new Integer[]{2, 3, 4, 5}; instead of List<Integer> sizes = new List<Integer>{2, 3, 4, 5};
    • But you have to use the prior convention if you want to initialize a List with an existing List or Set. Set<String> lastNames; String[] lastNameList = new List<String>(lastNames);
  3. Abandoned the whole Return Variable mumbo jumbo. I always try to be as explicit as possible when using variable names. Example:

    • If you have a getter String getName(), somewhere in the Method, you should set a String called name and return it at the end. Don't call the variable n or something other than what the getter is explicitly called.
    • public Data getExtraData(){ ... Data extraData = new Data(); ... return extraData; }

Original

To add to the mix:

Variable Names

For variables names, I like to have them be as explicit as possible usually adding the variable Type as a suffix unless the term is "understood". I especially favor long, descriptive names over short, sometimes-ambiguous names.

For instance variables & all methods, I start the name with a lower-case letter. For static variables I like to start the name with a Capital letter.

Additionally, whenever referencing static variables or methods, I ALWAYS add the class prefix. Furthermore, whenever referencing instance variables or methods, I try to use the this prefix. Therefore it is much clearer where variables/methods come from/reside -- which is especially useful when copying code to and from other classes or re-writing code.

Examples:

  • Set<Id> contactIdSet
  • List<String> nameList
  • List<String> otherNameList
  • Decimal paymentAmount
  • Account parentAccount

When creating a Map, I like to add a comment that states the key/values for reference.

Map<String, Account> accountMap = new Map<String, Account>(); // accountMap: clientCode ---> Account
for(Account clientAccount :
    [SELECT Id, Client_Code__c
     FROM Account
     WHERE RecordType.Name = 'Client']
){
    accountMap.put(clientAccount.Client_Code__c, clientAccount);
}

For for loops, I favor using temp as a prefix for already used variable names:

List<Tax_Payment__c> taxPaymentList = [SELECT Id, Amount__c, Payment_Date__c
                                       FROM Tax_Payment__c
                                       WHERE Payment_Date__c = THIS_FISCAL_QUARTER];
Map<Date, List<Tax_Payment__c>> taxPaymentMap = new Map<Date, List<Tax_Payment__c>>();
    // taxPaymentMap: paymentDate ---> List<TaxPayment>
for(Tax_Payment__c taxPayment :taxPaymentList){
    List<Tax_Payment__c> tempTaxPaymentList = taxPaymentMap.get(taxPayment.Payment_Date__c);
    if(tempTaxPaymentList == null)
        tempTaxPaymentList = new List<Tax_Payment__c>();
    tempTaxPaymentList.add(taxPayment);
    taxPaymentMap.put(taxPayment.Payment_Date__c, tempTaxPaymentList);
}

Rewriting the last example using static and instance methods:

public class TaxPaymentExtension{
    public static String DefaultTaxType = 'Federal 941';

    String taxType;
    public List<Tax_Payment__c> taxPaymentList {get;set;}
    public Map<Date, Tax_Payment__c> taxPaymentMap {get;set;}

    public TaxPaymentExtension(){
        this.taxType = ApexPages.currentPage().getParameters().get('taxtype');
        if(String.isBlank(this.taxType))
            this.taxType = TaxPaymentExtension.DefaultTaxType;
        this.taxPaymentList = [SELECT Id, Amount__c, Payment_Date__c
                               FROM Tax_Payment__c
                               WHERE Payment_Date__c = THIS_FISCAL_QUARTER
                               AND Tax_Type__c = :taxtype];
        this.taxPaymentMap = TaxPaymentExtension.getPaymentMap(taxPaymentList);
    }

    public static Map<Date, Tax_Payment__c> getPaymentMap(List<Tax_Payment__c> tpList){
        Map<Date, Tax_Payment__c> returnMap = new Map<Date, List<Tax_Payment__c>>();
            // taxPaymentMap: paymentDate ---> List<TaxPayment>
        for(Tax_Payment__c taxPayment :taxPaymentList){
            List<Tax_Payment__c> tempTaxPaymentList = taxPaymentMap.get(taxPayment.Payment_Date__c);
            if(tempTaxPaymentList == null)
                tempTaxPaymentList = new List<Tax_Payment__c>();
            tempTaxPaymentList.add(taxPayment);
            taxPaymentMap.put(taxPayment.Payment_Date__c, tempTaxPaymentList);
    }
}

For methods returning a value I like to (1) always create the return variable at the start of the method and (2) have the return variable name of the form return + Type:

!!!! This is all mumbo jumbo.  See Update on 2016-02-17 above. !!! 

public List<Case> getCaseList(){
    List<Case> returnList = new List<Case>();
    // ...
    return returnList;
}

public String getActivityFile(Date startDate, Date endDate){
    String returnString = '';
    // ...
    return returnString;
}

public class Data {
    public List<String> nameList {get;set;}
    public Map<String, Decimal> amountMap {get;set;}  // amountMap: name ---> amount
}

public Data getData(){
    Data returnData = new Data();
    // ...
    return returnData;
}

Test Classes

For Test Classes I like to always construct all necessary Test Data in a subClass. This way it is easy to create the Test Data in the Test Class itself as well as any other Test Class that might need to use it now or later on.

I also like to test Instance and Static methods separately:

@isTest
public class SpecialCaseExtensionTest{

    public class TestData{
        Account testAccount {get;set;}
        List<Case> caseList {get;set;}

        TestData(){
            // ...
        }

        // Have multiple constructors for multiple scenarios
        TestData(Integer caseCount){
            // ...
        }
    }

    @isTest
    public static void testInstanceMethods(){
        TestData tData = new TestData();

        Test.startTest();

        // ...

        Test.stopTest();
    }

    @isTest
    public static void testStaticMethods(){
        TestData tData = new TestData();

        Test.startTest();

        // ...

        Test.stopTest();
    }
}

....

@isTest
public class AnotherCaseExtension{

    public TestData{
        SpecialCaseExtensionTest.TestData specialTestData {get;set;}
        List<Account> extraAccountList {get;set;}
        // ...
    }

    @isTest
    public static void testInstanceMethods(){
        TestData tData = new TestData();

        Test.startTest();

        // ...

        Test.stopTest();
    }

    @isTest
    public static void testStaticMethods(){
        SpecialCaseExtensionTest.TestData tData = new SpecialCaseExtensionTest.TestData();
        // All I need is the Special Case Extension Test Data!
        Test.startTest();

        // ...

        Test.stopTest();
    }

4

The best and most complete documentation I've found about SalesForce conventions is provided by the CFPB "Consumer Financial Protection Bureau", which is basically a US Government organisation.

https://github.com/cfpb/salesforce-docs/blob/master/_pages/Salesforce-Naming-Conventions.md

Unfortunately, due to the length of this document, I don't think it is wise to copy/paste it here, as it should be. I'm therefore just taking a few screenshots of what I believe is the most important/interesting convention rules.

enter image description here

enter image description here

enter image description here

I also wonder if SalesForce provides any tooling that allows administrators to automatically enforce such guidelines. But I'll open another question for that.


Another resource, that is very focused on APEX conventions is https://github.com/anupj/Apex-Code-Convention/blob/master/ApexCoding.txt

3

Besides Salesforce.com specific naming recommendations you can and should keep to the Standard Java Naming conventions.

We recently started an Open Source repo on GitHub porting the famous Java Static code analyzer PMD to Apex. We also ported many of the original Java rules from PMD to Apex. Especially the Java Naming rules can be applied without any changes to Apex.

The latest PMD SNAPSHOT release also contains an updated Eclipse plugin. Just point your Force.com IDE to this Update site: https://sourceforge.net/projects/pmd/files/pmd-eclipse/update-site-latest/ and run 16 configurable Apex rules on your code.

1
  • 1
    This looks great, although the GitHub repo returns a 404 message. Has this been still maintained?
    – panza
    Commented Mar 22, 2019 at 14:50
1

For the class naming, I follow Separation of Concerns Principle (https://trailhead.salesforce.com/en/content/learn/modules/apex_patterns_sl/apex_patterns_sl_soc)

For the method and variable naming,I have write it down in my article here: https://github.com/Xixiao007/Apex-Best-Practices/blob/master/content/meaningful_names.md

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .