How to write highly scalable and maintainable code for Salesforce development?

When configuration limits in Salesforce are reached, features can be extended through code. Well-written code is scalable, able to grow as the business evolves.

But the reality is that in many systems, legacy code is so complex that it is difficult to update it without risk. When the code is long and difficult to read, the ill effects of updates are often unpredictable. How to solve this problem?

01

How to write maintainable code?

No developer writes bad code on purpose, most code works fine to begin with. But the code is usually always changing. As changes are made, the generated code can become patchy. As more changes are added to the same codebase, methods and classes start to grow longer, which can only end up making changes difficult.

In order to write maintainable code, you can follow some basic rules: first, keep methods and classes small and modular; second, standardize the names of classes and methods to make the code more readable.

02

Keep methods and classes small

Breaking down any problem into smaller chunks makes it easier to work with, and the same goes for code. The first thing to do to keep your code manageable is to keep your methods and classes small. For example, if you have a method called updateContact, don’t let it both update the opportunity and send an email to the contact. Ensure that a method does only one thing.

If a method only does one thing, and it has 100% test coverage, unless the business logic encapsulated by the method changes, it will never need to be changed again. Think of them as little building blocks to create and bookmark that will always work as expected.

The following is an example of a long method:

public void handleBeforeUpdate(List<Sale__C> newSales, Map<Id,Sale__C> oldMap){
           
           // update audit fields
           for(Sale__c s : newSales) {
               if(oldMap != null){ // this is an update
                   
                   Sale__c oldRec = oldMap.get(s.id);
                   
                   if( oldRec. Audit_Completed__c == true & amp; & amp; s. Audit_Completed__c == false) {
                       boolean canAudit = false;
                       Id currentProfileId = userinfo. getProfileId();
                       
                       Profile curUserProfile = [Select Id,Name from Profile where Id = :currentProfileId LIMIT 1];
                       
                       for(String pname: allowedProfileNames){
                           if(curUserProfile.name == pname){
                               canAudit = true;
                           }
                       }
                       if(!canAudit){
                           s.addError('Audit Box cannot be unchecked once checked');
                       }
                   }
                   else if(s.Audit_Completed__c == true){
                       s.Audit_Completed_Time__c = system.now();
                       s.Auditor__c = UserInfo.getUserId();
                   }
                   else { // an admin is unchecking the checkbox
                       system.debug('an admin is unchecking the sales audit checkbox');
                       s.Audit_Completed_Time__c = null;
                       s. Auditor__c = null;
                   }
               } // insert - there is no oldmap
               else if(s.Audit_Completed__c == true){
                   s.Audit_Completed_Time__c = system.now();
                   s.Auditor__c = UserInfo.getUserId();
               }
           }
           
           for(Sale__c s : newSales) {
               
               String category;
               if(s.Amount__c < 1000){
                   s.Sale_Category__c = 'Small';
               }
               else if( s.Amount__c < 10000){
                   s.Sale_Category__c = 'Medium';
               }
               else if(s.Amount__c < 50000){
                   s.Sale_Category__c = 'Large';
               }
               else if(s.Amount__c > 50000){
                   s.Sale_Category__c = 'Extra Large';
               }
           }
       }){<!-- -->

This style of coding can get complicated, and it can get complicated very quickly. Here’s an example that makes the code more readable, can you spot the difference?

public void handleBeforeUpdate(List<Sale__C> newSales, Map<Id,Sale__C> oldMap){
   addErrorForUnauthorizedAuditChanges(newSales, oldMap);
   handleAuditFieldChanges(newSales, oldMap);
   setSaleCategory(newSales);
}
 
 
private void addErrorForUnauthorizedAuditChanges(List<Sale__C> newSales, Map<Id,Sale__C> oldMap){
   // error code here
}
 
 
private void handleAuditFieldChanges(List<Sale__C> newSales, Map<Id,Sale__C> oldMap){
   // audit field change code here
}
 
 
private void setSaleCategory(List<Sale__c> newSales){
   // sale category code here
}

03

Keep the inner workings of the class private

A lot of code exposes all methods, which makes part of the job very easy. Especially when writing test classes for code coverage, just call all methods from the test class to get the code. But is this the right thing to do?

Imagine that there is a class that validates addresses. It calls three other methods with basic logic to ensure the validity of the street, city, and zip code. These methods are public. This class was noticed by other developers in the organization who needed to validate zip codes, so they decided to use that method in their code.

public class AddressValidator{
 
 
   public Boolean isAddressValid(String address){
       return (isStreetValid() & amp; & amp;
                isCityValid() & &
                isPostalCodeValid)
   }
 
 
   public Boolean isStreetValid(){
       // validation code
   }
 
 
   public Boolean isCityValid(){
       // validation code
   }
 
 
   public Boolean isPostalCodeValid(){
       // validation code
   }
}

Later, the business decided to purchase a service to more accurately verify addresses. Therefore, these three methods can be removed and replaced with calls to the service. However, the isPostalCodeValid() method cannot be removed because it is being used elsewhere. If these methods are private in the first place, they will not be exposed and will not cause code dependencies.

public class AddressValidator{
 
 
   public Boolean isAddressValid(String address){
       return PostalAddressValidationService. validateAddress();
   }
 
 
}

Therefore, only expose what needs to be seen from outside the class you write. Making everything public creates unintended dependencies. Any inner workings should be private so that changes can be made as needed without breaking anything outside the class.

04

Naming of standardized methods

If the naming of the method is standardized, the code does not need too many comments. Code also becomes easier to read and understand when you read it over time. For example:

In conclusion, in order to keep the code maintainable, developers should strive to keep methods and classes small. This means that methods should only do one thing at a time, and method names should reflect what actually happens in the method. Use the public modifier to display only what is necessary and make everything else private.

Author: Freeman Tribe

Get it for free: Salesforce study materials, high-paying positions, exam strategy, $140 exam coupon

This article is welcome to reprint, but without the author’s consent, this statement must be retained, and the original text link should be given in an obvious place on the article page

If the content of the article is helpful to you, please like it~

The knowledge points of the article match the official knowledge files, and you can further learn relevant knowledge Java skill treeHomepageOverview 109804 people are studying systematically