A Salesforce Lightning Component Design Pattern for Optimum Code Reuse

As the author of Salesforce.com’s official instructor-led course for Lightning Developers – Dev601: Programming Lightning Components as well as the Trailhead Lightning Component Framework Superbadge, I’ve spent a lot of time developing hands-on exercises that illustrate the mechanics of custom app development on the Salesforce.com platform.

What that course doesn’t officially cover, however, are design patterns for creating components for optimum re-use and application maintainability. Therefore I decided to author this blog article to act as additional reading materials for that course. Note that this post does assume that you are already quite familiar with Salesforce Lightning Component development.

Before we can discuss a pattern strategy, let’s define a couple of terms.

Tightly Coupled Components

A Tightly Coupled App is one where all of the components are nested within a container-component.In effect, you can treat the parent component as a de facto controller, handling any Lightning component events thrown by its members (typically by setting public properties and calling public methods of components other than the one that threw the event).

For instance, consider a scenario where a user chooses from a select-box of beers as illustrated by Figure 1. The BeerSelector component throws a component event containing the beer selection back to FriendsWithBeer.cmp. FriendsWithBeer.cmp then takes the beer selection and programmatically sets a beerId attribute in c:FWB_BeerContacts which triggers and APEX request, displaying a list of all contacts who like that particular beer.

app_org1

Figure 1: Tightly Coupled App Wireframe for our sample app, Friends with Beer

Loosely Coupled Components

Loosely Coupled components, illustrated by Figure 2, are assembled into an application with Lightning App Builder and therefore have no direct parent component other than a Lightning App Builder template. The only way these components can therefore communicate with each other is via Lightning Application events. In this scenario, encapsulation of functionality is an absolute-must as business users have the freedom to include or exclude any installed Lightning App Builder-enabled components in your Salesforce org.

app_org2

Figure 2: Loosely Coupled App Wireframe

Why Bother?

It’s a fair question. If you’ve tracked the progress of Lightning App Builder over the last few release cycles, it’s pretty clear that Salesforce is expending a lot of effort in this particular area of the framework. Having components that can be surfaced by both developers (as strongly-coupled apps), yet retain the flexibility to be deployed in App Builder, helps future-proof your code. It would not surprise me if within a couple of years, the vast majority of custom lightning applications are assembled using App Builder by both developers and power-users/admins.

Bringing it all together

I therefore suggest that you organize your Lightning applications around three separate tiers, as illustrated in Figure 3:

  • The Functional Tier are comprised of utility components that do all the actual output within your application. I’m talking about Lightning Base Components, utility components such as custom grids/tables, custom buttons, and whatnot.
  • The Declarative Application Tier are components that invoke Apex methods, encapsulate business logic, and pass data to the functional tier components for output to the user. These components also fire and listen to component events. A strongly-coupled Lightning application would consist of only components from the Declarative Application Tier and the Functional Tier.
  • The Orchestration Tier invokes components from the Declarative Application Tier, re-firing custom Lightning Component events as custom Lightning Application events. They serve as a wrapper for the Declarative Tier components that you want to surface in Lightning App Builder. They also wrap components in lightning:card, as this is the preferred methodology (in Winter 18) to ensure that your component is not transparent against the new Winter 18 Lightning custom background.
app_org3

Figure 3: Code Organization Pattern

Naming Conventions

You’ve probably inferred from the slides above that I’ve settled on a few naming conventions:

  • Functional component names start with a lower-case letter and are camel-cased.
  • Declarative Application Tier components start with applicationName_ComponentName. Since the name of my sample app is Friends With Beer, I’ve abbreviated the app name to FWB. Therefore, FWB_BeerSelector, FWB_BeerContacts, and so forth.
  • Orchestration Tier components are prefixed with applicationName_App_ComponentName
  • Component event names are prefixed with applicationName_evt_ComponentEventName
  • Application event names are prefixed with applicationName_aEvt_ApplicationEventName

Feel free to critique these choices and concepts in the comments section below. In (hopefully) about 30 days, you’ll be able to view my detailed explanations of these concepts (including a code walkthrough) as a Pluralsight video play-by-play with my fellow Lighting Component instructor Don Robins!

Need immediate help? For Lightning Component consulting, development, and best-practices code-reviews please send an email to info@figleaf.com. My company, Fig Leaf Software is a certified Service-Disabled Veteran-Owned Small Business located in Washington, D.C.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s