Blesta 3.0: Designing A Modular System

October 5, 2011 | Posted by Cody

There are two prevailing factors that determine how well a software product can adapt, improve, and be extended without imploding in on itself. They are:

  1. Coupling, and
  2. Cohesion

Coupling represents how dependent a given module is on other modules within the system (I use the term “module” in this article in an abstract sense to describe an object or set of objects that are designed to accomplish some task). A loosely coupled module doesn’t rely or expose much of its inner workings to other modules. Conversely, a tightly coupled module relies heavily on other modules and may expose portions of its inner workings so that other modules may interact with it.

Version 3 of Blesta is built on top of an MVC (Model-View-Controller) framework, which, as the name suggests, separates control into three distinct areas. Building off of an MVC framework (in our case, minPHP) gives us the discipline needed to maintain a loosely coupled system. But it’s not without its challenges. For example, as I’ve mentioned in a previous article explaining data validation, error handling can be handled in a number of ways, but the best way is this through message passing. This allows the errors of a model to be accessed and interpreted without the controller having any direct knowledge of the model or how it works, and vice versa, thus maintaining a loosely coupled relationship.

Cohesion relates to how well the various functional elements of a module are related. High cohesion requires that the module be, in a sense, single-minded. In other words, a class may have high cohesion if all of its methods are closely related. Low cohesion means that a module attempts to accomplish too many tasks, or relates to multiple distinct sets of data.

When designing a modular system, we strive for high cohesion because it improves readability and comprehension of a particular module. If a module attempts too much it becomes bloated, disorganized, and difficult to maintain.

This works hand in hand with coupling. As each module becomes more refined it generally becomes more independent, or loosely coupled. A perfect example of this is the payment gateway system in version 3, which consists of four merchant gateway interfaces (Credit Card, ACH, off-site Credit Card, and off-site ACH). Each interface is designed to accomplish a distinct set of actions (high cohesion), and each payment gateway is thereby only associated with the rest of the system through the implemented interfaces (low coupling). This allows us to create a wide variety of payment gateways that can process credit cards only, or ACH payments only, or any other combination of interfaces without requiring any changes to any other parts of the system.