Constants - wimvelzeboer/fflib-apex-extensions GitHub Wiki
Avoid centralisation
Constants are everywhere and should be everywhere. Try to avoid centralizing them into a single class, but keep them close to their purpose/concern. That avoids having a God-class and using a single constant for two complete different purposes.
We can identify the following different types of constants;
These constants contain information specifically about the application itself. It should not contain constants that should be available for the entire application, those belong to a specific concern (see field names, field labels).
public class Application
{
public static final String NAME "MyApp";
public static final String NAMESPACE "myapp";
...
}
Class constants are typically private as they are only available in the class.
public class MyClass
{
private static final String MY_PROPERTY "My Property";
...
}
Constants related to SObjects are typically field names, labels and picklist values (global values-sets excluded) are grouped into their own class.
public with sharing class AccountNames
{
// Regular fields
public static String Rating
{ get { return Schema.Account.Rating.getDescribe().getName(); } } // returns `Rating`
// Picklist field values
public static RecordTypeNames RecordType
{
get
{
if (RecordType == null)
{
RecordType = new RecordTypeNames();
}
return RecordType;
}
private set;
}
public class RecordTypeNames
{
public final String Partner = RecordTypes.Partner.name();
public final String Internal = RecordTypes.Internal.name();
public final String Customer = RecordTypes.Customer.name();
}
public enum RecordTypes
{
Partner, Internal, Customer
}
}
Usage
String PartnerRecordTypeName = AccountNames.RecordType.Partner; // returns 'Partner'
// Using the ENUM
Accounts partnerAccounts =
Accounts.newInstance(records).selectByRecordType(AccountNames.RecordTypes.Partner);
// Using the String
Accounts partnerAccounts =
Accounts.newInstance(records).selectByRecordType(AccountNames.RecordType.Partner);
// Regular field names
String rating = AccountNames.Rating;
public class AccountLabels
{
// Regular fields
public static String Rating
{ get { return Schema.Account.Rating.getDescribe().getLabel(); } } // returns `Account Rating`
// Picklist fields
public static RecordTypeLabel RecordType
{
get
{
if (RecordType == null)
{
RecordType = new RecordTypeLabel();
}
return RecordType;
}
private set;
}
public class RecordTypeLabel
{
public final String Partner = 'Partner Account';
public final String Internal = 'Internal Account';
public final String Customer = 'Customer Account';
}
}
Usage
String HotRating = AccountLabels.Rating.Hot;
String PartnerRecordTypeLabel = AccountLabels.RecordType.Partner; // returns 'Partner Account'
Global value sets can best have their own class, so that they are easily accessible.
public class CountryLabels
{
public static final String IRELAND = 'Ireland, Republic of';
public static final String USA = 'United States Of America';
....
}
public class Country
{
public static final String IRELAND = 'Ireland';
public static final String USA = 'USA';
....
}
public class CountryCodes
{
public static final String IRELAND = 'IE';
public static final String USA = 'USA';
....
}
public class LanguageCodes
{
public static final String IRELAND_English = 'en-IE';
public static final String IRELAND_IRISH = 'ga-IE';
public static final String USA_English = 'en-US';
public static final String UK_ENGLISH = 'en-GB';
....
public static final Map<String, Set<String>> BY_COUNTRY_NAME = new Map<String, Set<String>>
{
Country.Codes.IRELAND => new Set<String>{ IRELAND_English, IRELAND_IRISH }
Country.Codes.USA => new Set<String>{ USA_English }
....
}
}
Usage
String ireland = Country.IRELAND; // 'Ireland'
String irelandLabel = CountryLabels.IRELAND; // 'Ireland, Republic of'
String gaelic = LanguageCodes.IRELAND_IRISH; // 'ga-IE'
Set<String> languages =
LanguageCodes.BY_COUNTRY_NAME.get(CountryCodes.IRELAND); // {'en-IE', 'ga-IE'}