Extending Salesforce sObjects with Methods

Unlike classes in traditional programming languages such as Java or C#, Salesforce database objects (sObjects) cannot be extended with user-defined methods. As a result, object processing code is often scattered across triggers, Lightning actions, batch processes, and REST API calls, leading to fragmented and error-prone implementations.

This fragmentation can make maintaining complex processing logic both challenging and expensive. This post outlines a design pattern that circumvents Salesforce’s limitations, enabling cleaner code and easier maintenance.

The Ideal Code Structure

The lack of extensible sObjects in Salesforce prevents writing Apex code like this (using a custom Contract__c object as an example):

Contract__c contract  = [SELECT ...];

contract.start(...)
contract.renew(...);
contract.terminate(...);
 

In this scenario, methods would encapsulate the logic for each operation, such as contract renewal. As a result, triggers, Lightning actions and batch jobs would become much simpler.

An Alternative Approach

As mentioned earlier, Apex does not directly support extension methods; however, the following approach can help overcome sObject limitations:

  1. Determine methods for the object. It is a good practice to identify verbs that stakeholders use to describe it (e.g., when a contract is signed, the contract is renewed) and convert them into method names.
    Best PracticeDesign methods as if designing an API to manipulate the object.
  2. Create a static helper class with methods determined in #1 above with object as the first argument. This is exactly the same pattern as extension methods, e.g., in C#.
    Best Practice“Bulkify” methods (i.e., make them accept arrays rather than individual objects as arguments) to make them easily usable in Salesforce triggers.

    In that case, the equivalent of code above would look as:

    Contract__c contract = [SELECT ...];
    
    ContractHelper.start(contract, ...)
    ContractHelper.renew(contract, ...);
    ContractHelper.terminate(contract, ...);
    
  3. Unit test the helper class.
  4. Update your triggers, batch jobs, aura classes to use the helper class, so there is only one place for testing & implementation of the processing logic.
  5. If need be, expose helper class methods via REST as an external API (more information here). If you did a good job in #1, you should have all methods you’ll need for easy integration.
A diagram of the Salesforce sObject extension pattern.
Salesforce sObject extension pattern.

This approach can be seen as creating a microservice around a Salesforce object.

Handling Object Status Changes

Most useful objects have a state or status field. In the case of the contract object example shown above, it might look like this:

Draft → Signed → Terminated

Let’s consider the following business requirement:

if Contract Status changes to Signed, send an email to customer

A common initial implementation of this logic is to modify trigger code to detect the status change and send the email. However, this approach is an anti-pattern that often leads to unmanageable code and frequent administrative interventions (e.g., “Could you please change this status but temporarily disable the trigger so the email isn’t sent?”).

The correct way to handle state changes is to drive them through actions. For instance, in the scenario above, you can create a Sign action that calls a sign() method. This method encapsulates all the related logic (e.g., sending the email, saving logs, recalculating non-formula fields).

An example is illustrated in the screenshot below: Start, Complete, and Restart are actions that invoke corresponding helper methods:

A screenshot of example actions on a Salesforce object.

 

Conclusions

The pattern outlined in this post enables the extension of Salesforce sObjects with an API-like methods that are easily consumable via triggers, quick actions, batch jobs, and REST API classes.

Additional benefits include:

  • Clean, easy to maintain design.
  • Compact code with well-defined entry points.
  • Easily testability.

These advantages lead to lower development and maintenance costs.

Nextian has extensive experience in implementing complex Salesforce customizations with Apex and Lightning, helping our clients unlock the full potential of their Salesforce.

Contact us today to find out how we can help you!

    Thank you for contacting Nextian. Your request was successfully submitted, we will get back to you within two working days.

    BY INDUSTRY

    Cloud Infrastructure Providers

    Cloud Software Companies

    Managed Service Providers

    Communications Service Providers

    BY ROLE

    CEO / Owner

    CRO / VP Sales

    CFO / VP Finance

    COO / VP Operations

    CPO / VP Product

    CIO / VP IT

    Product Management

    Plan, launch and manage your product offerings throughout their entire lifecycle.

    CPQ & Sales

    Quickly create accurate quotes for complex products, subscriptions and add-ons

    Order Management

    Ensure faster, consistent order delivery with tasks, workflows and automation

    Service Management, Support & Monitoring

    Retain and upsell customers with comprehensive account intelligence, support, monitoring, analytics

    Customer Portal

    Empower your customers with 24/7 self-service, support and on-line ordering

    NEXTIAN PLATFORM

    Platform Overview

    Billing Integration

    Network Monitoring Integration

    Reporting & Analytics