TransWikia.com

O uso de imutabilidade

Stack Overflow em Português Asked by dougg0k on December 14, 2020

Imutabilidade

  1. Quais as vantagens e benefícios, quando devo usar e por que devo usar
    imutabilidade em meus projetos?
  2. A complexidade da implementação x tempo, vale a pena?
  3. Quando não devo usar imutabilidade e quais são as desvantagens?
  4. Quais "boas" práticas devo considerar ao implementar imutabilidade, isso é, se existirem?

One Answer

Pode-se entender um pouco sobre imutabilidade em outra pergunta aqui no site.

Ela apenas garante que o estado nunca será alterado no mesmo objeto. Não garante que uma variável tenha sempre o mesmo valor. Esta é uma distinção importante. Usa uma técnica de COW.

Inclui quaisquer estruturas que só permitem fazer leitura depois de sua criação.

Não estamos falando de constância.

Também não entenda imutabilidade como algo que garante que o objeto jamais será alterado na memória. Esta é uma garantia que a aplicação compilada e executada, em condições normais, terão os dados preservados por ela, nada mais que isto.

Quais as vantagens, quando devo usar e por que devo usar imutabilidade em meus projetos?

  • Facilita muito o uso de threads, afinal se o estado nunca muda todos algoritmos são livres para acessar os objetos sem preocupações de serem mudados no meio do caminho ou de mudá-los e causar problemas para outras partes da aplicação. Facilita a concorrência e paralelização. São livres de efeitos colaterais. Ou seja, o compartilhamento fica livre;
  • ela é ótima como chave para diversas estruturas de dados em diversas aplicações. Chaves mutáveis são sempre complicadas de manipular porque uma mudança no objeto que foi usado como chave pode mudar toda a estrutura de dados;
  • podem ser usados em cache sem maiores preocupações, o objeto tem estado único;
  • os códigos ficam mais fáceis de acompanhar. Mudança de estado sempre foi o maior complicador da programação, eliminando isto elimina complexidade e evita bugs;
  • testar objetos imutáveis é mais fácil;
  • objetos imutáveis podem ser considerados automaticamente atômicos, consistentes e isolados, características que idealmente todo objeto deveria possuir;
  • eles possuem uma durabilidade no sentido de que nunca são sobrepostos, a informação original sempre está disponível. Claro que isso não quer dizer que seja permanente. Se não houver referências para o objeto eles podem ser descartados. E obviamente não há durabilidade permanente em dispositivos de armazenamento temporário, como é o caso da memória RAM (diferente de NVRAM);
  • como o estado é que é importante várias referências para o mesmo objeto podem economizar memória evitando ter cópias com dados repetidos. Isso pode ser vantajoso em alguns cenários de grande duplicação de objetos de mesma identidade.

A complexidade da implementação x tempo, vale a pena?

Pura opinião, depende, sei lá, só você sabe para o seu caso.

Se fosse essa bala de prata toda que alguns acham, todo mundo estaria fazendo tudo imutável. Isso não ocorre na maioria das aplicações.

Quando não devo usar imutabilidade?

  • O motivo principal é o custo de manter estas estruturas ativas. Para garantir a imutabilidade a cópia dos objetos é necessária em todas operações que escrevem em qualquer parte do seu estado. Sempre que há uma escrita, um novo objeto precisa ser criado. Isto é caro tanto em processamento quanto em consumo de memória, e alguns objetos são absurdamente grandes. Se compensa pagar este preço depende de cada necessidade;

  • a cópia do objeto pode disparar uma quantidade absurda de cópias de outros objetos, pois a criação de um novo objeto possivelmente resulta na alteração de estado de outro objeto;

  • pode ser pior, os objetos podem ter referências cíclicas impedindo o seu uso;

  • o algoritmo da cópia ainda pode ter um custo de desenvolvimento e dificuldade de manutenção nos casos em que a cópia não seja um processo trivial que pode ser facilmente automatizada na sua implementação;

  • se a linguagem não ajuda (anda ficando raro) pode não ser tão simples implementar a imutabilidade;

  • não pode usar quando o objeto precisa ser único ou não pode ter cópias indiscriminadas na aplicação. O caso mais típico é o de criação de objetos Singletons ou qualquer padrão semelhante. Exemplo:

    Imagine um saldo de conta corrente que recebe uma retirada, então é criado outro objeto por causa da imutabilidade. Ao mesmo tempo é feita outra retirada, que cria outro objeto baseado no primeiro mas não na cópia gerada agora. Já deu para perceber que a conta não vai fechar, né? Uma coordenação será necessária, o que parecia simples já não é tão simples assim;

  • lembre-se que o modelo mental que temos da maioria dos objetos é que suas características podem ser mudadas em vez de criar um novo objeto quando precisa de uma característica diferente. Adaptar o modelo mental ao paradigma não costuma ser ideal. Convenhamos, impor algo para uma equipe que não trabalha bem com isto pode ser desastroso. A melhor ferramenta é aquela que você conhece. Exemplo:

    Pode ser esquisito dizer que o João passa ser outra pessoa porque agora ele teve um aumento salarial. A imutabilidade exige isto, e pior, o João original continua existindo. Passa ter um João pobre e um clone rico ;) isto não reproduz o que de fato acontece no mundo real.

    Claro que existem soluções para estas problemas, mas aí começamos complicar o design da aplicação e começamos nos questionar se compensa.

O que principalmente devo considerar ao utilizar imutabilidade?

Posso pensar? Ainda não sei. Além de tudo o que já escrevi precisaria pensar.

Preste atenção na complexidade das estruturas de dados imutáveis. Para otimizar e evitar a cópia integral de toda a estrutura é comum adotarem uma estrutura interna que muda a complexidade (Big O) que normalmente o desenvolvedor espera daquela estrutura. Para evitar cópias é possível que um vetor ou uma pilha vire uma lista ligada ou árvore, ou pelo menos faça uso destas estruturas de forma complementar.

Conclusão

Conheço pouco sobre DDD mas me parece ser uma metodologia que define algumas regras para adoção de cada caso.

Tem que pesar bem, não posso dar conclusões definitivas. E não é ideal adotar uma forma única. Na maioria dos cenários costuma ser melhor decidir sobre isto, estrutura por estrutura e não adotar uma forma para todo projeto.

Não considere esta resposta como definitiva sobre todos os aspectos. A pergunta é um pouco ampla e acho que não caberia encher de detalhes. Nem mesmo fiz uma pesquisa profunda para analisar tudo o que poderia. Certamente esqueci de coisas importantes.

Correct answer by Maniero on December 14, 2020

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP