Implementazione predefinita rilevabile di un'interfaccia

5

Ho un paio di classi semplici che implementano il modello Null Object.

Per illustrare la gerarchia, definiamo un'interfaccia Config con due classi che la implementano ConfigItem e MissingConfig , ciascuna definita nel suo file.

// Config.java

public interface Config {

    Something process();
}

// ConfigItem .java

public class ConfigItem implements Config {

    // some fields

    @Override
    public Something process() {
       // some actual logic and return statement
    }
}

// MissingConfig.java

public enum MissingConfig implements Config {

   INSTANCE;

    @Override
    public Something process() {
        // do no harm
    }
}

Nel mio caso, l'oggetto MissingConfig è immutabile e solo una singola istanza è garantita per esistere.

Funziona bene e mi permette di evitare i controlli nulli. Tuttavia, il fatto che questa implementazione dell'interfaccia Config esista può essere ignorata da altri sviluppatori che lavorano con il codice.

Sto provando a trovare un modo per rendere facile trovare la rappresentazione null riutilizzabile di Config .

Mi è venuto in mente che potrei esporlo usando l'interfaccia stessa:

public interface Config {

    Something process();

    MISSING = MissingConfig.INSTANCE;
}

in modo che venga completato automaticamente per tutti coloro che cercano di fare qualcosa con Config

Questo, comunque, in un certo senso, introduce una costante nell'interfaccia, che è sconsigliata in Java efficace di Joshua Bloch (Capitolo 4, articolo 19)

Un altro modo per strutturare il codice che mi è venuto in mente è definire l'enum all'interno dell'interfaccia.

public interface Config {

    Something process();


    public enum Missing implements Config {

        INSTANCE;

        @Override
        public Something process() {
            // do no harm
        }
    }
}

Sembra quasi leggibile se consumato

Config.Missing.INSTANCE

ma non bello come la versione precedente ... e tecnicamente, questa è ancora una costante definita all'interno di un'interfaccia. Solo un po 'più contorto.

C'è un modo in cui posso rendere palesemente evidente il consumo dell'oggetto nullo senza violare le buone pratiche del design dell'interfaccia ... o sto cercando di avere la mia torta e di mangiarla anch'io?

Sto iniziando a pensare che la mia implementazione originale (con l'enum definito nel suo stesso file) sia la più elegante e che la rilevabilità dovrebbe essere raggiunta da una menzione esplicita in Javadoc. Per quanto mi piacerebbe, non posso proteggermi da persone che non leggono javadoc.

Ho anche pensato di passare da interface a abstract class ma questo limita il riutilizzo in modi che non posso accettare a causa dell'ereditarietà singola (qualche codice esistente che ha a che fare con Config )

Spero che questo non sia troppo aperto per Programmatori

    
posta toniedzwiedz 17.05.2016 - 17:52
fonte

1 risposta

2

C'è una frase nel capitolo a cui fai riferimento ( Effective Java di Joshua Bloch (Capitolo 4, articolo 19)):

If the constants are strongly tied to an existing class or interface, you should add them to the class or interface.

e potresti riscrivere i tuoi esempi per:

public interface Config {

  Config EMPTY = new Config() {
    @Override
    public void doSomething() {
      // empty for missing config
    }
  };

  void doSomething();
}

ma alcuni JAVADOC potrebbero essere utili per i tuoi colleghi.

    
risposta data 17.05.2016 - 18:26
fonte

Leggi altre domande sui tag