0

My Queueable Apex class worked fine before but after discovering Apex PMD ruleset, found that using >4 parameters in any method or constructor is not best practice. I tried searching up answers where one advice is to pass an entire record. However that approach doesn't work for me as I have more than one object I need to pass into the parameter.

I also tried reading the Q&A to this but the examples given in the solutions are un-readable to me.

I'm still quite new to Wrapper classes so please example as simple as you can. I tried my best to write a simple use case of wrapper class example below:

public class UpdateOpportunityToClosedWonQueueable implements Queueable, Database.AllowsCallouts {

    private Set<Id> opptyIdSet {get; set;} //first time set be processed or retry list to be processed
    private Set<Id> remainingIdSet = new Set<Id>();
    private Set<Id> opptySendToExternalIdSet = new Set<Id>();
    private Integer retryAttempt; // count of retry attempts
    Credentials__c  apiCredentials = new Credentials__c (); 
    private String countryCode {get;set;}
    
    public UpdateOpportunityToClosedWonQueueable(RetryParamWrapper retryParams){

        this.opptyIdSet = retryParams.opptyIdSet;
        this.remainingIdSet = retryParams.remainingIdSet;
        this.opptySendToExternalIdSet = retryParams.opptySendToExternalIdSet;
        this.retryAttempt = retryParams.retryAttempt;
        this.apiCredentials = retryParams.apiCredentials;
        this.countryCode = retryParams.countryCode;
    }

    public void execute(QueueableContext context){
        ...
        if (!Test.isRunningTest()) {
            //System.enqueueJob(new UpdateOpportunityToClosedWonQueueable(new RetryParamWrapper{
             //   retryParams.opptyIdSet,retryParams.sfiOpptyIdSet,retryParams.retryAttempt.apiCredentials,retryParams.countryCode}));
        }
        ...
    }        

    public Class RetryParamWrapper{
        public Set<Id> opptyIdSet;
        public Set<Id> remainingIdSet;
        public Set<Id> opptySendToExternalIdSet;
        public Integer retryAttempt;
        public Credentials__c apiCredentials;
        public String countryCode;
    }
}
  • Is the Wrapper class in the constructor that I wrote called correctly?
  • How do I call the constructor method on the enqueueJob? or how do I call the constructor in general? (Commented out in the code)

1 Answer 1

0

You can always treat your Queueable/Batchable/Schedulable class as the wrapper itself. In other words, in your code, this would be an acceptable alternative:

public void execute(QueueableContext context){
    // ...
    if (!Test.isRunningTest()) {
        System.enqueueJob(this);
    }
    // ...
}

If you're trying to avoid long parameter lists, the builder pattern from the question you've linked is often acceptable. I won't repeat that code here; go try reading it again.

Finally, you can always just populate the data one property at a time, as in:

public void execute(QueueableContext context){
    // ...
    if (!Test.isRunningTest()) {
        RetryParamWrapper wrapper = new RetryParamWrapper();
        wrapper.opptyIdSet = opptyIdSet;
        wrapper.remainingIdSet = remainingIdSet;
        // ... etc
        System.enqueueJob(new UpdateOpportunityToClosedWonQueueable(wrapper));
    }
    // ...
}

As you might think about this, it seems wasteful, because you're just doing and undoing the same operation all at once, and I'd agree with this assessment. Simply use your current instance (this) to start the next job. The example above is simply about what you'd want to do if you wanted to pass a wrapper from one class to another.

You must log in to answer this question.

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