Update on 2016-02-17
I've evolved the below in a few cases:
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
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);
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();
}