Contents |
MVC is about loose-coupling, and Modular Programming takes that concept to the extreme. A modular application can dynamically load and unload modules at runtime, completely separate applications in their own right, which interact with the main application and other modules to perform some set of tasks.
In this article you will presented with a different approach to Web development, one that doesn’t focus on a design pattern, instead, it focuses on a programming paradigm known as Modular programming.
Modularity is an important design principle, its goal is to design systems so that modules can be optimized independently of other modules, so that failure of one module does not cause other modules to fail, and in general to make it easier to understand, design and manage complex interdependent systems.
One of the advantages of modularity, where modules are self contained, is that you can replace or add any module without affecting the rest of the system.
Some frameworks allow you to re-organize your directory structure, but because they were not created with a Modular architecture in mind, they fail to provide most of the advantages that this architecture has to offer.
Example: Traditional MVC implementation
admin/
controllers/
models/
views/
app/
controllers/
ContactUsController.php
NewsController.php
models/
ContactUsModel.php
NewsModel.php
views/
contactus/
index.html
news/
Using an MVC framework forces you to divide and organize your code according to the framework conventions. Presentation code goes to the view, data manipulation code goes to the model, and the request manipulation logic goes to the controller.
This is all theory, of course, and even though it’s not written anywhere that you should place 200 html files inside a folder called “views”, some systems encourage you to do it. And because everyone is doing it, you think that this is the right thing to do, right? Wrong.
Modular programming is the breaking down of a website into parts that are of more manageable size and have a well-defined purpose. Modules should fit intuitively together into a system. In any development environment, modular programming is how larger, more complicated websites are constructed. The first step is to break the task into its basic parts, which leads to defining intermediate steps, and ultimately devising a comprehensive and efficient solution. Modules can be developed individually, validated, and then used throughout an organization, promoting teamwork, efficiency, and innovation. The advantages of modularity are obvious. Code only needs to be written once, which allows quick modifications. It provides a framework that dictates how subsequent programming should be incorporated. Modularity fits an environment where several programmers share work.
A module is a self-contained component of the system, which has a well-defined interface to the other components and can have its own MVC implementation. For example:
modules/
home/
controllers/
models/
views/
contact-us/
controllers/
ContactUsController.php
models/
views/
A module can also contain configuration data, user defined routes, dependencies information and language translations:
modules/
contact-us/
controllers/
i18n/
en/
models/
properties/
ContactUsConfig.php
ContactUsRoutes.php
ContactUsDependencies.php
views/
Composability refers to a collections of modules that can be coordinated and assembled to produce new systems. Pushing this concept a little bit further, we could create a ModuleCoordinator component that acts as a connector between modules. This will allow us to assemble and coordinate new modular subsystems.
In an MVC framework that implements a modular architecture, separation of concerns (SoC) is the process of breaking a module into distinct features that overlap in functionality as little as possible. A concern is any piece of interest in a module. Based on this concept we could separate the functionality of a module into two groups, front-end and back-end:
modules/
contact-us/
controllers/
backend/
ContactUsBackendController.php
frontend/
ContactUsFrontendController.php
i18n/
en/
models/
properties/
views/
backend/
frontend/
The router of the framework will then determine which module, controller, and action of that controller should receive the request. For example:
Front-end Action Controller
The first segment of the URL path maps to the module’s front-end controller. The second segment is usually called “action” and maps to a method within that controller.
URI: http://www.example.com/contact-us/support/product/iphone
Module: contact-us
Controller: ContactUsFrontendController.php
Method: supportAction()
Params: array('product', 'iphone')
Back-end Action Controller
URI: http://cms.example.com/contact-us/view-departments/10
Module: contact-us
Controller: ContactUsBackendController.php
Method: viewDepartmentsAction()
Params: array('view', 10)
Based on this architecture, you can create a Content Management System (CMS) that allows users to install, activate and assign modules to nodes (or pages). For example:
Page Module URL Action ----------------------------------------------------------------- - Home home home edit | delete - News news latest-news edit | delete - Products products products edit | delete + Sales products on-sales edit | delete + Shops map where-to-find-us edit | delete - Contact Us contact-us contact edit | delete
In the example above, we created a vertical module structure, where the module “maps” depends on the module “products” and inherits its properties. They have a parent/child relationship. However, if you want to minimize dependencies between modules, you can create a flat module structure.
Systems like Joomla and other Content Management Systems have adopted similar architectures, this confirms that a Modular Architecture is a good approach to Web development and RAD.
A system architecture should not only be based on a design pattern, such as MVC, it should also be based on different programming paradigms.
In a typical website, a design is implemented so that it meets a set of requirements at the time of development. Often, after a website is delivered, the user will want added functionality, or different users will require custom functionality based on specific needs. In order to accommodate these situations without a complete re-write, a framework that allows for future additions of modules without breaking the existing code base needs to be implemented.
In theory, putting the models in the models/ directory, the controllers in the controllers/ directory and the views in the views/ directory makes perfect sense, but in practice, it doesn’t. Remember, designing a flexible and scalable system architecture is way beyond your directory structure.