Skip to content

Instantly share code, notes, and snippets.

@lucasconstantino
Last active January 18, 2017 19:10
Show Gist options
  • Save lucasconstantino/795ab879fd0733646c503bf6fc30e930 to your computer and use it in GitHub Desktop.
Save lucasconstantino/795ab879fd0733646c503bf6fc30e930 to your computer and use it in GitHub Desktop.
Arquitetura Fractal
Títulos
1. Arquitetura Fractal - Um Ensaio Usando Webpack e React
2. Um Ensaio sobre Arquitetura Fractal usando Webpack e React
Aplicações de menor porte são normalmente organizadas de modo a separar os arquivos por *natureza*; componentes, [contêineres](https://css-tricks.com/learning-react-container-components/), rotas, etc. O resultado é uma aplicação com uma estrutura parecida a esta:
```
components/
Header.js
HomePage.js
Footer.js
Post.js
PostList.js
PostPage.js
User.js
UserProfile.js
UserAvatar.js
containers/
App.js
Post.js
User.js
routes/
index.js
post.js
user.js
router.js
index.js
```
Essa estrutura, porém, não é escalável e certamente em pouco tempo você começará a ter dezenas de arquivos em cada uma dessas pastas, pulando entre pastas para trabalhar em uma funcionalidade específica do sistema.
Existem diversas alternativas de arquitetura; cada uma será a melhor opção para um tipo de projeto. Mas uma arquitetura que me costuma sempre funcionar, tanto nos casos pequenos quanto nos grandes, é a arquitetura fractal.
## O que raios é um fractal?
Comumente usado em outras áreas da ciência, [*fractal*](http://www.dicionarioinformal.com.br/fractal/) é o termo usado para descrever uma "forma que mantém suas características físicas quando repartida em partes menores, embora possa cada parte possuir valores diferentes". Algumas árvores são exemplo simples de fractal: a forma de uma árvore - com uma única raiz, galhos que se separam, e assim por diante - é a mesma forma, praticamente, de um de seus galhos quando estudado em isolamento. De fato, a natureza é repleta desses exemplos, quando paramos para analisar. Até mesmo um brócolis é um exemplo perfeito desse tipo de estrutura:
![Brócolis Romanesco](https://www.fourmilab.ch/images/Romanesco/images/Lcr3.jpg)
O importante é perceber que, em uma estrutura fractal, toda parte tem as mesmas propriedades do todo, a mesma forma, e é um "todo" em potencial.
**Obs.:** ó raios, raios também são fractais! :)
## E o que é um software fractal?
Bom, uma aplicação que utilize uma arquitetura fractal é, em suma, uma aplicação composta de sub-aplicações, e assim recursivamente até onde for necessário. Toda aplicação ou sub-aplicação precisa de um ponto de entrada comum e previsível, e no caso de aplicações em React (e que utilizem react-router) esse ponto pode facilmente ser o roteamento.
> Para seguir nesse caminho, é importante que você esteja confortável não só com o react-router, mas com o formato de declaração de [objetos de rota](https://github.com/ReactTraining/react-router/blob/master/docs/API.md#plainroute), em comparação à declaração de rotas através do componente `Route` e afins. O primeiro é facilmente modularizável, permitindo que rotas residam em arquivos separados.
## Um blog fractal
Um blog feito em React e seguindo a estrutura fractal, apesar de talvez não ser o exemplo de aplicação mais interessante para esse tipo de arquitetura por sua simplicidade, poderia ser organizado da seguinte forma:
```
routes/
blog/
index.js <-- blog related router
components/
Header.js
HomePage.js
Footer.js
containers/
App.js
routes/
posts/
index.js <-- post related router
components/
Post.js
PostList.js
PostPage.js
containers/
Post.js
users/
index.js <-- user related router
components/
User.js
UserProfile.js
UserAvatar.js
containers/
User.js
index.js <-- app bootstrap file
```
Repare que na raiz do projeto temos apenas o `index.js` - provavelmente utilizado pelo Webpack como entrypoint único da aplicação e responsável pelo bootstrap, pela inicialização do React, pela inicialização do router, do redux, etc. - e uma pasta *routes*. Essa pasta contém apenas uma subpasta (por hora): *blog*. É a raiz da nossa aplicação, da nossa lógica de negócio.
O módulo *blog* - ou essa aplicação, e aqui os dois significados se confundem - contém um `index.js` também. Segue um exemplo do que poderia ser o conteúdo desse arquivo:
```js
import App from './containers/App'
import HomePage from './components/HomePage'
import posts from './routes/posts'
import users from './routes/users'
export default {
path: '/',
component: App,
indexRoute: { component: HomePage },
childRoutes: [
posts,
users,
],
}
```
Ótimo! Esse arquivo simplesmente exporta uma rota no formato esperado pelo `react-router`. Além disso, ele declara rotas filhas, usando as rotas encontradas na pasta *routes* do módulo blog.
Além do `index.js` e da pasta *routes* o blog também contém componentes e contêineres; mas apenas aqueles componentes e contêineres que são diretamente do seu *interesse*.
### Sub-aplicações
Tanto *posts* quanto *users*, dentro desse contexto, são aplicações em potencial. São autônomas, independentes, e devem possuir seu próprio roteamento e seus próprios contêineres/componentes. Dessa forma, ambos têm um `index.js` muito similar àquele do módulo *blog*. O `index.js` do módulo *posts*, por exemplo, poderia ser assim:
```js
import PostPage from './components/PostPage'
const post = {
path: '/:postId',
components: post
}
export default {
path: '/posts',
childRoutes: [
post,
],
}
```
Pronto! A *aplicação* "posts" tem uma porta de entrada; um `index.js` que expõe um objeto de rota. Exatamente como faz a *aplicação* "blog". Ambas tem a mesma forma. Isso significa, dentre outras coisas, que você conseguiria inicializar a aplicação *posts* independente de todas as outras, para fins de teste por exemplo. Independente mesmo da aplicação que a contém; o *blog*.
## Conclusão
É compreensível que para a maioria das aplicações esse tipo de granularização pode ser mais uma sobrecarga do que um benefício a longo prazo. Porém, quando tratamos de sistemas complexos e gigantes, com possivelmente diversos times de desenvolvimento trabalhando em partes isoladas da aplicação - exemplos clássicos são Facebook e Airbnb - essa forma de modularização é justamente o que permite independência das partes e o que garante a facilidade de mover pessoas entre partes distintas do projeto sem sacrificar a experiência prévia do desenvolvedor, já que todas as partes tem uma organização previsível.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment