fflib-apex-common
fflib-apex-common copied to clipboard
New Selector Pattern
@afawcett I said earlier in a different issue #75 that is now closed that we developed a selector pattern that allows us to work with different fields based on the call to the selector. We have been using it primarily to lookup all fields, updateable fields, or a list of external ids
We accomplish this by setting an enum before we call one of the selector methods.
You can see an example of this in the code below of an Account Selector
public class AccountSelector extends fflib_SObjectSelector {
/**
* @description Get the type of the sObject
*/
public Schema.SObjectType getSObjectType(){
return Account.sObjectType;
}
//Enum used to change the fieldnames selected by the selector
public enum SelectorOption {ALL, UPDATEABLE, STANDARD}
//Variable used to store the SelectorOption enum value
public SelectorOption selectorOptionValue = SelectorOption.STANDARD;
public List<Schema.SObjectField> getSObjectFieldList(){
if (selectorOptionValue.name() == SelectorOption.ALL.name()) {
//Select all fields on the object
return Account.sObjectType.getDescribe().fields.getMap().values();
} else if (selectorOptionValue.name() == SelectorOption.UPDATEABLE.name()) {
//select only the updateable fields
List<Schema.SObjectField> editableFields = new List<Schema.SObjectField>();
List<Schema.SObjectField> allFields = Account.sObjectType.getDescribe().fields.getMap().values();
for(Schema.SObjectField field : allFields) {
Schema.DescribeFieldResult fd = field.getDescribe();
if (fd.isUpdateable()) {
editableFields.add(field);
}
}
return editableFields;
} else {
//Default or STANDARD enum option
return new List<Schema.SObjectField> {
Account.Id,
Account.FirstName,
Account.MiddleName,
Account.LastName,
Account.Suffix,
Account.PersonEmail,
Account.Phone,
Account.PersonBirthdate
};
}
}
the call to the selector looks like this
AccountSelector selector = new AccountSelector();
selector.selectorOptionValue = AccountSelector.SelectorOption.ALL;
List<Account> accounts = selector.selectAccountsById(new Set<Id>{accountId});
There are probably areas for improvement and there might be a way to code this into fflib if there is value in that.
Let me know what you think
Thanks for sharing. I am less keen on state based configurations effecting the behaviour of standard methods. If the selector instance is passed around or used later in the execution it becomes less clear how its been configured. Have you considered the decorator pattern? https://www.journaldev.com/1540/decorator-design-pattern-in-java-example
I agree with Andy -- if you want a specific Selector to return only updateable fields, then the usage would be AccountsSelector.newInstance().selectAllUpdateableById(someIdSet)
and let the selector method itself resolve from the Describe those fields that are updateable