0

I have a wrapper class.

public class wrapperClass{
String s;
Date d;
Integer i;
Id id;
}

There are different operations for which certain fields are required on these wrapper object. Example 1. for functionality 1 => only Date d and String s is required , 2. for functionality 2=> only d,i and Id are required fields to be available. As the class grows and new functionality comes in I would need to check for the required fields based on the new functionality.

So I decided to create a reusable method to validate required fields:

 public List<WrapperClass> validate( List<WrapperClass> wrapperClass) {
    List<WrapperClass> validRecords = new List<WrapperClass>();

    for (WrapperClass obj : WrapperClass) {
      if (checkRequiredFields(obj)) {
        // its valid record
validRecords.add(obj);
      } else {
        //  not valid
      }
    }
    return validRecords;
  }

  private Boolean checkRequiredFields(
    WrapperClass obj
  ) {
    if (
      obj.s != null &&
      obj.d != null
    ) {
      return true;
    } else {
      return false;
    }
  }

My thought is to send the required fields to be checked as a Set to validate() method and keep things more generic so that it can be reused everywhere. Like below. I pass reqFields Set which would consist of which fields should be checked for !=null.

  public List<WrapperClass> validate( List<WrapperClass> wrapperClass, Set<String> reqFields) {
}

However I am facing a challenge on how I could use this reqFields to check against the wrapperClass Obj. I thought of using a Map where String would have reqFields and Object will have values from wrapperClass Obj. However it will fail in runtime.

String key = 's';
Map<key,obj.key>

So that I can use this Map to check and make things more generic.

1

While there could be multiple possible ways to achieve this, but if I had to write this, I would have used classic abstraction approach here utilizing Interfaces.

In your scenario, you can have a base implementation of the WrapperClass as:

public interface WrapperClass {
    // declare all the common attributes here

    // add an abstract method which will be implemented by implementing classes
    Boolean isRequiredFieldsPopulated();
}

Now for a specific functionality, you can have specific classes implementing the interface and then providing their version of required fields validation. As an example for your Functionality 1, it could be as:

public class Functionality1Wrapper implements WrapperClass {
    // all your functionality specific fields goes here

    public Boolean isRequiredFieldsPopulated() {
        if(d != null && s != null) {
            return true;
        } else {
            return false;
        }
    }
}

Though this leads you to maintain different wrapper classes for specific functionality, but this also provides you with more control on how you want to manage and maintain your functionality specific code in a cleaner and modular approach. As you introduce new functionality, you can easily scale your approach without breaking anything existing (less regression).

3
  • Also, you can use multiple interfaces in a single class, allowing for modular adaptations. – sfdcfox Apr 24 '20 at 16:07
  • This makes sense. What my though process was to have a utility method that does this. You jus pass a list and requirefields that needs to be validated and the method says if it passes the validation. Also wanted to avoid some redundant code of looping checking each field. Is that a valid thought? – SfdcBat Apr 24 '20 at 16:12
  • 1
    @SfdcBat In all other cases, you will need to utilize say a switch or if-else blocks to validate the fields based on the functionality. Unfortunately there is no way (at least I am not aware of) that you can dynamically pull a field's value from a class based on the name of the field provided as input string. – Jayant Das Apr 24 '20 at 16:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.