What is separation of Concerns (SoC)?

I noticed that we don't have a question on this topic.

Separation of concerns( SoC), also known as:

  • separation of interests
  • separation of concerns
  • separation of responsibilities
  • separation of concepts

I would like to know:

  • what is it?
  • How does it work?
  • How to reach it?

Optionally, a good material to read about (Dijkstra, etc.)

Author: Piovezan, 2019-10-20

2 answers

Introduction

To understand what separation of responsibilities means, let's first look at what is the first principle of S. O. L. I. D: acronym Responsibility Principle (SRP), or principle of Single Responsibility.

Principle of single liability

This principle says that, in a very simple way, a class or module has a single responsibility, or we can say that, from what the software does, such a module or class is responsible for only "part".

For example, in a product query system, a class that does only query the product data in the database , is adherent to the SRP.

It is important to understand that, this principle aims to make it easier to maintain and understand the system, since a code has a single responsibility, it is easier to know where it needs to be changed to do a certain maintenance or new functionality.

Separation of Responsibilities

Separation of responsibilities is a principle / standard of software architecture that has the same principle as SRP, but with a slightly more macro view, not at the class level, but at the package, assembly, etc.level, which aims to separate the application into "parts" that are responsible for distinct responsibilities.

For example, if such a class from the example above (let's call it Repositorioproduct for ease), and that class is in a package that contains another class (let's call it Repositorioclient ), which is responsible for querying customer data, it seems reasonable to say that they, within their unit functions, have similar functions, which we could say are that of obtaining information from the database.

Now imagine that we have another class that formats the product data to be displayed to the user, and let's call it Product Format. From the point of view of the SRP, this class it is adherent, it only does one thing, but if it is in the same package, assembly, etc, as the Class Repositorioproduct , it is not adherent to the separation of responsibilities, because one class has a responsibility at the level of data repository, and or the other at the level of presentation to the user, so they must be separated.

How to get it? Examples

This separation can be done logically or physically, and is usually implemented when creating layers in the code.
We have the classic presentation/business/repository model, the well-known model in 3 layers , where every package, project, assembly has a responsibility.
Within these components we can have infinite classes with common subjects, making responsibility well defined.

insert the description of the image here

This separation can also be done logically by grouping the components within the same package but from a way be easy to identify.
This happens with projects that use the MVC standard (Model, View, Controller ), which in many projects, despite the separation of responsibilities, can have the components in the same package, but logically separated, in folders, namespaces , etc.

Below is an example of the logical separation of responsibilities of a project using the MVC pattern

insert the description of the image here

Benefits

This has several benefits, we can think for example:

  • Ease of understanding the components: if separation is well implemented and we need to change the way something is displayed to the user, we can only change some class of the presentation layer;

  • Help in estimating maintenance or new features: it's easier to look at just one part of the code and estimate effort if we know exactly where it will be needed change;

  • Decoupling: if each layer has its responsibility well separated, it becomes easier to decouple each of them. Here are two interesting situations: we can change and publish only one package of code instead of all the code if the change is in one layer. You can still override an entire layer without affecting the rest of the code depending on how it is implemented. It could for example replace the database without having to change the others layers, or even the presentation layer, changing from a Desktop application to a Web for example.

 4
Author: Ricardo Pontual, 2020-06-11 14:45:34

Well, any pattern originates from some recurring problem that had been found a standard approach to its solution. So I believe that even without knowing you already use some level of SoC without even knowing. And when I say level understood, "applied granularity level", where the lowest level of granularity could generate multiple Code Smells and the highest level could be considered an Overengineering. That is why it is up to those involved in the project to define which is the best level to apply and monitor if the same is being followed. Also remembering that SoC is not only for backend development but in the design of the architecture as a whole, and goes from the definition of the architecture to the definition of an entity. Let's go to an example in a lower possible level of granularity in a web application, which a long time ago was common practice in ASP, PHP, Java and the subsequent improvements were thought aimed at SoC.

Level 0 - No SoC - all together and mixed

HTML/Javascript / CSS / backend code on same page html / JSP / php/asp; Variables, business rules, bank access (connection opening, bank queries). positive: Did you know that everything that referred to a screen for example would be in the screen file negative: No entities, classes of services, nothing, having to find business rules defined within a , lawless earth, Hell On Earth.

Level 1 - MVC-layered Division logic

View-everything that represented the presentation of data, such as a page or a report, was still seen back end code between HTML, CSS and Javascript Controller-definition of the page flow, you still see Bank code in these classes, utility classes for connection Model-bank entities, DTOs, ViewModels, VOs, etc. positive: a little more organized negative: in this model the use of a business rule was still seen in all layers

Level 2-BO / DAO

In this model there was the introduction of business classes (Business Object - BO). Large data access object (DAO) classes) Bank connection utility Classes, Log, date parse, etc.. positive: the business rules were separate from the MVC, only being used when necessary, better code reuse. negative: classes did not have a "single responsibility", i.e., any part of the system could be responsible for the increase of a class.

Level 3-Services/Repositories

Better separation of business rules and data access. Each service / repository represents the business rules and data access definition of a screen, feature, or entity. From here you already see a lot the use of DI (Denpendency Injection). S. O. L. I. D. in high, cohesive classes, cohesive methods, several cohesive. positive: a definition best of Single Responsibility, simplified maintenance, each class grows based only on what it was created. negative: increase in the number of classes, more work Pro GCs if it is necessary to use Di (Denpendency Injection) to control the live cycle of classes.

Level 4-physical layer separation

Physical separation between responsibly "unique" layers (or at least should be unique). Each layer would be a project, assembly, dll, jar, etc.. connected to each other. Ex: Web, Test, Bussiness, DAL (Data Access Layer) Ex2: Web, Services, Repositories, Domain, Core positive: is no longer a monolith. Small projects that can be updated independently depending on the situation, simplified maintenance. negative: care must be taken to maintain the sanitation of projects, keep them cohesive, versioning control.

Level 5-API, Web Services-front End Back End

In this mode, you could have a Web application, a Mobile One, using the same API. Use of SOAP, REST, messaging, and other distributed system resources. Here agent already speaks of Isolate of Concern, isolated applications integrated with each other, to design a product. It must be respect interface contracts for integration to remain cohesive. positive: each in its Square, no one messes with what should not mess, less code to keep, it is more easy to find which part of the system needs more attention. negative: basically we are dealing with a distributed application, that is, to form a single system, if it is necessary several applications, distinct, with distinct versions, distinct deployments, maybe even teams, if not done right, it can generate headache.

Level 6-Microservices

A greater segregation of a system, involving even bank segregation. Each microservice can be independent or not. Division of a single system, taking into account the load (has many accesses, is heavier, traffics more data, critical) or domain(referring to a module). Each microservices has its responsibility, its reason to exist, and grows according to its own needs. Cloud, DevOps; positive: each microservice could be maintained by a small team, keeping a contract on its interfaces the microservice is easy to maintain, easier to test, can be built in independent language / bank, making it easier to optimize. negative: although the microservice is easy to maintain, the application made on microservices is extremely difficult to maintain without DevOps, making it necessary to maintain the resources in an orchestrator, Cloud.

Level 7-Servless

Instead of segregating by domain, why not segregate by function? Each servless service corrects the smallest executable part of an application. This is the smallest responsibility maintained to this day, use with caution, in prone situations. A solution can be a monolith and have a servless feature. If used correctly, it can have a huge savings on certain application activities. There are other aspects of this architecture, several discussions involving it, but I will leave aside to maintain brevity. positive: easy to mjanter or code, smaller scope. negative: may incur excessive cost if done incorrectly, deploy difficulty, slowness to rise if the application is cold, difficulty.

At any of these levels it is possible to do something functional and maintainable, in the same way that something unsustainable can be done. And overall it will depend on how its application is.

Make an application in 10, 20 layers? The system will never grow, why separate into layers? A unique feature of your system is separated into 10 classes of services? Have the need to use Microservices? Is He Servless? Are you prepared to manage this?

 2
Author: EJSpawn, 2019-10-21 14:58:01