Apex Naming and Organization
Naming Conventions
Project code prefix
First-party Apex classes, exceptions, and related global types use a project-specific prefix in ALL_CAPS, an underscore, and a descriptive PascalCase name (for example ACME_AccountService). How your team chooses and records that prefix—and how it lines up with LWC bundle naming—is covered in Project code prefix.
Classes
-
Format:
<APEX_PREFIX>_ClassNameInPascalCase(placeholder:ACME_…) -
Naming: ALL_CAPS project prefix, underscore, then descriptive PascalCase name
-
Pattern:
<APEX_PREFIX>_<DescriptiveClassName> -
Examples:
public class ACME_AccountSelector { } public class ACME_AccountTriggerHandler { } public class ACME_PermissionUtils { } public class ACME_ProjectService { }
Methods
-
Format: camelCase
-
Naming: Verb-based names that describe the action performed
-
Examples:
public static List<Account> getAccounts() { } public void processRecords(List<SObject> records) { } private Boolean validateInput(String input) { }
Variables
-
Format: camelCase
-
Naming: Be specific and self-documenting - prefer full words over unclear abbreviations (unless the abbreviation is widely understood). Name for what the value is (e.g.
accountNamenotname,accountListnotlist), including temporaries. -
Length: Single- and double-letter names are not allowed except for loop index variables (
i,j,k, etc.). -
Examples:
// Good: Meaningful variable names String accountName = 'Test Account'; Integer recordCount = 10; Boolean isLoading = true; List<Account> accountList = new List<Account>(); Account currentAccount; String errorMessage = error.getMessage(); // Good: Loop index variables (exception to the rule) for (Integer i = 0; i < items.size(); i++) { processItem(items[i]); } for (Integer j = 0; j < rows.size(); j++) { for (Integer k = 0; k < columns.size(); k++) { processCell(rows[j], columns[k]); } } // Bad: Single/double character variables (except loop indices) String a = 'Test Account'; // Bad - use accountName Integer x = 10; // Bad - use recordCount Account acc = [SELECT Id FROM Account LIMIT 1]; // Bad - use currentAccount or accountRecord String msg = error.getMessage(); // Bad - use errorMessage // Bad: Unclear abbreviations String accNm = 'Test Account'; // Bad - use accountName List<Account> accs = new List<Account>(); // Bad - use accountList or accounts Integer cnt = 0; // Bad - use recordCount or count
Constants
-
Format: UPPER_SNAKE_CASE
-
Naming: Descriptive names in all caps with underscores
-
Examples:
static final String DEFAULT_STATUS = 'Active'; static final Set<String> DATE_LITERALS = new Set<String>{ 'YESTERDAY', 'TODAY', 'TOMORROW' }; static final Integer MAX_RETRY_ATTEMPTS = 3;
Exceptions
-
Format: PascalCase with "Exception" suffix
-
Naming: Descriptive name indicating the exception type
-
Examples:
public class ACME_ValidationException extends Exception { } public class ACME_SecurityException extends Exception { } public class ACME_DataAccessException extends Exception { }
Inner Classes
-
Format: PascalCase (same as top-level classes)
-
Usage: Discretionary - wrappers and response classes are acceptable as inner classes, but don't overuse
-
Examples:
public class ACME_AccountSelector { public class QueryResult { // Inner class for query results } }
Constants vs Enums
Note: Normative guidelines are deferred until the team agrees when to prefer Apex enum types versus static final constants (and how that interacts with picklists, packages, and integrations). Until then, use constants by default unless an existing module has already standardized on enums.
Code Organization
Class Structure Order
Classes should follow this order:
- Constants - Static final fields
- Properties - Instance and class variables
- Constructors - Class constructors
- Methods - Public methods first, then private/protected methods
Example:
public with sharing class ACME_AccountService {
// 1. Constants
private static final String DEFAULT_STATUS = 'Active';
// 2. Properties
private String accountName;
private List<Contact> contacts;
// 3. Constructors
public ACME_AccountService() {
contacts = new List<Contact>();
}
// 4. Public Methods
public static Account createAccount(String name) {
// Implementation
}
// 4b. Private Methods
private Boolean validateAccount(Account acc) {
// Implementation
}
}
Package Organization
Code should be organized by feature/domain in your Salesforce DX package structure so related classes are easy to find and maintain:
force-app/
└── main/
└── default/
└── classes/
├── account/
│ ├── ACME_AccountService.cls
│ ├── ACME_AccountSelector.cls
│ └── ACME_AccountTriggerHandler.cls
├── billing/
│ ├── ACME_InvoiceService.cls
│ └── ACME_PaymentGateway.cls
└── shared/
└── ACME_PermissionUtils.cls
Change History
Version 1.0 - 2026-03-26
- Added initial version history tracking for this document.
Last Updated: 2026-03-26 Version: 1.0