Implementation design guidelines

As in the previous chapter, this section provides some general design and best practice guidelines around designing a Domain layer class for a given object. Note that some of these conventions are shared by the Service layer, as it also calls the Domain layer because conventions such as bulkification apply to the logic written here as well.

Naming conventions

The key principle of the Domain layer pattern is to lay out the code in such a way that it maps to the business domain of the application. In a Force.com application, this is typically supported by the Custom Objects. As such, it's important to clearly indicate which Domain layer class relates to which Standard or Custom Object:

  • Avoid acronyms: As per the previous chapter, try to avoid these unless it makes your class names unworkably long.
  • Class names: Use the plural name of your Custom Object for the name of your Domain class. This sets the tone for the scope of the record that the class deals with as clearly being bulkified, as described in the following subsection.
    • Some bad examples are Race.cls and RaceDomain.cls
    • Some good examples are Races.cls and Teams.cls
  • Method names: Methods that relate to the logic associated with database operations or events should follow the onEventName convention. Other method names should be descriptive and avoid repeating the name of the class as part of the name.
    • Some bad examples are Races.checkInserts and Races.startRace
    • Some good examples are Races.onBeforeInsert and Races.start
  • Parameter Names and Types: Much of what was described in the previous chapter applies here. Though passing in a list of records to the Domain class methods is not required, this is available as a class member variable to all the domain class methods, as you will see later in this chapter.
    • Some bad examples are:
      Races.onBeforeInsert(
        List<Race__c>racesBeingInserted)
      Races.start(
        List<Id>raceIds)
    • Some good examples are:
      Races.onBeforeInsert()
      Races.start()
  • Inner classes and interfaces: Much of what was described in the previous chapter also applies here. As the data being managed is expressed in terms of the actual Custom Object themselves and that information is available as a class member variable, there is typically less of a need for inner classes representing data to be passed in and out of a Domain class.

The following diagram shows how the Domain classes that are used in this chapter map to their respective Custom Objects. Each Domain class receives the records that its methods act on in its constructor. The methods shown in the Domain classes are described in more detail as we progress through this chapter.

Naming conventions

Bulkification

As with the Service layer, code written in the Domain layer is encouraged to think about records in a bulk context. This is important when Domain class methods are being called from an Apex Trigger context and the Service layer code, both of which carry the same bulkification requirement.

Instead of enforcing bulkification through passing parameters and ensuring that parameter types are bulkified, as with the Service layer, the information in the Domain class logic acts on and is driven by its member variables, which are bulkified. In this case, the Records class property returns a List<SObject> object:

public void onValidate() {
  for(Contestant__c race : (List<Contestant__c>) Records) {
  }
}

Defining and passing data

Most methods on Domain classes already have the information they need through the Records property (the state the Domain class was constructed with). As such, there is little need to pass data information on the methods themselves. However, for some custom behavior methods (those not reflecting the Apex Trigger logic), you might want to pass other domain objects and/or a Unit Of Work as additional parameters. Examples later in this chapter help illustrate this.

Transaction management

For Domain class methods that perform database operations, there are two design guidelines: utilize a transaction context (Unit Of Work) passed as a parameter to the method or create one for the scope of the Domain class method execution.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
52.14.39.59