[quote=domingos.neto]Antes de responder com a minha sugestão eu gostaria de dizer que nem todo ‘objeto grande’ deve ser feito immutable. Especialmente alguns exemplos que vocë deu. Vou explicar:
Você pode distinguir os seus objetos entre Value Objects e Business Entities (tem outros tipos, lógico, mas pra essa discussão estes são os dois tipos importantes). Value Objects representam uma característica, como uma Cor, um Valor Monetário, etc. Business Entities representam, bem, entidades de negócio
A grande sacada é você se perguntar: Dados dois objetos da classe Xyz com os mesmos valores em seus atributos, eles podem ser intercambiáveis? Se forem dois objetos do tipo Cor, sim, isto é, dois objetos que não tem nada a ver com o outro podem apontar para o mesmo objeto representando o Amarelo. Por outro lado, dois objetos do tipo Pessoa com os mesmos valores nos seus atributos não são intercambiáveis. Você pode ter duas Pessoas com o mesmo nome e data de nascimento, mas cada instância representa uma pessoa diferente.
A idéia é que Value Objects podem (e em geral devem) ser feitos imutáveis, pra tirar proveito do compartilhamento dos objetos e evitar bugs bizarros quando alguém modifica um Value Object que é compartilhado por um outro cara. Imagina que dois caras apontam para o mesmo objeto do tipo Cor representando o Amarelo e um desses caras resolve mudar sua cor pra Vermelho. Aí o outro cara ia mudar pra vermelho também e ia ficar difícil de debugar e entender onde está o problema.
Business Entities não devem ser imutáveis, porquê você não ganha nada com isso. Sempre que dois caras estiverem referenciando o mesmo objeto Pessoa, eles estão realmente apontando para a mesma entidade, então qualquer mudança feita por um deve ser vista pelo outro.
Bem, tendo dito tudo isto, como fazer pra criar ou modificar objetos complexos que são imutáveis? Uma idéia é usar uma classe auxiliar que que é mutável, e usar ela enquanto o objeto estiver sendo modificado, e no final chama classeMutavel.getImutableObject() ou algo do tipo. É exatamente a idéia do StringBuffer e StringBuilder. Quando vocë quer criar uma String complexa, você instancia um StringBuffer, faz todas a modificações que precisa fazer em cima do StringBuffer, e só no fim você chama toString pra obter a String final. Você pode fazer o mesmo pros seus objetos imutáveis.
Espero ter ajudado!!![/quote]
Concordo com tudo o que ele falou. Vou só pro lado prático da coisa.
Se você tem um objeto “grande” imutável, então na maioria das vezes (e é bom que seja assim) este objeto referencia objetos que são também imutáveis. Caso seja assim, uma mudança de uma propriedade deste objeto implica em um novo objeto. Porém, se algumas propriedades inalteradas são referencias para objetos imutáveis, você simplesmente faz com que os dois objetos mantenham a mesma cópia do objeto! Não precisa de “deep copy”, pois por ser imutável, caso o novo objeto precise alterar sua referência, o antigo não se altera.