2

I'm trying to understand the SoC and Service, Domain, etc. layers. The following is confusing me:

global with sharing class ActivityServices {

    global static void createActivities(Set<Id> recordIds, Schema.SObjectType objectType) {
        service().createActivities(recordIds, objectType);

        // QUESTION HERE -- why not just this instead?
        Activity_Service_Impl actImpl = new Activity_Service_Impl();
        actImpl.createActivities(recordIds, objectType);
    }

    //This gets an instance of the Activity_Service_Impl class from our Application class
    private static Activity_Service_Interface service() {
        return (Activity_Service_Interface) Application.service.newInstance(Activity_Service_Interface.class);
    }
}

In the line where the question is indicated. Why do we ask the application factory to give us an instance of Activity_Service_Impl when (I believe) we would always get an instance of Activity_Service_Impl regardless of input parameters?

Or does this example not fully demonstrate the benefits that I cannot see?

1 Answer 1

0

For a single-use instance, you're right, it would hardly make sense to do this. But, we're interested in code reuse. Consider this:

global static void createActivities(Set<Id> recordIds, Schema.SObjectType objectType) {
    service().createActivities(recordIds, objectType);
}
global static void updateActivities(Set<Id> recordIds, Schema.SObjectType objectType) {
    service().updateActivities(recordIds, objectType);
}
global static void deleteActivities(Set<Id> recordIds, Schema.SObjectType objectType) {
    service().deleteActivities(recordIds, objectType);
}

Versus:

global static void createActivities(Set<Id> recordIds, Schema.SObjectType objectType) {
    Activity_Service_Impl actImpl = new Activity_Service_Impl();
    actImpl.createActivities(recordIds, objectType);
}
global static void updateActivities(Set<Id> recordIds, Schema.SObjectType objectType) {
    Activity_Service_Impl actImpl = new Activity_Service_Impl();
    actImpl.updateActivities(recordIds, objectType);
}
global static void deleteActivities(Set<Id> recordIds, Schema.SObjectType objectType) {
    Activity_Service_Impl actImpl = new Activity_Service_Impl();
    actImpl.deleteActivities(recordIds, objectType);
}

Yes, you can do that, but you're doubling the amount of code you have to write. And, you have to do it every time you add a new method. A factory method such as service() means less typing for you, and less maintenance. Also, if you later have to refactor the interface, you now only need to change one line of code instead of dozens or hundreds.

2
  • Thank you sfdcfox. Although this is a separate but related question, I'll ask it here: why not just put the contents of Activity_Service_Impl.createActivities() right into the ActivityServices class? Is it only so that we'll have an interface class (Activity_Service_Interface) which neatly outlines all actions that ActivityServices undertakes? May 23, 2021 at 9:14
  • I've found Andrew Fawcett explaining that issue saying that the service method has become simply an entry point, or like a coupon to use that service's actual implementation of that method so as to keep the outside world (callers of the static method) oblivious to changes/edits in the static method, should there be any. Have I understood that correctly? May 23, 2021 at 10:02

You must log in to answer this question.

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