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 5. Application Service Layer

If your application were considered a living organism, the Service layer would be its beating heart. Regardless of how the environment and the things that interact with it change over time, it must remain strong and able to adapt. In this chapter, we begin our journey with the three coding patterns: Service, Domain, and Selector, which were introduced in Chapter 4, Apex Execution and Separation of Concerns.

In this chapter, we will review the pattern as set out by Martin Fowler and then review how it has been applied on the Force.com platform in Apex, describing design guidelines born from the Separation of Concerns we defined in the previous chapter.

One concern of this layer is interacting with the database; a later chapter will cover querying this in more detail. This chapter will focus on updating the database and introducing a new pattern, Unit Of Work, which helps make your code more streamlined and bulkified.

At the end of this chapter, we will extend...

Introducing the Service layer pattern


The following is Martin Fowler's definition of the Service layer (http://martinfowler.com/eaaCatalog/serviceLayer.html):

"Defines an application's boundary with a layer of services that establishes a set of available operations and coordinates the application's response in each operation."

The use of the word boundary in Martin's definition is interesting, as this literally represents the point of separation or boundary between the concerns of the application's business logic in the Service layer and execution context or caller, be that a Visualforce or Lightning Component Controller class or a Batch Apex class, as illustrated in the UML diagrams shown in the previous chapter.

The following illustration shows just some of the types of callers that an Apex Service layer is designed to support. By following the design guidelines given in the next diagram, you can ensure that your Service layer code can be called from any one of these features and others in...

Implementation of design guidelines


Having studied the Separation of Concerns in the previous chapter and reflected on the previous illustration, the following design guidelines help ensure that the Service layer is agnostic towards the caller, easy to locate, and encourages some Force.com best practices, such as bulkification. Note that bulkification is not just a concept for Apex Triggers; all the logic in your application must make efficient use of governed resources.

Naming conventions

A colleague of mine used to reference the following when talking about naming:

"There are only two hard things in Computer Science: cache invalidation and naming things."

- Phil Karlton

In my career so far, I have come to realize that there is some truth in this statement. Naming conventions have never been so important on Force.com as it is currently without a means to group or structure code files, using a...

Handling DML with the Unit Of Work pattern


The database maintains relationships between records using record IDs. Record IDs are only available after the record is inserted. This means that the related records, such as child object records, need to be inserted in a specific dependency order. Parent records should be inserted before child records, and the parent record IDs are used to populate the relationship (lookup) fields on the child record objects before they can be inserted.

The common pattern for this is to use the List or Map keyword to manage records inserted at a parent level, in order to provide a means to look up parent IDs, as child records are built prior to being inserted. The other reasoning for this is bulkification; minimizing the number of DML statements being used across a complex code path is vital to avoid hitting governor limits on the number of DML statements required as such lists are favored over executing individual DML statements per record.

The focus on these two...

Services calling services


In the previous chapter, I described a reuse use case around a FormulaForce application feature that awards championship points to contestants. We imagined the first release of the application providing a Custom Button only on the Contestant detail page and then the second release also providing the same button but on the Race detail page.

In this part of the chapter, we are going to implement the respective service methods, emulating this development cycle and, in turn, demonstrating an approach to call between Service layer methods, passing the Unit Of Work correctly.

First, let's look at the initial requirement for a button on the Contestant detail page; the method in the ContestantService class looks like the following:

publicstaticvoidawardChampionshipPoints(Set<Id>contestantIds) {
  fflib_SObjectUnitOfWorkuow = Application.UnitOfWork.newInstance();

  // Apply championship points to given contestants
  Map<Integer, ChampionshipPoint__mdt>pointsByTrackPosition...

Contract Driven Development


If you have a large piece of functionality to develop, with a complex Service layer and user interface client logic, it can be an advantage to decouple these two streams of development activity so that developers can continue in parallel, meeting up sometime in the future to combine efforts.

An approach to this is sometimes referred to as Contract Driven Development. This is where there is an agreement on a contract (or service definition) between the two development streams before they start their respective developments. Naturally, the contract can be adjusted over time, but having a solid starting point will lead to a smoother parallel development activity.

This type of development can be applied by implementing a small factory pattern within the Service layer class. The main methods on the service class are defined as normal, but their internal implementation can be routed to respective inner classes to provide an initial dummy implementation of the service...

Testing the Service layer


It is tempting to allow the testing of the Service layer to be done via tests around the calling code, such as Visualforce controller tests. However, depending solely on this type of testing leaves the Service layer logic open to other use cases that may not strictly be covered by the controller logic. For example, a custom controller using StandardController will only pass in a single record and not multiple ones. Make sure to develop specific Apex tests against the Service layer as the functionality is developed.

Mocking the Service layer

Sometimes, the data setup requirements of the Service layer are such that it makes writing Apex tests for controllers or other callers, such as Batch Apex, quite complex and thus expensive, not only in terms of server time for the test to run (due to data setup for each test method) but also in terms of developer time, while preparing a full set of test data.

While you still need to test the full stack of your code, there is an...

Calling the Service layer


The preceding examples have shown the use of the service class methods from Visualforce Controller methods. Let's take a closer look at what is happening here, the assumptions being made, and also at an Apex Scheduler example. Other examples of service methods in action, such as from a Lightning Component, will feature throughout later chapters.

The following code represents code from a controller class utilizing StandardController that provides support for the Visualforce page associated with a Custom Button on the Race object. Notice how it wraps the record ID in Set, honoring the bulkified method signature:

public PageReferenceawardPoints(){
  try{
    RaceService.awardChampionshipPoints(new Set<Id> {standardController.getId() });
  }

  catch (Exception e){
    ApexPages.addMessages(e);
  }
  return null;
}

The constructor of these controllers is not shown, but it essentially stores StandardController or StandardSetController in a member variable for later...

Summary


In this chapter, we have taken the first step in developing a robust coding convention to manage and structure the coding complexities of an enterprise application. This first layer encapsulates your application's business process logic in an agnostic way, in a way that allows it to be consumed easily across multiple Apex entry points; both those required today by your application and those that will arise in the future as the platform evolves.

We have also seen how the Unit Of Work pattern can be used to help bulkify DML statements, manage record relationships and implement a database transaction, and allow your Service layer logic to focus more on the key responsibility of implementing business logic. In the upcoming chapters, we will see how it quickly becomes the backbone of your application. Careful adherence to the guidelines around your Service layer will ensure it remains strong and easy to extend.

In the next chapter, we will look at the Domain layer, a pattern that blends...

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