Qual è un buon schema per la memorizzazione e la reinizializzazione combinate?

5

Ho una situazione in cui ho tre requisiti:

  1. Inizializzazione pigra : non creare la raccolta finché non ti viene richiesta
  2. Memorizzazione nella cache : conserva la raccolta in memoria sull'oggetto
  3. Reinizializzazione : puoi reinizializzare la raccolta quando desideri, invece di ottenere semplicemente i risultati esistenti.

Questa è semplicemente un'ottimizzazione all'interno di una singola classe - non sta caricando nulla da un database e idealmente mi piacerebbe solo un buon modello di progettazione del metodo per questo, non un design multiplo.

Di solito per l'inizializzazione pigra avrei questo:

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

Ma ora ho problemi a decidere il modo migliore per fornire la reinizializzazione di una nuova collezione e ottenere quella collezione. Un parametro booleano fresh funzionerebbe, ma l'aggiunta di un parametro a un getter non sembra avere senso (forse è Java in me che parla - potrei essere convinto).

    
posta Nicole 12.04.2011 - 04:29
fonte

4 risposte

7

Se ti stai limitando a una singola chiamata al metodo, non posso onestamente immaginare una soluzione senza parametri che distingua tra il recupero del valore memorizzato nella cache e un valore reinizializzato.

Ogni cache che ho visto utilizza uno dei seguenti modelli:

  • Un metodo Invalidate o Expire che contrassegna il valore per la reinizializzazione alla prossima ricerca;

  • Un parametro booleano o di enumerazione, come quello che hai escluso;

  • Un metodo di reinizializzazione separato, ad esempio getNewCollection .

Penso che debba essere il Java di cui parli, perché in altre lingue sono molto abituato a passare i parametri nelle ricerche della cache - in alcuni casi uno dei parametri potrebbe anche essere un metodo anonimo o un puntatore a funzione che dice al cache come ottenere il valore.

Quando si progetta una cache basata sull'inizializzazione posticipata, quasi certamente si vorranno avere sovraccarichi di metodo che prendono parametri per priorità e / o scadenza, poiché non esiste più alcun metodo Put o Store per mantenerli. Quindi, penso che la nozione di un metodo di ricerca lazy-loaded metodo con facoltativo sia praticamente fuori dalla finestra.

Se ti senti a disagio nel fatto che si tratta di un getter, basta dargli un nome diverso come Load o Lookup .

P.S. Mi rendo conto che potrebbe non essere in realtà la progettazione di un cache qui, ma i principi si applicano ancora; non vuoi avere qualcosa che agisce come una cache internamente ma non fornisce la semantica della cache. Ciò comporterebbe solo mal di testa.

    
risposta data 12.04.2011 - 04:40
fonte
1

Vorrei aggiungere un metodo extra invece di passare un parametro booleano:

Collection getFreshCollection()
{
   collection = null;

   return getCollection();
}
    
risposta data 22.04.2014 - 10:31
fonte
0

Potrebbe non valere la pena in questo caso, ma potresti avere una piccola classe che si blocca sulla raccolta e ha due metodi (pubblici): uno per ottenere il valore memorizzato nella cache e uno per ottenere un valore aggiornato / ricalcolato. Entrambi i metodi dovrebbero probabilmente avere il codice di inizializzazione pigro in essi, a meno che non si sappia con certezza quale verrà chiamato per primo.

    
risposta data 12.04.2011 - 06:01
fonte
0

Guarderei Aspect Oriented Programming (AOP). Il caching è un uso abbastanza comune di AOP e java ha uno strumento AOP piuttosto carino chiamato AspectJ.

Ti aiuterà a mantenere separati i tuoi problemi di memorizzazione nella cache dall'entità o dai dubbi sulla persistenza.

    
risposta data 12.04.2011 - 06:19
fonte