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
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
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:
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
<h1 id="title">Hello, </h1>
user.css
h1 {
padding-left: 1rem;
padding-right: 1rem;
padding-top: 1rem;
padding-bottom: 1rem;
}
user.js
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 (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)", 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!
Top comments (42)
Parabéns, gostei do artigo.
Que artigo massa primo!!! Segue firme que está ótimo!!!
Parabéns! Muito bom artigo!
Parabéns pelo artigo, primo!
Continue escrevendo conteúdos fodas como esse <3
Mandou bem demais mano!!
Continua o bom trabalho!
the goat
Muito bom! Parabéns!
Parabens pelo artigo primo <3
parabens !
Parabéns pelo artigo meu bom, excelente artigo!