Shortcut to seniority

Home
Go to main page

Section level: Junior
A journey into the programming realm

Section level: Intermediate
The point of no return

Section level: Senior
Leaping into the unknown
Go to main page
A journey into the programming realm
The point of no return
Leaping into the unknown
Architectural patterns refer to general solutions used in the architecture of the entire software.
Layered architecture pattern is used to divide work packages into layers, each of the layers having a specific role and responsibility within the application.
This pattern fully uses the separation of concerns principle among the components.
Presentation layer, for example, is only concerned with displaying the information on the screen, while the business layer focuses on performing business logic against the data (calculate values, aggregate data) before passing it to the presentation layer.
With the layered pattern, the calls between layers flow downwards.
For example, if the user pressed a button on a webpage (on the GUI – presentation layer), the code that is executed will call further the underlying layer (Application Layer, business layer etc).
We can also use abstractions, so that layers talk with each other through interfaces, and we can easily swap between implementations of the same layers (Especially for presentation layer which can change between how it’s displayed on PC or on mobile, etc.).
Layers must be designed in a way that each of them perform a specific task, which overcome the cost required to pass the call from one layer to another. If we have layers that simply delegate and do not perform any logic, we should think again about our design of the application.
The MVC pattern is commonly used for developing user interfaces, and it decouples the logic into three major components, allowing for efficient code reuse and parallel development.
The components are the following:
Model: The model is the central component of the MVC pattern. It directly manages the data and the logic of the application. Model is directly connected to both the View and the Controller.
View: The view is in charge of what is visible to the user. By decoupling the view from the model, we can choose how to display the data, without being interested in where that data came from.
Controller: The controller is the one that accepts the input from the user and converts it into a command for the model or view.
Let’s understand this pattern with some code. First, we code the model.
class HumanModel {
private:
string name;
int age;
public:
void setName(string new_name) {
name = new_name;
}
void setAge(int new_age) {
age = new_age;
}
string getName() { return name; }
int getAge() { return age; }
};
After that, we implement the view and in the end, the controller.
class HumanView {
public:
void print(string name, int age) {
cout << "Name: " << name;
cout << "Age: " << age;
}
};
class HumanController {
private:
HumanModel model;
HumanView view;
public:
HumanController(HumanModel _model, HumanView _view) {
model = _model;
view = _view;
}
// model part
void setName(string new_name) {
model.setName(new_name);
}
void setAge(int new_age) {
model.setAge(new_age);
}
string getName() {
return model.getName();
}
int getAge() {
return model.getAge();
}
// view part
void updateView() {
view.print(model.getName(), model.getAge());
}
};
The demo will simply create the classes, update some model data, and then refresh the view.
void mvc_demo() {
HumanModel model;
model.setName("Robert");
model.setAge(27);
HumanView view;
HumanController controller(model, view);
controller.updateView();
controller.setAge(28);
controller.updateView();
};
Event-driven architecture is an architectural pattern that is relying on events (create, send, detect and consume them).
An example of such architecture can be seen on the web, when some action is performed after a button is pressed.
This is possible by registering (subscribing) the action to the button press. When the button is clicked, the event is created and sent through the Event bus, which will send it further to all the subscribed objects.
What happens when an event occurs? We’re programmers, so we handle it.
Similar to logic, we can describe the event and the handlers as follows:
if event p occurs, then execute q.
There are three main topics:
The events are sent to the event loop, and the event loop dispatches each event to their respective event handler.
As a rule of thumb:
The events are the heart of the event-driven architecture. The event contains two properties: type, and data (not always necessary, we can use events just so we know to do something specific, but we might not want / need to use any information related with the event).
The type of the event determines which handlers will handle that event. The data is used by the handler.
Handlers are a specific way to deal with an event. They do just that – handle some specific event.
The event loop process all the events, as they arrive, by dispatching them to their handlers.
The code should contain a queue of events so they can be processed as they arrive. When an event is raised, we will add it into the queue and execute them one by one, based on order of arrival (unless we have some prioritization going on).
In the event loop, we process the events by removing them from the queue and send them to their appropiate handlers.
The microkernel architecture pattern is an architectural pattern that is divided into two components:
The code system needs to know about which plugin modules are available and how to reach them.
Before talking about the microservices architecture, we need to understand what is the monolith architecture. The monolith term refers to the traditional design in which the whole thing is developed in one piece – the user interface, the logic, the database, and so on.
The monolith tends to become difficult to manage over time, for some reasons:
Both microservices and monolithic architectures have an interface, functions, and a database. However, microservices separates the major functions into independent high cohesive services.
This separation allows the service components to be individually developed, tested, and deployed.
Because it’s a distributed architecture, all the involved components are fully decoupled from each other (and probably deployed on multiple computers) and they communicate through a remote access protocol.
There are a few things to consider when you decide to switch to a microservices architecture. I say this, because you may not need to use a microservices architecture after all. You need to analyze the pros and cons and make a decision whether turning your application into a microservices one is feasible or not.
The main challence is that people try to switch their entire system all at once. The change to a microservices architecture should be an iterative approach.
A solution would be to keep the code in place, but any new addition can be developed as a microservice.
Another solution would be to take out some areas of the code and transform that into a microservice.
The team also needs to be trained for such change, so they can get familiar with the technologies and change their mindset from a single application to one consisted of microservices.
Another focus should be on the API used by two or more services. In case you want to share data between microservices – don’t. And in the end, you should make sure you don’t break the application into too many small pieces.
Every class should have a single responsibility, and that responsibility should be entirely encapsulated by the class.