Creazione di un singleton per accedere ai dati statici

1

Ho alcune proprietà in un file di proprietà a cui ho fatto riferimento in un singleton in modo che possa accedervi facilmente da diverse parti della mia applicazione. Per ogni proprietà, inserisco le proprietà insieme ad alcune informazioni aggiuntive per ogni proprietà in un elenco di oggetti. Lo sto facendo nel costruttore privato del singleton. È questo il modo corretto di archiviare / accedere a dati statici su un server?

Qualsiasi aiuto o guida è apprezzato.

Aggiunto un esempio di ciò che sto facendo attualmente

public class PropertiesSingleton {

    private static PropertiesSingleton instance = null;
    private List<MyPropertyObject> properties = new ArrayList<>();

    private static PropertyManager pm = PropertyManager.getInstance();

    private PropertiesSingleton() {
        properties.add("first property description", 
                "other property info", 
                new MyPropertyObject(pm.getProperty("firstProperty")));
        properties.add("second property description", 
                "other property info", 
                new MyPropertyObject(pm.getProperty("secondProperty")));
        properties.add("third property description", 
                "other property info", 
                new MyPropertyObject(pm.getProperty("thirdProperty")));
    }

    public static getInstance() {
        if (instance == null) {
            instance = new PropertiesSingleton();
        }
        return instance;
    }

    public getProperties() {
        return this.properties;
    }
}
    
posta qbolt 17.03.2017 - 17:26
fonte

2 risposte

1

Se funziona per te, allora in questo senso è corretto.

In un senso più ampio, penso che molte persone lo vedrebbero come una specie di anti-modello se lo stavi usando nel modo seguente:

class Foo
{
    public void Bar()
    {
        int value = StaticData.getInstance().getUsefulPropertyValue();
        // do stuff with value
    }
}

Questo è considerato un anti-pattern perché il fatto che Foo dipende da StaticData è nascosto all'interno dell'implementazione di Foo . Questo coppia strettamente Foo e StaticData . In questa situazione specifica potrebbe non esserci un grosso problema perché StaticData è invariato, ma nella situazione generale questo rende più difficile testare la classe genitore.

Ad esempio, se Foo dipendesse effettivamente dal singleton DatabaseAccess , l'unità testando Foo sarebbe impossibile. Foo richiederebbe la presenza di un database da testare che è a) scomodo, e b) non è più tecnicamente un test unitario!

Puoi aggirare questo problema utilizzando Iniezione di dipendenza :

class Foo
{
    private DatabaseAccess databaseAccess;

    // Here we use Constructor Injection to inject Foo's dependencies into it.
    // NOTE: The dependency on DatabaseAccess is made explicit by being a part of Foo's constructor signature.
    // This makes it clear that Foo cannot be created without an instance of DatabaseAccess.  It therefore depends on it.
    public Foo(DatabaseAccess databaseAccess)
    {
        this.databaseAccess = databaseAccess;
    }

    public void Bar()
    {
        // NOTE: We are no longer plucking its dependency out of thin air!
        int data = this.databaseAccess.getTheCoolestIntegerEver();
    }
}

Funzionalmente, questo codice è molto simile, ma in termini di testabilità e manutenibilità è di gran lunga superiore.

Inoltre, nota che DatabaseAccess potrebbe ancora essere un singleton. La chiave da prendere qui è di non accedere mai ai tuoi singleton con un metodo getInstance() statico.

    
risposta data 17.03.2017 - 17:52
fonte
0

Qual è la variabilità di queste proprietà? Devono differire tra gli ambienti dev / test / prod?

Se la risposta è "Sì", tirerei quei valori dalle variabili ambientali. Questo ti permetterebbe di riutilizzare l'artefatto compilato in tutti gli ambienti. Perché utilizzare i vars ambientali OS, non i parametri JVM? Per esempio. è utile quando si impacchetta il tuo artefatto all'interno dell'immagine della finestra mobile.

Quindi, dai un'occhiata a libreria di configurazione HOCON di Lightbend. Permette di utilizzare variabili d'ambiente e impostare valori predefiniti sensibili memorizzati in forma strutturata e leggibile simile a JSON in resources / application.conf.

Infine, se le proprietà possono essere caratterizzate come configurazione, di solito preferisco lasciare una singola entrata per i dati di configurazione nella mia applicazione. Entra nel punto in cui la tua app è cablata, convalidata da alcuni factory di configurazione, e quindi parti rilevanti dei dati di configurazione vengono passati attraverso il grafico degli oggetti tramite i parametri del costruttore.

    
risposta data 17.03.2017 - 21:56
fonte

Leggi altre domande sui tag