Separação de Conceitos e Localidade de Comportamento - Um guia imparcial
Tags: softwareengineering, braziliandevs, webdev
Published: 2023-08-21 16:13:46

Você agora é um pedreiro. Isso mesmo, o melhor da cidade ainda. Um cliente te pediu para construir uma casa; já comprou as ferramentas, o cimento e os tijolos, o engenheiro civil até já fez a planta. Agora basta você pegar todos esses recursos, organizá-los e utilizá-los de alguma forma a ter o produto final: a casa. Como você vai fazer isso?

Talvez você não consiga resolver esse problema; Quem sabe, se eu trocar um pouquinho a história... Pronto! agora você é um engenheiro de software que precisa construir um produto. A IDE tá aberta, o café tá na mesa, a daily é daqui 5 minutos. Até os juniors estão prontos pra trabalhar como um sênior pelo preço de um estagiário!! Como você vai juntar seus recursos e produzir esse Software?

## Glossário

- SoC / SdC : Separation of Concerns / Separação de Conceitos
- LoB / LdC: Locality of Behavior / Localidade de Comportamento
- EdS: Engenharia de Software

## Balas de prata e favoritismo

Um dos maiores problemas da EdS é o famoso favoritismo/elitismo. Existe um errôneo ideal de estar sempre do lado certo. Isso não acontece só na EdS, mas é muito prevalecente nessa área, devido a enorme quantidade de escolhas. Não é à toa que não temos um dia de paz na _bolha tech_.

Venho antes de tudo declarar que este artigo é uma apresentação dos conceitos e aplicações de SoC e LoB. Não estou colocando nenhum acima do outro. Existem momentos certos para um, e para o outro. Ser Engenheiro é também ser crítico e entendedor. Já diziam os sábios:

> Depende.

## O que são estes palavrões?

SoC e LoB são princípios que procuram descrever como uma codebase é organizada, em quesitos como árvore de arquivos, nomenclatura, alinhamento, posição de código, etc. Não se preocupe, irei entrar em mais detalhes a seguir. Trazendo como exemplo o problema do pedreiro no começo, a forma como os tijolos serão colocados, o tamanho dos cômodos, etc. são prováveis princípios seguidos durante toda a construção da casa.

### Separação de Conceitos

A Separação de Conceitos trata da modularização dos aspectos de um Software, de forma a prover coesão ao separar blocos de código baseado em seu aspecto e função primordial. você cuida de X? Então vai pra pasta dos Xs. Você cuida de Y, vai pra pasta do Ys, etc.

> In another mood we may ask ourselves whether, and if so: why, the program is desirable. But nothing is gained—on the contrary!—by tackling these various aspects simultaneously. It is what I sometimes have called "the separation of concerns", which, even if not perfectly possible, is yet the only available technique for effective ordering of one's thoughts, that I know of. This is what I mean by "focusing one's attention upon some aspect": it does not mean ignoring the other aspects, it is just doing justice to the fact that from this aspect's point of view, the other is irrelevant. It is being one- and multiple-track minded simultaneously. - [Edsger W. Dijkstra](https://www.cs.utexas.edu/users/EWD/transcriptions/EWD04xx/EWD447.html)

O exemplo mais canônico é a forma como as aplicações Web são criadas (vanilla): por meio de 3 tipos de arquivos diferentes: HTML, CSS e Javascript. Dessa maneira, existe uma separação de aspectos: O HTML fica com a declaração dos elementos da DOM, o CSS com a estilização desses elementos, e por fim o Javascript complementa a interação entre esses próprios elementos e o usuário.

### Localidade de comportamento

A localidade de comportamento trata da organização dos módulos de uma codebase com base na proximidade do comportamento de uma seção de código, ao invés do aspecto em si.

> “The primary feature for easy maintenance is locality: Locality is that characteristic of source code that enables a programmer to understand that source by looking at only a small portion of it.” - [Richard Gabriel](https://www.dreamsongs.com/Files/PatternsOfSoftware.pdf)

O LoB tem suas origens nessa citação de Richard Gabriel, do qual o princípio em si é formulado da seguinte maneira:

> O comportamento de um pedaço de código deve ser o mais óbvio possível olhando apenas para esse pedaço de código.

## Qual a diferença na prática?

Um exemplo prático que posso dar são as recentes Frameworks Javascript e CSS. Nesse caso, vou estar falando de React e Tailwind. Observe o seguinte arquivo jsx:

```javascript
function formatName(user) {
  return user.firstName + ' ' + user.lastName;
}

const user = {
  firstName: 'Josué',
  lastName: 'Teodoro'
};

const element = (
  <h1 class="px-4 py-2">
    Hello, {formatName(user)}!
  </h1>
);
```

Talvez você nunca tenha usado React ou Tailwind, mas se você tem a base de lógica da programação, não seria nenhum pouco complexo entender o que essa porção de código está fazendo.

Agora imagine se estivéssemos utilizando uma abordagem de SoC, a formação desse mesmo bloco seria separada entre os seguintes arquivos:

**user.html**
```html
<h1 id="title">Hello, </h1>
```

**user.css**
```css
h1 {
	padding-left: 1rem;
	padding-right: 1rem;
	padding-top: 1rem;
	padding-bottom: 1rem;
}
```

**user.js**
```javascript
function formatName(user) {
  return user.firstName + ' ' + user.lastName;
}

const user = {
  firstName: 'Josué',
  lastName: 'Teodoro'
};

var title = document.getElementById("title")
title.onload = sayHello()

function sayHello() {
	title.innerText = "Hello, " + formatName(user)
}
```

## Qual devo usar?

Existem alguns pontos que você pode tomar em conta na hora de decidir qual princípio tomar a frente no desenvolvimento da aplicação. Vale lembrar que estes não são os únicos, e que é necessário que você dê uma pesquisada antes de colocar a mão na massa.

### Ferramentas

> Se seu cliente te pediu uma casa de madeira, pra que comprar cimento?

Muitas das ferramentas disponíveis para nós desenvolvedores foram criadas com um ideal em mente. Java por exemplo, é uma linguagem de programação Orientada a Objeto. Não faria sentido programar Orientado a Procedures na mesma língua.

Da mesma maneira, se o seu time está acostumado com um conjunto de ferramentas orientados a SoC (como por exemplo uma Framework MVC), continue do jeito que está, a não ser que seja necessário mudanças.

### Complexidade desnecessária

> Por quê usar 8 tábuas pequenas para fazer uma porta, se você pode usar 1 tábua grande?

Outro princípio importantíssimo na EdS é o [DRY](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself#:~:text=%22Don't%20repeat%20yourself%22,redundancy%20in%20the%20first%20place.) (Don't Repeat Yourself), onde a repetição de informação deve ser reduzida e reposta por abstrações, removendo redundâncias. Um dos embargos do DRY, entretanto, é a __Over Abstraction__: existe um medo da repetição; dezenas de interfaces, Singletons, Abstract Factories, etc. se espalham pela codebase, criando complexidade que dificultam mais do que ajudam.

Uma das minhas talks preferidas é a ["Simple Made Easy - Rich Hickey (2011)"](https://www.youtube.com/watch?v=SxdOUGdseq4), do criador do Clojure. Nessa talk Hickey explica a necessidade da simplicidade (não facilidade) nas ferramentas e softwares atuais. Recomendo muito que assista, mas em suma:

A cada linha de código, arquivo, etc. que é criado, a complexidade da codebase aumenta. Nós, humanos, não somos máquinas capazes de armazenar milhares de informações ao mesmo tempo; no máximo 3 coisas e olha lá. Sendo o ato de programar entender sequencialmente os passos de uma aplicação, as abstrações são uma informação a mais a levar em consideração.

Um código simples é aquele que tanto um ser humano quanto a máquina conseguem entender. Ter que fazer malabarismo mental toda vez que tiver que ler uma base de código é custoso não somente pro time, mas para a própria empresa.

Tendo isto em mente, e o seu produto final, responda a si mesmo: Eu e meu time, como seres humanos, temos capacidade para manter esses diversos conceitos dispersos em um bloco de código na mente?

## Conclusão

Como disse anteriormente, não existe uma bala de prata na EdS. É seu trabalho, como Engenheiro e/ou Desenvolvedor, estabelecer o caminho a ser tomado para chegar no produto final. Os princípios apresentados aqui são uma base que podem criar uma fundação; nem toda casa é de cimento, e nem toda é de madeira.

Obrigado!

[Josué Teodoro Moreira](https://j0suetm.com).