There exists a lot of design patterns, architectures and design concepts that can be applied to technical aspects of implementing a product. For eg., we have MVC architecture that isolates the view, controller and model of the application. We have a factory pattern that defines how to create objects and so on. Yet, these all limit themselves to the technical aspects of the product, while there exists no definite pre-defined architecture or patterns to design and build “business functions”. The Plug and Play architecture I want to describe in this article is a “Functional architecture”, that defines a pattern to design the business functionality to get the most out of it.
Modular architecture is a design technique where functionality of a program is separated into independent, interchangeable modules, such that each module contains everything necessary to execute one aspect of the desired functionality. Typically, in modular architecture, separation is done based on technical aspects. For eg., a module is created for database interaction, another is created for logging and so on. The advantage of a modular architecture is that you can easily replace or add components without affecting the rest of the application. The modules clearly define the interfaces that are used to interact with the module and these are tied at compile time to other modules.
What if we could extend this architecture to “business functionality” rather than just limiting it to technical aspects of a product. We already design “Business functionality” in a modular manner. But, we do not consciously look at it as modules with clear-cut interfaces for inputs and outputs.
Defining the Plug and Play architecture
The Plug and Play architecture extends the techniques of modular architecture to business functions. For eg., a module can be created to encompass all functions related to Order, while another can be created to encompass all functions related to Quote. I will call these independent modules implementing business functions as Flows.
An application, in this architecture, is a “collection of flows working together”. The same advantage of modular architecture applies here, i.e., you can replace, add or remove flows without affecting the rest of the application. An added advantage to extending modules to business functions, is that the flows can be combined in different paths to get different business functionality.
Further, extending this definition to be able to add, remove or replace modules at “runtime” rather than tying them together at compile time gives us the flexibility to customize the application at runtime without “in-built flags and if clauses”. The beauty of this extension of the architecture is that “it gives us the flexibility to create a set of loosely coupled flows that can be bound together at runtime as opposed to coding one tightly integrated application that is rigid and not malleable”.
To further see how this architecture works, let us consider a set of loosely coupled flows coded as per the diagram:
There are 5 flows coded and deployed. Each flow exposes an output and accepts a set of inputs.
For eg., the “Product Listing” flow encapsulates the following business functions
- Create products manually by admin
- Import products by admin
- Provide services to view, search and list products
- Expose an output, “Product” data that can be linked to other flows
Another eg., is the Cart Flow. This encapsulates the following business functions
- Create a new cart
- Add Items to the cart
- Check out the cart
- Expose an output, “Cart” data that can be linked to other flows
- Accept an input, “Cart Item” that can be linked to the output from other flows
We can connect the output “Product” data from “Product Listing” flow to the “Cart Item” input of the cart flow. This is not tightly coupled at compile time and is left as an open gate or an input for the cart flow. At runtime the gate is closed or left open as required by the customer.
From the diagram we see that we have 5 gates that can be closed. Leading us to create different applications at runtime by closing the correct gates. For eg., we can just enable “Product Listing” for a customer which provides just the basic features of product listing. Gates 4 and 6 can be closed to create an application with the features
- Create, list products
- Add products to a cart
- Send an enquiry for the products added to the cart
In another variation instead of gates 4 and 6, gate 7 can be closed. The application now has the features
- Create, list products
- Send an enquiry for single products
By plugging the “inputs” of flows with different “outputs” from other flows, varied applications can be created. This is called a plug and play architecture. SMART is implemented in this architecture to give a highly flexible container to build Saas products.
Need for plug and play architecture
When a product is exposed as a multi-tenanted Saas product, it cannot be created with “One size fits all” tenet. To break this tenet we need a flexible, customizable runtime environment where features can be varied based on a customer need without affecting other customers serviced by the same application. The plug and play architecture provides this flexibility to the Saas.