When we talk about patterns in the context of OOP, we usually think about the Design Patterns. They are common solutions to recurring problems, so if you care about your code, you definitely should know at least some of them. But there is another important set of patterns in terms of programming. We call them Architectural Patterns and I think it’s worth to start from here, despite the fact that we much more often use, talk and implement the Design Patterns than the Architectural ones.
Architecture vs Design
In most scenarios, we think of Architectural Patterns just like we do about the Design Patterns, but we have to remember the most significant difference: Architectural Patterns have a much broader scope. The broader scope means bigger consequences, so be careful, because the system architecture is the most critical factor when we talk about the success of the project development.
There are dozens of Architectural Patterns and not all of them function at the same level of abstraction. Every single pattern is set out to solve a problem, but the problems differ from each other. We should not think of Architectural Patterns the way we think and talk about our application architecture itself. It’s quite common to have an application architecture composed of a number of patterns within a single project.
What is worth to remember about all the patterns in programming - they’re not a silver bullet that makes your project awesome. Choosing and using them wisely may help you develop a healthy system, but using patterns improperly produces extra complexity and can do more harm than good, especially when it comes to architecture. Whenever you consider implementing a pattern, never forget that they’re a starting point for you, not a final destination. It’s your job to adapt them to your project.
MVC, MVP, Layering, SOA, P2P, Microservices etc.
You’re probably quite familiar with terms like MVC, MVP, Layering, P2P, SOA, Microservices and the others. These all are Architectural Patterns*, but we will not be describing them here as there are lots of materials online you can find easily. We’ll take a look at just 2 of them we use most of the time in “our” web-development world.
Layering is an Architectural Pattern widely used in OOP. Just like the name suggests, layering helps you break apart a complicated system into layers, what comes with a number of important benefits:
- it’s easier to understand and work with a single layer
- layers can be used substantially in another project with similar requirements
- you can minimize dependencies (and thus system complexity) between layers
- layers are a good place for standardization in the project - you define how layers should operate
- a well-designed layer can be a base for whatever you want to put on it (e.g. TCP/IP is used by FTP, SSH, HTTP etc.)
As it is usually, layering comes with some downsides as well:
- it’s almost impossible to encapsulate all the things inside a layer, so from time to time, you may experience cascading changes.
- every layer typically needs some time to do something - this can harm performance.
- in complex systems, the hardest part is to decide what layers we need and what is the responsibility for each of them.
Fortunately, in most scenarios we’re facing in web development, the systems are quite simple (or at least start that way). In such cases we don’t need a complicated layering architecture, it’s often enough to stick to the famous 3 basic layers:
Presentation layer: deals with the things about how to handle the interaction between the user and the system. It shows the data to the user and interprets commands from the user upon the domain and data source layers.
Domain (business logic) layer: the central point of the system, working both with the stored data and the data from the presentation layer. It actually does everything you need to do for the domain you’re working with.
Data source layer: communicates with other systems (e.g. a database system) to provide the data to the system
Of course, three layers above are just the base so adding more of them is actually very common (e.g. a Service Layer).
MVC in Rails
If you don’t know what does the MVC stand for, please search for “Model View Controller” in Google and you’ll get millions of results, so I won’t be writing yet another article about that here. As we’re not talking about the technical aspect of patterns in programming, I want to take a look at MVC from a different perspective. I think MVC was a great choice when it comes to Rails architecture. This one** decision to use MVC helped a lot to get Rails where they are now, and in my opinion, it’s still a great place to start for many web applications. But when you start wondering whether the code belongs to the Model or Controller, it’s the sign that MVC is not enough and it’s time to consider restructuring your application. And it’s a perfect moment to try some other patterns.
Once its worth to know some patterns, bear in mind that both the Design Patterns and Architectural Patterns are not ready solutions for every project. It is a developer’s responsibility to play with them, combine ones with the others and try to make the best possible patterns set that does the right job in the context of the project.
* - there is much more, there are lots of them!!
** - of course, idea of Convention over Configuration and some other decisions were also important, but we’re talking about the patterns here ;-)