Adoro o "padrão" imutável por causa de seus pontos fortes e, no passado, achei benéfico projetar sistemas com tipos de dados imutáveis (alguns, a maioria ou até todos). Frequentemente, quando faço isso, me pego escrevendo menos bugs e a depuração é muito mais fácil.
No entanto, meus colegas em geral evitam o imutável. Eles não são inexperientes (longe disso), mas escrevem objetos de dados da maneira clássica - membros privados com um getter e um setter para cada membro. Então, geralmente seus construtores não aceitam argumentos, ou talvez apenas tomem alguns argumentos por conveniência. Com frequência, a criação de um objeto se parece com isso:
Foo a = new Foo();
a.setProperty1("asdf");
a.setProperty2("bcde");
Talvez eles façam isso em todos os lugares. Talvez eles nem definam um construtor que use essas duas strings, por mais importantes que sejam. E talvez eles não alterem o valor dessas strings mais tarde e nunca precisem. Claramente, se essas coisas são verdadeiras, o objeto seria melhor projetado como imutável, certo? (o construtor pega as duas propriedades, sem setters).
Como você decide se um tipo de objeto deve ser projetado como imutável? Existe um bom conjunto de critérios para julgá-lo?
Atualmente, estou debatendo se é necessário mudar alguns tipos de dados em meu próprio projeto para imutáveis, mas precisaria justificá-los para meus colegas, e os dados nos tipos podem (MUITO raramente) mudar - e nesse momento é claro que você pode alterar da maneira imutável (crie uma nova, copiando as propriedades do objeto antigo, exceto as que você deseja alterar). Mas não tenho certeza se esse é apenas o meu amor por imutáveis aparecendo, ou se há uma necessidade real / benefício deles.