Smart Layers is a product suite that currently includes 6 different UI widgets (including share, follow, recommended content). Although each widget contains unique functionality, there are many similarities between the widgets.
For example, all widgets create and append DOM elements, listen to events, support user-specified options, utilize CSS3 show/hide animations, etc. Once we put our code architect hats on, we realized that:
We needed an inheritance model that could handle both unique widget functionality and common logic without code duplication.
Instance properties are properties that are scoped to a particular instance object and are not propagated to other instances (unless you go out of your way to change that). Let’s look at an example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
In the previous example, each instance object contains one instance property (name). Since each instance object’s properties are not propagated to each other, they are not aware of each other’s changes.
All prototype properties are kept in sync and visible to each instance.
Let’s demonstrate prototypes by expanding upon our previous code example:
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
For Smart Layers, every widget instance reuses the same object as it’s prototype. This both simplifies the codebase and makes it easy to make changes that need to be propagated to all widgets.
Since every widget is created in a similar way, we needed a design pattern to take care of the instance creation process. Smart Layers uses the Factory pattern as a generic interface for creating instance objects.
Here’s a high-level look:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
The previous example shows a
factory() method that can be called by passing a string name and an object literal containing all of the desired instance properties.
Let’s look at a basic example of the module pattern:
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
This example demonstrates that all local variables, declared using the
var keyword, are only accessible within the declaring function or other nested functions.
In our example, a person’s first name, last name, and occupation are all local variables. An object, that includes the
firstName property, is then returned inside of our constructor function. Since the
firstName local variable is the only variable returned, it is the only property that can be retrieved from a different scope.
The module pattern is an example of a closure, since a local property is kept alive and can be referenced inside of a different scope.
Here’s a more practical example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
This demonstrates the technique that Smart Layers uses to expose public API methods. All methods that start with an underscore are assumed to be private and are not returned as a public method.