[SalesForce] Use an intermediary Custom Object in Trigger handler class

I have a rather simple Trigger. When fired it determines its own type and calls an appropriate function in Trigger handler class.

trigger Project_Trigger on Acme_Project__c (before insert, after insert, before update) {
    if (Trigger.isBefore) {
        if (Trigger.isInsert) {  
            ProjectHandler.projectBeforeInsert(Trigger.new);
        }
        ...
    }
    ...
}

Trigger handler class takes Trigger.old/Trigger.new and performs all required logic.

public class ProjectHandler {
    public static void projectBeforeInsert(List<Acme_Project__c> newProjects) {
        ...
    }
}

I would like to make the handler class work for many different Custom Objects, not only for Acme_Projects__c. In fact I already have those Custom Objects and I can just clone the class and find/replace 'Acme' with, for instance, 'Some_Other_Client', but that seems too repetitive.

My idea is to create an intermediary Custom Object, like Clipboard_Project__c, and use it to populate with Trigger.old/Trigger.new values, perform class handler methods on instances of that Custom Object, and then return everything back to trigger to do final DML operations…

In the Trigger –

Clipboard_Project__c[] newProjects;

for (Acme_Project__c p : Trigger.new) {
    Clipboard_Project__c one = new Clipboard_Project__c(
        Id = p.Id,
        Field_1__c = p.Field_1__c,
        ...);
    newProjects.add(one);
}

ProjectHandler.projectBeforeInsert(newProjects);

//some code that puts newProjects back into Trigger.new

delete(newProjects);

Is this a viable approach? How do I put newProject contents back into Trigger.new (as far as I understand that's the only way to make Custom Object instances update)?

Best Answer

Apex has support for generic sObjects. You can do pretty much anything with a generic sobject that you could do with a specific sObject type (get/set fields, dml operations, etc.) So you could write your generic handler as follows:

public class myTriggerHandler {
    public static void BeforeInsertHandler(List<Sobject> newRecords) {
        ...
    }
}

There is no reason to pass anything back to the triggers as you can perform everything in the trigger handler. The best practice is to have a simple trigger that delegates all the actual work to a trigger handler. If you have slightly different logic for the different types of sObjects:

public class myTriggerHelper {
    public static void doGenericLogic(List<Sobject> newRecords) {
        ...
    }
}

public class ProjectHandler {
    public static void projectBeforeInsert(List<Acme_Project__c> newProjects) {
        myTriggerHelper.doGenericLogic(newProjects);
        ...
    }
}
Related Topic