35

I've looked around in the Apex and Visualforce developer guides and around the web and can't seem to find any coding conventions out there. The Apex Dev guide has a section on Naming Conventions that just says to use java naming conventions (which prompted this discussion).

A good place to start might be the Java Coding Conventions since the languages are so similar, but I'm also looking for details about Salesforce specific uses such as formatting SOQL queries, as well as validation rules and formula fields. Is there a good set out there?

2
  • Have you come up with conventions that work for you? I asked a similar question but before I go ahead and work on an answer, I'm in the market for answers that already exist and I can tweak for my team. Commented Jul 21, 2014 at 2:40
  • @CharlesKoppelman just added an answer with a link to the ones I put together, it's not perfect, but could be a good starting point for you. Commented Jul 22, 2014 at 16:06

6 Answers 6

32

Great question. I haven't seen a good full set that's publicly available.

For clients in my consulting days, I've written maybe a dozen or so sets of SFDC coding conventions but sadly can't share them since they were all technically works for hire. For formatting / naming / capitalization, I always started with the Java conventions - if you follow those, you're already doing better than 95% of SFDC customers.

Typical document like this was 10-20 pages long and designed to be thoroughly absorbed by new technical team members. The sections these documents usually contained included:

  • how to set up your development environment, and how the general team development workflow works.
  • SFDC custom object conventions (field naming, object naming, every field must have descriptive help text and description, buttons vs custom links, etc)
  • Trigger rules (I'm fond of the rule that "every combination of object / before-after / event has exactly one trigger, and vice versa, and they are called, e.g., OpportunityBeforeUpdate", as well as the rule that triggers contain no real implementation code, only callouts to utility methods.)
  • Design patterns (a few teams I've worked with were committed to using a type of DAO or Service pattern, where no object-retrieval SOQL, and/or no direct references to SObject instances, are permitted in code outside of the DAO wrappers.)
  • Current overview of code, including important utility classes. This section can be long if there's a big code base and is designed to be a guide to which classes a new developer needs to familiarize themselves with immediately. Prevents the problem of having dozens of places in code where dates are being converted/formatted differently, etc.
  • i18n / l10n rules, if applicable
  • team security practices, if applicable
  • overall architecture diagram showing integrations, external portals and sites, security measures if applicable
  • use of third-party libraries in Apex and VF, which most commonly were not much more than apex-lang and JQuery / JQueryUI
  • test code guidelines. Almost every Apex developer I've worked with who isn't from a "real" dev background thinks the only reason tests exist is to hit that 75% magic number. So the section mostly ends up being training about what a good test does, and how to make a unit test actually a unit test. (Which sucks and is why line coverage is such a terrible goal to impose on the community. It could be argued that it's better than nothing, but that's about all you can say about it.)
  • rarely got into VR's and formula fields other than error message convention if they didn't come from a product manager / BA (passive vs active voice, helpfulness, etc)

Anyway, that's not really an answer to your question but hopefully at least helps people who need to come up with something like this.

6
  • Awesome answer, curious to see what else people come up with. I'm in the process of starting my own, but my goal would be to gather it into some community wiki that could become a living document. Not sure where that would best live ... Commented Mar 15, 2013 at 4:46
  • Well be prepared for an edit war over the usage of curly braces and tabs vs spaces! :) Coding conventions benefit from the ownership of a benevolent dictator, imo, but I'd definitely be up for contributing some of my opinions.
    – jkraybill
    Commented Mar 15, 2013 at 4:53
  • Lol, good point, sounds like a publicly accessible document with commenting but no edit rights might be the better route. Commented Mar 15, 2013 at 4:58
  • Would that be possible to point some sample for DAO/Service pattern implementation in APEX and Third Party Apex Library.. Please Commented Mar 16, 2013 at 2:30
  • @kadalamittai haven't seen any such example "in the wild" but I use it all the time. Maybe I'll write a post on it some time, it's a very useful pattern.
    – jkraybill
    Commented Mar 16, 2013 at 3:02
11

@jkraybill gave an excellent overall answer.

For SOQL, I like to keep it as readable as possible so that I can see its function in a quick scan. I might move the query into its own self describing named function, too, if that helps.

  1. The first line has the assignment to the variable and the end line has the closing bracket.
  2. Use Uppercase first letter for keywords (seems to work well with syntax highlighter in IDE, isn't a pain to type, and the Force.com IDE's schema browser generates it that way).
  3. Group like fields on the same line (e.g., from the same parent), breaking for new groups of fields or if it gets too long to fit in a reasonable IDE window (100 characters?).

    3.1. Primary fields of an object first.

    3.2. Parent fields second.

    3.3. Related lists last.

  4. Four spaces for indentation.
  5. Indent for readability.

List<Account> accts = [
    Select   
        Id, Name, AccountNumber, Description,
        BillingStreet, BillingCity, BillingState, BillingPostalCode, BillingCountry,
        ShippingStreet, ShippingCity, ShippingState, ShippingPostalCode, ShippingCountry,
        (Select 
             Id, Name, CloseDate, StageName, Description,
             Account.Name, Account.AccountNumber
         From Opportunities
         Where Name = 'ABC'),
        (Select
             Id, FirstName, LastName
         From Contacts
         Where FirstName = 'Peter'
             And LastName = 'Knolle'
             And Email = '[email protected]')
    From Account
    Where Id In :setOfIds
        And Name Like 'Heroku%'
        And AccountNumber
];

All that being said, for a simple, compact query I will break that rule and write a one-liner.

   List<Account> accts = [Select Name From Account Where Id In :ids];

Or a simple three liner.

List<Account> accts = [
    Select Id, Name, AccountNumber
    From Account
    Where Id In :setOfIds
];
  • I usually stick to the rule of keeping the formatting consistent within a single file, so if I'm editing some legacy code I may not apply new rules, but rather stick to whatever rules have been adhered to within that file.

  • Readability is of utmost importance. I don't care as much about adhering 100% to the indenting rules when code reviewing, as long as the query is 100% readable.

  • I used to have more line break and indenting in SOQL formatting such as near the From clause, but I felt that the queries weren't gaining any readability from it.

You could probably search for SQL formatting for some other suggestions that could be translated over to SOQL.

1
  • Amazing answer and great suggestion about reviewing the SQL conventions out there for insight. A quick google search seems that it's a pretty contentious subject. My thought is to treat "[" like a bracket and keywords, i.e. SELECT, as having an implied bracket. Really like the thought you put into the ordering, i.e. primary object first. Might be worth adding use aliases for clarity on parent objects to avoid extra long select lins. Commented Mar 16, 2013 at 2:18
5

We recently started an Open Source repo on GitHub porting the famous Java Static code analyzer PMD to Apex. We would love to see you join as contributor.

We also ported many of the original Java rules from PMD to Apex. Those are great convention to use (and automatically check code for):

Code Size Rules

  • ExcessiveMethodLength: When methods are excessively long this usually indicates that the method is doing more than itsname/signature might suggest. They also become challenging for others to digest since excessive scrolling causes readers to lose focus.Try to reduce the method length by creating helper methods and removing any copy/pasted code.

  • ExcessiveParameterList: Methods with numerous parameters are a challenge to maintain, especially if most of them share thesame datatype. These situations usually denote the need for new objects to wrap the numerous parameters. ExcessiveClassLength: Excessive class file lengths are usually indications that the class may be burdened with excessive responsibilities that could be provided by external classes or functions. In breaking these methodsapart the code becomes more managable and ripe for reuse.

  • StdCyclomaticComplexity: Complexity directly affects maintenance costs is determined by the number of decision points in a method plus one for the method entry. The decision points include ‘if’, ‘while’, ‘for’, and ‘case labels’ calls. Generally, numbers ranging from 1-4 denote low complexity, 5-7 denote moderate complexity, 8-10 denotehigh complexity, and 11+ is very high complexity.

  • ExcessivePublicCount: Classes with large numbers of public methods and attributes require disproportionate testing effortssince combinational side effects grow rapidly and increase risk. Refactoring these classes intosmaller ones not only increases testability and reliability but also allows new variations to bedeveloped easily.

  • TooManyFields: Classes that have too many fields can become unwieldy and could be redesigned to have fewer fields,possibly through grouping related fields in new objects. For example, a class with individual city/state/zip fields could park them within a single Address field.

Coupling (Java)

  • CouplingBetweenObjects: This rule counts the number of unique attributes, local variables, and return types within an object. A number higher than the specified threshold can indicate a high degree of coupling.

Design (Java)

  • UseUtilityClass: For classes that only have static methods, consider making them utility classes.Note that this doesn’t apply to abstract classes, since their subclasses maywell include non-static methods. Also, if you want this class to be a utility class,remember to add a private constructor to prevent instantiation.(Note, that this use was known before PMD 5.1.0 as UseSingleton).

  • AvoidDeeplyNestedIfStmts: Avoid creating deeply nested if-then statements since they are harder to read and error-prone to maintain.

  • GodClass: The God Class rule detects the God Class design flaw using metrics. God classes do too many things,are very big and overly complex. They should be split apart to be more object-oriented.The rule uses the detection strategy described in “Object-Oriented Metrics in Practice”.The violations are reported against the entire class. See also the references:Michele Lanza and Radu Marinescu. Object-Oriented Metrics in Practice:Using Software Metrics to Characterize, Evaluate, and Improve the Designof Object-Oriented Systems. Springer, Berlin, 1 edition, October 2006. Page 80.

Unused Code (Java)

  • UnusedPrivateField: Detects when a private field is declared and/or assigned a value, but not used.
  • UnusedLocalVariable: Detects when a local variable is declared and/or assigned, but not used.
  • UnusedPrivateMethod: Unused Private Method detects when a private method is declared but is unused.
  • UnusedFormalParameter: Avoid passing parameters to methods or constructors without actually referencing them in the method body.
  • UnusedModifier: Fields in interfaces are automatically public static final, and methods are public abstract.Classes or interfaces nested in an interface are automatically public and static (all nested interfaces are automatically static).For historical reasons, modifiers which are implied by the context are accepted by the compiler, but are superfluous.

Naming (Java)

  • VariableNamingConventions: A variable naming conventions rule - customize this to your liking. Currently, it checks for final variables that should be fully capitalized and non-final variables that should not include underscores.
  • MethodNamingConventions: Method names should always begin with a lower case character, and should not contain underscores.
  • ClassNamingConventions: Class names should always begin with an upper case character.
  • MethodWithSameNameAsEnclosingClass: Non-constructor methods should not have the same ng conventions indicate a constant. However, the field is not final.
4

In the interest of sharing with the community, feel free to review and/or copy the Coding Conventions I've put together for my team.

Please be aware of the following caveats:

  • This is a work in progress
  • This contains elements that are specific to my team and may not work for you
  • It may get changed at any time for any reason, so make a copy if you want to use it for your team
4

I'll throw in my bits on variable naming conventions (no doubt controversial to some) but they work for me

Boolean variables Try real hard to name these so when read aloud, indicate that when used in an if statement or in a VF-referenced boolean getter, the name reads as the 'true' value. (SFDC uses this approach for SObject field names such as Opportunity.isWon so consistency was my guide here)

Example

Boolean  hasExceededCapacity;
if (hasExceededCapacity) ...

public Boolean isDisabledFromEdit {get; private set;}

List, Sets, and Maps

Because the methods are different on these collections and they also serve different purposes (e.g. Lists can be indexed, used for DML, ...; Sets are good for uniqueness; Maps are directly indexable by key and crucial to bulkification), I like to suffix my collection variables with either List, Set, or Map.

If a List, the List is named with some prefix indicating what is being collected followed by the purpose of the list

List<Account> aUpdList;  // List to use in DML statement to update Accounts

If a Set, the Set is named with some prefix indicating what is being collected followed the purpose of the set

Set<ID> oIdSearchSet;  // Set of OpportunityIds used in a SOQL where clause

If a Map, the Map is always named as keyToWhatMap as in..

Map<ID,Account> aIdToAccountMap;  // Map of account Ids to Accounts
Map<ID,List<Account>> aIdToAccountListMap;  // Map of account Ids to List of Accounts

The advantage to the above is that when you have a method/class with lists, sets, and maps, it is easy to see (particularly months later) what each variable does and what its inherent 'limitations/features' are as you debug or extend.

I eschew the approach so commonly seen in SFSE code posts:

List<Account> acct;       // not even a plural variable name!
Map<ID,Contact> contacts; // variable name implies a list but is declared as a map!

this

Lastly, although not strictly required, whenever I reference a class member variable in a method, I try real hard to prefix by this.

public class Foo {
    Integer aUpdCounter;

    public bar() {
       this.aUpdCounter++;   // use of this.
    }
}

The reason I do this is when the class spans more than one screen's worth of my IDE, I like to be reminded when reviewing the code which variables are local to the method and which are class instance variables.

1

An in-depth convention guidelines for APEX programming can be found at https://github.com/anupj/Apex-Code-Convention/blob/master/ApexCoding.txt

Also, this document focuses more on the SalesForce administration side, how to name about every entity. https://github.com/cfpb/salesforce-docs/blob/master/_pages/Salesforce-Naming-Conventions.md

Similar question can be found on SO at What is a good set of naming conventions to use when developing on the Force.com platform? and also contains more SalesForce users feedbacks and point of views.

You must log in to answer this question.

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