Using Model-View-Controller
Lessons from the Assembly Line
If you had a car factory, you would not want to replace every assembly machine every time, right? You would first want to design at least some reusable components, and after that, keep assembly lines in the same order. The people who assemble the chassis should build the chassis for all the vehicles, and the engine lines should overlap, too. Building an app that you may ever wish to update, maintain, or expand should be handled with similar foresight, so I recommend that you consider designing apps using the Model-View-Controller (MVC) paradigm.
Model-View-Controller is a popular, simple design pattern that will allow you to make more than one model or year of car, so to speak. To understand how to have a happy, humming factory, allow me to break down the three components of MVC:
The Model
The model is the model of the data: how it looks, how it may be added or accessed. Typically you have a structure or schema in your models folder. Mongoose for MongoDB is an excellent example of using Models for the data: build a Schema for a Car or for a SiteUser, for example, and the user can only enter or retrieve data in the format you expect, and thus your Car or SiteUser data must conform to the desired structure.
The View
So what is a view, really? It is a vehicle (wink, wink) to present the data in a manner that will be meaningful for the user. More than that, it gives a structure to compartmentalize different elements that go on the page, or the actual file structure that the user will see.
The Controller
The model and the view need to pass messages. When the user requests data, the controller talks to the model and tells the model which data it needs to input or to retrieve. The model then works with the database and then sends either the desired output data, or the resolution of the input request to the controller. The controller can then turn around and tell the appropriate view in the "views" folder the result, whether it's an error, a completed input request, or the result of a database fetch.
What it Looks Like Altogether
For your typical fullstack application, you will need your main logic script (which will often be app.js if you're using Node or Express), your configuration file or folder (with .env information, for instance), your models folder for different schema you'll use, and you'll also need a robust views folder with the components for rendering the user's view inside. You'll also need a routes or controller folder that contains the logic to talk to each piece.
But... Why All the Extra Files, Folders, and Work?
At this point, you may be thinking, "Wait! I have a small app with only a few pages. Why would I want to break it into so many different pieces and have to work with so many files?" Separation of concerns is well served by the MVC paradigm, in that it allows for modular development. One team may work on the view, for instance, with limited input from the model and controller team. Moreover, maintaining and upgrading various different components is going to be dramatically easier.
Because its structures are decoupled, it can be much faster to bring an app to market, as well as simpler -- yes, simpler! -- to debug and maintain, upgrade, or change elements. If you ever want or need to change the underlying database product, by using the MVC architecture, you can "hot swap" the model out without losing uptime, as well as need to make fewer adjustments to keep the rest of your program intact. One day you may decide to use a different tool to separate components of your pages. With MVC, you can sweep away the code for viewing the pages in Handlebars, and instead plug it into EJS or Django.
I hope you'll consider using the Model-View-Controller paradigm for your next app. Your future self and future teammates are going to thank you for it!
Top comments (0)