O que é um bom padrão para caching e reinicialização combinados?

5

Eu tenho uma situação em que tenho três requisitos:

  1. Inicialização preguiçosa - não crie a coleção até que seja solicitada
  2. Caching - mantém a coleção na memória do objeto
  3. Reinicialização - ser capaz de reinicializar a coleção quando desejado, em vez de simplesmente obter os resultados existentes.

Isto é simplesmente uma otimização dentro de uma única classe - não é carregar nada de um banco de dados e, idealmente, eu gostaria apenas de um bom padrão de design de método para isso, não um design de múltiplas classes.

Normalmente, para inicialização lenta, tenho isto:

Collection getCollection() {
    if (collection != null) {
         // generate and set collection
    }
    return collection;
}

Mas agora estou tendo problemas para decidir a melhor maneira de reinicializar uma nova coleção e obter essa coleção. Um parâmetro booleano fresh funcionaria, mas adicionar um parâmetro a um getter não parece correto (talvez esse seja o Java em mim falando - eu poderia ser convencido).

    
por Nicole 12.04.2011 / 04:29
fonte

4 respostas

7

Se você está se limitando a uma única chamada de método, não posso imaginar honestamente uma solução sem parâmetros que faça a distinção entre recuperar o valor em cache e um valor reinicializado.

Cada cache que vi usa um dos seguintes padrões:

  • Um método Invalidate ou Expire que sinaliza o valor para reinicialização na próxima consulta;

  • Um parâmetro booleano ou de enumeração, como o que você descartou;

  • Um método de reinicialização separado, por exemplo, getNewCollection .

Eu acho que deve ser o Java em você falando, porque em outras línguas eu estou muito acostumado a passar parâmetros em pesquisas de cache - em alguns casos, um dos parâmetros pode até ser um método anônimo ou um ponteiro de função dizendo ao cache como obter o valor.

Ao projetar um cache com base na inicialização adiada, você certamente também desejará ter sobrecargas de método que tomem parâmetros de prioridade e / ou expiração, já que não há mais nenhum método Put ou Store para mantê-los. Então, eu acho que a noção de um método de pesquisa sem parâmetros carregado com preguiça com atualização opcional está praticamente fora da janela.

Se você não se sentir confortável em ser um getter, adicione um nome diferente, como Load ou Lookup .

P.S. Eu sei que você pode não estar projetando um cache aqui, mas os princípios ainda se aplicam; você não quer ter algo que funcione como um cache internamente, mas não fornece semântica de cache. Isso apenas levaria a dores de cabeça.

    
por 12.04.2011 / 04:40
fonte
1

Eu adicionaria um método extra em vez de passar um parâmetro booleano:

Collection getFreshCollection()
{
   collection = null;

   return getCollection();
}
    
por 22.04.2014 / 10:31
fonte
0

Pode não valer a pena neste caso, mas você pode ter uma pequena classe que trava na coleção e possui dois métodos (públicos): um para obter o valor em cache e outro para obter um valor atualizado / recalculado. Ambos os métodos provavelmente precisariam ter o código de inicialização lenta, a menos que você saiba com certeza qual deles será chamado primeiro.

    
por 12.04.2011 / 06:01
fonte
0

Eu olharia para Aspect Oriented Programming (AOP). O cache é um uso bastante comum do AOP, e o java tem uma ferramenta AOP bem legal chamada AspectJ.

Ele ajudará você a manter suas preocupações de armazenamento em cache separadas da entidade ou das preocupações de persistência.

    
por 12.04.2011 / 06:19
fonte