1

At my new company they have a lot of Salesforce code all in one project. Are there ways to break the a Salesforce project into smaller components (like how java has libraries).

With everything in one project it just feels daunting to even know where to begin and I feel like any new members I bring on would be in the same position.

4
  • Yes, you can break code down into many classes. Other than that, your question is a bit too broad to answer effectively here, as there are a great many strategies on how to do so.
    – Adrian Larson
    Commented Aug 10, 2021 at 22:52
  • yeah, there are a ton of classes, I was thinking of breaking it down into multiple groups that are functionally distinct (ex: separating the opportunity lifecycle code into a different group than code around case management, along with another group for common functionality useful to everyone.
    – J. Larson
    Commented Aug 10, 2021 at 23:01
  • Strongly recommend working through some trailheads to get a better sense for what you are looking for. There are also some good Apex Design Patterns, though I recommend you not adopt their naming convention of using Impl.
    – Adrian Larson
    Commented Aug 10, 2021 at 23:11
  • Thanks. For the documentation, that's what I was hoping for. I'll read through that!
    – J. Larson
    Commented Aug 11, 2021 at 17:10

2 Answers 2

1

If your main concern is cleaning up your domain layer, you can take a look at Apex Enterprise Patterns: Domain & Selector Layers . I have a slightly different convention but any move to a cleaner separation of domain layer will likely help. My preferred pattern looks more like the below, though the idea is much the same.

public trigger Opportunity on Opportunity (before insert)
{
    OpportunityTriggerHandler handle = new OpportunityTriggerHandle(trigger.new, trigger.oldMap);
    switch on trigger.operationType
    {
        when BEFORE_INSERT { handle.beforeInsert(); }
        // other operations as needed
    }
}

public class OpportunityTriggerHandler
{
    @TestVisible static Boolean bypassTrigger = false;
    
    final List<Opportunity> newRecords;
    final Map<Id, Opportunity> oldMap;
    public OpportunityTriggerHandler(List<Opportunity> newRecords, Map<Id, Opportunity> oldMap)
    {
        this.newRecords = newRecords;
        this.oldMap = oldMap;
    }
    
    public void beforeInsert()
    {
        if (bypassTrigger) return;
        
        SpecificOpportunitySubservice.doSomeOperation(
            OpportunityFilters.meetsSomeCriteria(newRecords)
        );
    }
}

Basically, your trigger handler will handle which operations are bound to which events, and what filters to apply. But that class shouldn't tell you how to do anything, really, and we generally don't test it directly at all. It can be very thoroughly tested by testing the trigger itself, and any further testing on just the handler would be redundant.

Also, since you will be breaking logic down into separate filter and service methods, those smaller chunks should be where you do you most rigorous testing. The more you can avoid database interaction, the better efficiency you will get in protecting your code base, hitting as many cyclomatic nodes as possible with the least test run time.

Probably my biggest disagreement with the Apex Design Pattern of Domain Layer is that I still put validations in their own service. I do not feel they share an overlapping concern with the Handler, which is our version of the Domain Layer.

It's also worth reading up about the Service Layer Pattern and thinking about the idea of Separation Of Concerns as you approach the task of breaking your codebase into more manageable chunks.

2
  • N.B. fflib was updated recently to separate trigger handling from other domain functions - see github.com/apex-enterprise-patterns/fflib-apex-common/pull/273; doc hasn't caught up yet
    – cropredy
    Commented Aug 11, 2021 at 19:11
  • That discussion highlights one reason I tend to avoid fflib. Decisions can be compromised because the library is "bound to our signifiant customer base".
    – Adrian Larson
    Commented Aug 11, 2021 at 19:20
0

The Salesforce DX documentation covers Multiple Package Directories in detail. The name is a bit misleading (multiple package...), however, you can treat it as a multiple feature directory project and so on...

You did not specify if you are using SFDX, so, if you aren't, it would be worth taking a look and adopting it.

2
  • this sounds perfect. I will look into it! Thank you so much.
    – J. Larson
    Commented Aug 11, 2021 at 17:13
  • let me know if you run into any hiccups, cheers!
    – glls
    Commented Aug 11, 2021 at 18:04

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .