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