Advanced 40 min read

Build the Domain Layer

By the end of this lesson, you'll be able to:

  • Write a domain/trigger handler class for Milestone__c following Module 43's pattern exactly
  • Decide which trigger events this object actually needs to handle
  • Keep the domain layer focused purely on dispatch, not business logic

Prerequisites: "Design the Architecture"

The handler, following Module 43's exact shape

public with sharing class MilestoneTriggerHandler {
    public void beforeUpdate(List<Milestone__c> newMilestones, Map<Id, Milestone__c> oldMap) {
        MilestoneStatusService.validateStatusTransition(newMilestones, oldMap);
    }

    public void afterUpdate(List<Milestone__c> newMilestones, Map<Id, Milestone__c> oldMap) {
        MilestoneStatusService.recalculateProjectHealth(newMilestones, oldMap);
    }
}
trigger MilestoneTrigger on Milestone__c (before update, after update) {
    MilestoneTriggerHandler handler = new MilestoneTriggerHandler();
    if (Trigger.isBefore && Trigger.isUpdate) handler.beforeUpdate(Trigger.new, Trigger.oldMap);
    if (Trigger.isAfter && Trigger.isUpdate) handler.afterUpdate(Trigger.new, Trigger.oldMap);
}

Identical structure to Module 43\'s TransactionTriggerHandler — the handler only routes; MilestoneStatusService (built in Lesson 5) holds the actual business logic.

Deciding which events actually matter

Milestone__c only needs before update (to validate a status transition, like preventing a jump straight from "Not Started" to "Complete") and after update (to recalculate the parent Project\'s health once a milestone changes) — no insert-time logic is needed yet, since a newly created Milestone starts in a default state requiring no special handling. Deciding this deliberately, rather than handling every possible event out of habit, keeps the handler focused.

Exercise

As a comment, explain why MilestoneTriggerHandler has no logic of its own beyond calling MilestoneStatusService methods.

Show hint

Think back to Module 43's separation of concerns between trigger mechanics and business logic.

APEX

Build the Domain Layer Quiz

1. Why does MilestoneTriggerHandler only implement beforeUpdate and afterUpdate, not beforeInsert or afterInsert?

Log in to submit the quiz and save your score.

My Notes

Log in to keep private notes on this lesson.

Questions about this lesson

No questions yet — be the first to ask.

Log in to ask a question about this lesson.

Summary

The domain layer for Milestone__c reuses Module 43's exact trigger-handler shape — a thin dispatcher that routes each trigger event to the appropriate service method, with zero business logic living in the handler itself.