# Programação orientada a dados

A Programação Orientada a Dados é uma abordagem poderosa à programação que resulta em grandes melhorias de desempenho. Ela foca-se em tratar *dados* como o elemento central; todo o resto é organizado à sua volta, para aceder ou modificar esses dados. Esta abordagem também é muito amigável para multiplayer, pois torna os dados que precisam de ser sincronizados entre jogadores mais fáceis e rápidos de aceder.

A Programação Orientada a Dados incentiva-te a pensar em tudo na tua scene como dados que precisam de ser copiados e mutados ao longo dos vários systems. O principal benefício desta abordagem está em otimizar a velocidade com que os dados podem ser lidos da memória, que muitas vezes é o principal gargalo ao executar aplicações e jogos modernos.

Devido a esta notável melhoria de desempenho, grande parte da indústria de desenvolvimento de jogos tem vindo a mudar para adotar esta abordagem nos últimos anos.

O SDK da Decentraland executa scenes em JavaScript, e uma desvantagem desta linguagem é que não oferece controlo sobre a alocação de memória. O engine que executa a Decentraland, no entanto, usa C#, que beneficia bastante ao seguir princípios orientados a dados. O SDK e o engine estão constantemente a enviar mensagens entre si. Para tornar esta comunicação o mais eficiente possível, faz sentido manter as estruturas de dados em ambos os lados o mais semelhantes possível, para evitar ter de reorganizar constantemente estes dados.

## Como é que se parece

A Programação Orientada a Dados é diferente da Programação Orientada a Objetos, uma abordagem com a qual muitos developers estão atualmente familiarizados. Na Programação Orientada a Objetos, o código é estruturado seguindo abstrações que tentam replicar construções do mundo real: objects. Cada um destes objects pode conter tanto dados como funcionalidade. As applications que usam esta abordagem são muitas vezes fáceis de planear conceitualmente, mas também mais ineficientes de executar.

Na Programação Orientada a Dados, os dados não são estruturados à volta de objects; são estruturados para otimizar a facilidade de acesso. As construções do mundo real que os dados representam não têm qualquer papel nos diferentes fluxos que mutam esses dados.

O modelo Entity Component System (ECS) em que o SDK da Decentraland se baseia é muito compatível com a abordagem da Programação Orientada a Dados. Cada component faz parte de uma coleção estruturada de dados. Os components pertencem a uma entity por referência, mas os dados não são estruturados à volta da entity; os dados são estruturados como uma coleção de components semelhantes. Por exemplo, todos os `Transform` components numa scene são iguais. Um destes transforms pode pertencer ao modelo do teu edifício principal; outro, a um copo que é filho de uma mesa. Os systems na scene processam então a lista de `Transform` components um por um, sem fazer quaisquer distinções. Todos os `Transform` components têm os mesmos campos e passam pelas mesmas verificações.

![](/files/9fc55208e94b8ef32fa323c185874456ecf2aee3)

Imagina uma scene que tem uma dúzia de portas que podem estar abertas ou fechadas. Podes representar o estado de todas estas portas como um simples component "isOpen" que guarda um valor booleano. Se "isOpen" for true, a porta deve estar aberta; se for false, a porta deve estar fechada. Se um player clicar numa porta, ela deve alternar de state, e os outros players também devem vê-la alternar. Enquanto a tua scene está a processar uma mudança no state de uma porta e a sincronizá-la com outros players, a scene não se preocupa realmente com o que "isOpen" representa. Todo o conjunto de components é apenas uma coleção de booleanos que precisam de ser sincronizados com outros players. Um system separado na tua scene pode então tratar de corresponder regularmente o state de cada "isOpen" à rotação da porta correspondente.

A Programação Orientada a Dados não é necessariamente mais difícil, mas é uma abordagem diferente que precisa de ser aprendida e adotada. Developers que não estão habituados a esta abordagem podem precisar de algum tempo para se familiarizarem com ela; encorajamos-te a explorar e a brincar com exemplos para ganhares uma melhor perceção.

## Porque funciona

Para entender por que a programação orientada a dados faz uma diferença tão grande, precisamos de olhar para o hardware.

Quando o processador precisa de obter dados da memória, ele carrega para a cache um bloco inteiro de dados, incluindo dados que simplesmente estão escritos na memória junto ao valor que queríamos. Quanto mais o teu código conseguir tirar partido de dados que já estão na cache, mais depressa o teu código será executado.

Imagina que a memória da máquina é um armazém literal, onde os dados estão guardados em muitas caixas empilhadas. Sempre que precisamos de uma certa quantidade de dados, precisamos de chamar uma empilhadora para ir buscar a caixa onde esses dados estão localizados e trazê-la para a receção para inspeção. Essa receção só consegue acomodar algumas caixas de cada vez, por isso não podes manter muito dados por perto.

Leva muito tempo para a empilhadora ir até ao fundo do armazém e trazer-nos uma caixa. Se os dados que queres destas caixas estiverem espalhados, isso significará pedir à empilhadora que faça muitas viagens. Na maior parte do tempo, vais estar a passar o tempo à espera junto à receção, a aguardar que a próxima caixa que pediste chegue.

Podes evitar grande parte desse tempo desperdiçado se empilhares estas caixas de forma inteligente e organizares os dados de modo a que as coisas de que provavelmente vais precisar ao mesmo tempo fiquem maioritariamente agrupadas. Se agrupares os dados de forma inteligente, muitas vezes vais descobrir que a próxima coisa de que precisas já está numa das caixas na receção. Vais poder avançar diretamente, sem incomodar o operador da empilhadora.

Por exemplo, se tiveres uma scene que precisa de obter o state de uma porta para verificar se está aberta ou fechada, o hardware não está apenas a obter o valor do booleano específico que descreve o state dessa porta; está a obter também uma grande quantidade de outros dados que podem ou não ser relevantes.

Suponhamos que a tua scene tem um system que precisa de atualizar o state aberto/fechado de uma dúzia de portas, uma vez por frame. Se o teu código estiver organizado seguindo uma abordagem de Programação Orientada a Objetos, não há como saber como as diferentes partes relevantes de informação podem estar agrupadas. Talvez uma "caixa" do nosso armazém contenha o state "isOpen" da porta A e também a textura da porta A e o áudio que ela reproduz ao abrir. Podes ter de fazer uma viagem para ir buscar uma nova "caixa" de dados para cada uma das dúzias de portas. E, claro, todo este processo precisa de acontecer novamente em cada frame. Portanto, isso dá 360 (30 x 12) viagens metafóricas ao fundo do armazém por segundo, mesmo quando nenhuma das portas mudou de state.

Se o teu código seguir uma abordagem Orientada a Dados, por outro lado, é muito provável que todos esses 12 booleanos estejam na mesma caixa. Isto acontece porque todos estes booleanos fazem parte de um único array que foi gravado na memória de uma só vez. Nunca estás a organizar explicitamente como estes dados se encaixam na memória, por isso, no pior dos cenários, o array pode acabar dividido entre duas caixas. Mas, mesmo nesse pior cenário, 2 viagens é muito melhor do que 12.

Verificar o state de cada porta em cada frame parece muito trabalho, mas na verdade é super rápido se todos os dados já estiverem na cache da memória. Se os teus dados estiverem bem organizados, a tua scene pode executar processos como estes sobre muitos entities e continuar a correr muito depressa.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.decentraland.org/creator/content-creator-pt/scenes-sdk7/arquitetura/data-oriented-programming.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
