Implementação padrão detectável de uma interface

5

Eu tenho algumas classes simples que implementam o padrão Null Object.

Para ilustrar a hierarquia, vamos definir uma interface Config com duas classes implementando ConfigItem e MissingConfig , cada uma definida em seu próprio arquivo.

// 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
    }
}

No meu caso, o objeto MissingConfig é imutável e apenas uma única instância é garantida.

Isso funciona bem e me permite evitar as verificações de nulos. No entanto, o fato de essa implementação da interface Config existir pode ser perdido por outros desenvolvedores que trabalham com o código.

Estou tentando encontrar uma maneira de tornar a representação nula reutilizável do Config fácil de encontrar.

Ocorreu-me que eu poderia expô-lo usando a própria interface:

public interface Config {

    Something process();

    MISSING = MissingConfig.INSTANCE;
}

para que seja preenchida automaticamente para todos que tentam fazer algo com Config

Isso, no entanto, de certa forma, introduz uma constante na interface, que é desaconselhada em Effective Java de Joshua Bloch (Capítulo 4, item 19)

Outra maneira de estruturar o código que me ocorreu é definir o enum dentro da interface.

public interface Config {

    Something process();


    public enum Missing implements Config {

        INSTANCE;

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

Isso parece quase tão legível quando consumido

Config.Missing.INSTANCE

mas não tão bom quanto a versão anterior ... e tecnicamente, isso ainda é uma constante definida dentro de uma interface. Apenas um pouco mais complicado.

Existe alguma maneira de tornar óbvio o consumo do objeto nulo sem violar as boas práticas do design da interface ... ou estou tentando ter meu bolo e comê-lo também?

Estou começando a pensar que a minha implementação original (com o enum definido em seu próprio arquivo) é a mais elegante e que a descoberta deve ser alcançada por uma menção explícita a ela no Javadoc. Por mais que eu ame, não posso me proteger contra pessoas que não lêem javadocs.

Eu também pensei em mudar de um interface para um abstract class , mas isso limita a reutilização de maneiras que não posso aceitar devido à herança única (algum código existente que tem a ver com o Config )

Espero que isso não seja muito aberto para Programadores

    
por toniedzwiedz 17.05.2016 / 17:52
fonte

1 resposta

2

Há uma frase no capítulo que você mencionou ( Effective Java de Joshua Bloch (Capítulo 4, item 19)):

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

e você pode reescrever seus exemplos para:

public interface Config {

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

  void doSomething();
}

mas alguns JAVADOC podem ser úteis para seus colegas.

    
por 17.05.2016 / 18:26
fonte