O documento discute objetos imutáveis e mutáveis em cache, sugerindo que objetos imutáveis são mais seguros, mas imutabilidade compartilhada pode causar problemas. Ele apresenta várias soluções possíveis como híbrido, clonar objetos e usar wrappers para permitir que atributos sejam mutáveis por sessão enquanto mantendo outros aspectos do objeto imutáveis.
2. Cache
Objetos em cache ajudam muito a vida da
aplicação
- Existem dois tipos de objetos em cache:
- Único da sessão
- Usuário, Relatório, Source
- Divididos entre sessões
- Campanha, oferta, produto
3. Cache
Estados de um objeto precisam ser alterados
na maioria das aplicações.
- Único da sessão
- Pode mudar que não dá xabú
- Dividido entre sessões
- Alteração no estado em uma sessão
influência outra sessão, causando erros lógicos
4. Objetos imutáveis
Já dizia o Java effective "Promova a
imutabilidade"
- Objetos imutáveis são seguros
- Objetos imutáveis não tem estados obsoletos
- Objetos imutáveis são thread safe
- Objetos imutáveis são atômicos
5. Objetos imutáveis
Criar objetos imutáveis é de certa forma
simples (ou não)
public class UsuarioImutavel {
private final String nome;
private final Integer id;
private final Calendar nascimento;
private final Endereco endereco;
public UsuarioImutavel(String nome, Integer id, Calendar nascimento, Endereco endereco) {
this.nome = nome; this.id = id;
this.nascimento = nascimento; this.endereco = endereco;
}
public Integer getId() { return id; }
public String getNome() { return nome; }
public Calendar getNascimento() { return nascimento; }
public Endereco getEndereco() { return endereco; }
6. Objetos imutáveis
Possíveis Falhas
Possíveis Soluções
public void exemplo2(UsuarioImutavel usuarioImutavel) {
Calendar data = usuarioImutavel.getNascimento();
data.add(Calendar.YEAR, 2);
System.out.println(data.getTime());
}
public void exemplo1(UsuarioImutavel usuarioImutavel) {
Endereco endereco = usuarioImutavel.getEndereco();
endereco.setCEP("12345-678");
}
public Calendar getNascimento() {
Calendar cloneCal = Calendar.getInstance();
cloneCal.setTime(nascimento.getTime());
return cloneCal;
}
Fazer classe Endereco imutável
8. Mutabilidade compartilhada
- E se eu precisar mudar o estado de um objeto
divido entre sessões?
- Alteração em uma requisição muda o
comportamento de outra
- Concurrent Exception
- Comportamento imprevisível
9. Possíveis soluções
Híbrido
Criar uma classe imutável com atributos
mutáveis
- Atributo mutável continua compartilhado!
Clonar objeto na saída do cache
- Atributos imutáveis são os mesmos mas os
mutáveis são únicos para a sessão!
Adserver Approved!
10. Possíveis soluções
Bag of things
- Criar um objeto auxiliar que sempre
acompanha o objeto imutável
- Objeto tem todos os atributos mutáveis
necessários
Cache
Bag of things
11. Possíveis soluções
Wrapper
Solução chique baseada no pattern Decorator
(um pouco modificado).
- Proposta parecida com os Wrappers Java
padrão public class WrapperOferta {
private final Oferta oferta;
private String precoFormatado;
public Oferta getOfertaImutavel() { return oferta; }
public void mudaPreco(String novoPreco) { this.precoFormatado = novoPreco; }
public String getPreco() { return precoFormatado; }
}