Reader small image

You're reading from  Force.com Enterprise Architecture - Second Edition

Product typeBook
Published inMar 2017
Reading LevelIntermediate
PublisherPackt
ISBN-139781786463685
Edition2nd Edition
Languages
Right arrow
Author (1)
Andrew Fawcett
Andrew Fawcett
author image
Andrew Fawcett

Andrew Fawcett has over 30 years of experience holding several software development-related roles with a focus around enterprise-level product architecture. He is experienced in managing all aspects of the software development life cycle across various technology platforms, frameworks, industry design patterns, and methodologies. He is currently a VP, Product Management, and a Salesforce Certified Platform Developer II at Salesforce. He is responsible for several key platform features and emergent products for Salesforce. He is an avid blogger, open source contributor and project owner, and an experienced speaker. He loves watching movies, Formula 1 motor racing, and building Lego!
Read more about Andrew Fawcett

Right arrow

Chapter 7. Application Selector Layer

Apex is a very expressive language to perform calculations and transformations of data entered by the user or records read from your Custom Objects. However, SOQL also holds within it a great deal of expressiveness to select, filter, and aggregate information without having to resort to Apex. SOQL is also a powerful way to traverse relationships (up to five levels) in one statement, which would otherwise leave developers on other platforms performing several queries.

Quite often, the same or similar SOQL statements are required in different execution contexts and business logic scenarios throughout an application. Performing these queries inline as and when needed, can rapidly become a maintenance problem as you extend and adapt your object schema, fields, and relationships.

This chapter introduces a new type of Apex class, the Selector, based on Martin Fowler's Mapper pattern, which aims to encapsulate the SOQL query logic, making it easy to access,...

Introducing the Selector layer pattern


The following is Martin Fowler's definition of the Data Mapper layer on which the Selector layer pattern is based (http://martinfowler.com/eaaCatalog/dataMapper.html):

"A layer of Mappers (473) that moves data between objects and a database while keeping them independent of each other and the Mapper itself."

In Martin's definition, he is referring to objects as those resulting from the instantiation of classes within an OO language such as Java or Apex. Of course, in the Force.com world, this has a slightly ambiguous meaning, but is more commonly thought of as the Standard or Custom Object holding the record data.

One of the great features of the Apex language is that it automatically injects object types into the language that mirror the definition of the Custom Objects you define. These so-called SObjects create a type-safe bond between the code and the database schema, though you can also leverage Dynamic Apex and Dynamic SOQL to change these references...

Implementing design guidelines


The methods in the Selector classes encapsulate common SOQL queries made by the application, such as selectById, as well as more business-related methods, such as selectByTeam. This helps the developers who consume the Selector classes identify the correct methods to use for the business requirement and avoids replication of SOQL queries throughout the application.

Each method also has some standard characteristics, such as the SObject fields selected by the queries executed, regardless of the method called. The overall aim is to allow the caller to focus on the record data returned and not how it was read from the database.

Naming conventions

By now, you're starting to get the idea about naming conventions. The Selector classes and methods borrow guidelines from other layers with a few tweaks. Consider the following naming conventions when writing the Selector code:

  • Class names: in naming a Selector class, it typically follows the same convention as a Domain...

The Selector class template


A Selector class, like the Domain class, utilizes inheritance to gain some standard functionality; in this case, the base class delivered through the FinancialForce.com Enterprise Apex Patterns library, fflib_SObjectSelector.

A basic example is as follows:

public class RacesSelector extends fflib_SObjectSelector {

    public List<Schema.SObjectField> getSObjectFieldList() {
       return new List<Schema.SObjectField> {
           Race__c.Id,
           Race__c.Name,
           Race__c.Status__c,
           Race__c.Season__c,
           Race__c.FastestLapBy__c,
           Race__c.PollPositionLapTime__c,
           Race__c.TotalDNFs__c };
    }

    public Schema.SObjectTypegetSObjectType() {
        return Race__c.sObjectType;
    }
}

Tip

The base class uses Dynamic SOQL to implement the features described in this chapter. One potential disadvantage this can bring is that references to the fields are made without the Apex compiler knowing about them, and...

Implementing the standard query logic


The previous Selector usage example required a cast of the list returned to a list of Race__c objects, which is not ideal. To improve this, you can easily add a new method to the class to provide a more specific version of the base class method, as follows:

public List<Race__c> selectById(Set<Id>raceIds){
  return (List<Race__c>) selectSObjectsById(raceIds);
}

Thus, the usage code now looks like this:

List<Race__c> races = 
  new RacesSelector().selectById(raceIds); 

Standard features of the Selector base class

The fflib_SObjectSelector base class contains additional functionality to provide more query consistency and integration with the platform. These apply to the aforementioned selectSObjectsById method as well as your own. The following sections highlight each of these features.

Tip

You can, of course, extend the standard features of this base class further. Perhaps there is something you want all your queries to consider, a common...

Implementing custom query logic


If we take a look at the implementation of the selectSObjectById base class method we have been using so far in this chapter, the buildQuerySObjectById method code shown as following, gives an indication of how we implement custom Selector methods; it also highlights the newQueryFactory base class method usage:

public List<SObject> selectSObjectsById(Set<Id>idSet) {
  return Database.query(buildQuerySObjectById());
}
private String buildQuerySObjectById() {
  return newQueryFactory().
           setCondition('id in :idSet').
           toSOQL();
}

The newQueryFactory method exposes an alternative object orientated way to express a SOQL query. It follows the fluent design model with its methods making the configuration less verbose. For more information on this approach see https://en.wikipedia.org/wiki/Fluent_interface.

The instance of fflib_QueryFactory returned by this method is preconfigured with the object, fields, order by and any field set...

Introducing the Selector factory


The last chapter introduced the concept of a Domain factory, which was used to dynamically construct Domain class instances implementing a common Apex Interface in order to implement the compliance framework.

The following code is used in the ComplianceService.verify method's implementation, making no reference at all to a Selector class to query the records needed to construct the applicable Domain class:

fflib_SObjectDomain domain =
  Application.Domain.newInstance(recordIds);

So, how did the Domain factory retrieve the records in order to pass them to the underlying Domain class constructor? The answer is that it internally used another factory implementation called the Selector factory.

As with the Domain factory, the Selector factory resides within the Application class as a static instance, exposed via the Selector static class member, as follows:

public class Application 
{
  // Configure and create the SelectorFactory for this Application
  public static...

Updating the FormulaForce package


Review the updated code supplied with this chapter and update your packaging org. Perform another upload and install the package in your testing org. During install you should observe that the new Field Set component added in this chapter is shown as one of the new components included in the upgrade.

Summary


The Selector pattern provides a powerful layer of encapsulation for some critical logic in your application. It can help with enforcing best practices around security and provides a more consistent and reliable basis for code dealing with the SObject data.

Selectors can also take on the responsibility and concern for platform features such as Multi-Currency and Field Sets. Ultimately allowing the caller—be that the Service, Domain, or even Apex Controllers, or Batch Apex—to focus on their responsibilities and concerns, this leads to cleaner code which is easier to maintain and evolve.

With the introduction of the Selector factory, we provide a shortcut to access this layer in the form of the Application.Selector.selectById and Application.Selector.newInstance methods, opening up potential for more dynamic scenarios such as the compliance framework highlighted in the last chapter.

I'd like to close this set of chapters with a simple but expressive diagram that shows how the Service layer...

lock icon
The rest of the chapter is locked
You have been reading a chapter from
Force.com Enterprise Architecture - Second Edition
Published in: Mar 2017Publisher: PacktISBN-13: 9781786463685
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
undefined
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at £13.99/month. Cancel anytime

Author (1)

author image
Andrew Fawcett

Andrew Fawcett has over 30 years of experience holding several software development-related roles with a focus around enterprise-level product architecture. He is experienced in managing all aspects of the software development life cycle across various technology platforms, frameworks, industry design patterns, and methodologies. He is currently a VP, Product Management, and a Salesforce Certified Platform Developer II at Salesforce. He is responsible for several key platform features and emergent products for Salesforce. He is an avid blogger, open source contributor and project owner, and an experienced speaker. He loves watching movies, Formula 1 motor racing, and building Lego!
Read more about Andrew Fawcett