WCM Core Components Sling Models Interfaces Design

While reviewing Adobe’s WCM Core components you may realize that the Sling model all have JAVA interfaces. Why do they follow this design pattern, and what benefits does it help to the overall design of their Sling models? In this article, I will share my understanding of why Adobe designed its Sling models like this.

The simple answer is backward compatibility and versioning for implementing v1,v2,v3… of the AEM Core Components.

In this article, we will target the https://github.com/adobe/aem-core-wcm-components/blob/main/bundles/core/src/main/java/com/adobe/cq/wcm/core/components/models/Title.java Sling Model interface, to see what Adobe’s design pattern is with the Sling Models.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@ConsumerType
public interface Title extends Component {
    String PN_DESIGN_DEFAULT_TYPE = "type";
    String PN_TITLE_LINK_DISABLED = "linkDisabled";
    default String getText() {
        return null;
    }
    default String getType() {
        return null;
    }
    @Nullable
    default Link getLink() {
        return null;
    }
    @Deprecated
    default String getLinkURL() {
        return null;
    }
    default boolean isLinkDisabled() {
        return false;
    }
}

Why Interfaces

One of the fundamental concepts of Java is Java Interface. Java Interface is a fundamental component of all programming languages and are extensively used in software engineering design patterns. The majority of frameworks strongly rely on the interface.

Java’s interfaces offer a means of achieving abstraction. Additionally, the contract for the subclasses to implement is defined by the Java interface. Let’s imagine, for instance, that we wish to make a creation using a variety of animals. Here, we can design the interface for the Animal object type and specify all the methods that it will support. For the sake of simplicity, we can limit ourselves to just two methods: walk(), which will make our animal walk, and talk(), which will make the animal talk.


Benefits of Java Interfaces

  • It is wise to code in terms of interfaces since implementation classes cannot remove the methods we are using. Interfaces offer a contract for all implementation classes.
  • Interfaces are a great place to start when defining Types and building top-level hierarchies in our programs.
  • Since a Java class can implement many interfaces, it’s usually preferable to utilize an interface as a superclass.

Adobe’s Approach

From what I can see, Adobe’s approach to their Sling Model designs is highly prioritized on backward compatibility. When version 1 of the WCM Core Title component was released, the Title interface was created for it. The sling model backend is implemented via com.adobe.cq.wcm.core.components.internal.models.v1.TitleImpl. The Sightly code is tightly coupled with the getters() for the backend Sling Models.

As we move on in time, Adobe identifies bad performance their com.adobe.cq.wcm.core.components.internal.models.v1.TitleImpl Sling Model backend logic, so they introduced the v3 Title (skipped a version). For v3 implementation of the Title interface, they introduced com.adobe.cq.wcm.core.components.internal.models.v3.TitleImpl, and it extends from v1 Title and implements the Title interface.

Expected, customers are supposed to benefit from the performance improvements from the version upgrades, so AEM developers would update their organization’s proxied components to reference to the WCM Core Component’s latest version For the sake of the example, WCM Core Title Component, the latest Adobe backend Sling Model version updates are required to implement the Title interface, getters are still available, so this guarantees that our proxied components are still working as expected.

After updating our proxied components to reference the latest WCM Core Components, our components will benefit from the latest performance fixes. Simply to utilize the latest v3 of the title component’s performance enhanced BE execution, change your proxy component’s sling:resourceSuperType to “core/wcm/components/title/v3/title”, and it would take effect. Now v3 of the title component, “core/wcm/components/title/v3/title”, will be referenced to the correct backend Sling Model implementation, and invokes the correct version. The Sling Model is mapped via resourceType = TitleImpl.RESOURCE_TYPE, and that’s how the proxied component will select the correct v3 implementation of the title component, and execute the backend to produce the data model back to the front end (via Sightly);

Example of Adobe’s WCM Core Component’s v3 Title Component’s implementation. Take a look at line 15, where the implementation of the title v3 is registered with the resourceType. This component’s implementation also extends from com.adobe.cq.wcm.core.components.internal.models.v1.TitleImpl and implements Title interface.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
package com.adobe.cq.wcm.core.components.internal.models.v3;

import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.models.annotations.Exporter;
import org.apache.sling.models.annotations.Model;

import com.adobe.cq.export.json.ComponentExporter;
import com.adobe.cq.export.json.ExporterConstants;
import com.adobe.cq.wcm.core.components.commons.link.Link;
import com.adobe.cq.wcm.core.components.models.Title;
import com.fasterxml.jackson.annotation.JsonIgnore;

@Model(adaptables = SlingHttpServletRequest.class,
        adapters = {Title.class, ComponentExporter.class},
        resourceType = TitleImpl.RESOURCE_TYPE)
@Exporter(name = ExporterConstants.SLING_MODEL_EXPORTER_NAME,
        extensions = ExporterConstants.SLING_MODEL_EXTENSION)
public class TitleImpl extends com.adobe.cq.wcm.core.components.internal.models.v1.TitleImpl implements Title {

    protected static final String RESOURCE_TYPE = "core/wcm/components/title/v3/title";

    @Override
    public Link getLink() {
        return link.isValid() ? link : null;
    }

    @Override
    @JsonIgnore
    @Deprecated
    public String getLinkURL() {
        return super.getLinkURL();
    }

}

Adobe’s Github: https://github.com/adobe/aem-core-wcm-components/blob/main/bundles/core/src/main/java/com/adobe/cq/wcm/core/components/internal/models/v3/TitleImpl.java


Lesson here

The lesson here is, if you are planning to create your own versioned components for your organization, creating interfaces for Sling Models is actually a great design pattern. It allows your organization to be future proof, to fix performance issues, and extend new concepts. Most of all, the latest versions will still be backwards compatible.


Looking for Help? Or need a mentor?

If you need help to super drive your AEM career road map, you can hire me for a one-hour session on codementor.io; We can work together on a price works just for you. https://www.codementor.io/@briankasingli. I'd be happy to help you along your way to becoming a high-quality AEM full-stack engineer.

Was this post helpful?

Hello, I am an enthusiastic Adobe Community Advisor and a seasoned Lead AEM Developer. I am currently serving as an AEM Technical Lead at MNPDigital.ca, bringing over a decade of extensive web engineering experience and more than eight years of practical AEM experience to the table. My goal is to give back to the AEM Full Stack Development community by sharing my wealth of knowledge with others. You can connect with me on LinkedIn.

4 thoughts on “WCM Core Components Sling Models Interfaces Design

Leave a Reply

Your email address will not be published. Required fields are marked *

Back To Top