Se ogni istanza di un tipo deve essere casuale, come deve essere memorizzato l'oggetto generatore casuale?

1

Mi sembra che questo sia spesso riscontrato nella pratica e mi stavo chiedendo se c'è un modello di progettazione per quanto segue:

Supponiamo che abbia una classe che rappresenta una carta:

public class Hand {
    private static Random rng;
    private Rank rank;
    private Suit suit;
    public Hand() {
        if (prng == null)
            prng = new Random();
        }
        //more stuff
    }
}

Ogni volta che istanzia una carta, voglio una carta a caso. Facendolo sopra, si perde un confronto con null per istanziazione. Se creo un campo statico e lo alloco nella decelerazione:

private static Random rng = new Random();

un nuovo oggetto casuale viene istanziato ogni volta - anche non molto efficiente.

Se passassi l'oggetto Random nel costruttore, violerei "tell, do not ask."

Forse c'è un altro suggerimento, ma finora, penso che il modo migliore sia il controllo nullo.

    
posta Wuschelbeutel Kartoffelhuhn 29.12.2013 - 16:07
fonte

2 risposte

7

Un costruttore dovrebbe essere deterministico se possibile, altrimenti il codice sarà non verificabile. Avere almeno un costruttore sovraccaricato in grado di accettare un RNG:

public Hand(Random prng) {
  // more stuff
}

Un costruttore senza argomento può fornire un RNG predefinito, come nel tuo schizzo di progetto. Mentre un confronto null non è così costoso e un new Hand non è così comune, puoi semplicemente inizializzare l'RNG con la classe:

private static Random prng = new Random();

public Hand() {
  this(prng);
}

In questo modo, l'inizializzazione RNG viene eseguita solo una volta.

Altrimenti, la citazione su ottimizzazione prematura si applica ...

    
risposta data 29.12.2013 - 16:14
fonte
6

If I create a static field and allocate it in the deceleration:

private static Random rng = new Random();

a new Random object gets instantiated every time - also not very efficient.

Questo semplicemente non è vero - creerà un singolo Random quando la classe è inizializzata, ecco cosa significa static . Quindi, è la soluzione corretta. Ma ricorda anche che gli oggetti Random sono piuttosto leggeri e non c'è motivo di essere eccessivamente riluttanti a crearli, a meno che tu non lo stia facendo milioni di volte al secondo.

    
risposta data 29.12.2013 - 16:11
fonte

Leggi altre domande sui tag