Ao trabalhar com programas Java baseados na interface do usuário, uma maneira de anexar o comportamento a determinadas ações (por exemplo, com um clique no botão) é através do uso de classes anônimas. No exemplo abaixo, a estrutura da GUI é SWT, no entanto, tenho os mesmos problemas com os componentes da interface do usuário Swing ou Android. Ou seja, a estruturação dos meus programas.
MenuItem sampleMenuItem = new MenuItem(popupMenu, SWT.NONE);
sampleMenuItem.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
doSomething();
// handle all table entries
for (int i=0; i<10; i++) {
doSomething2();
}
doSomething3();
doSomething4();
}
});
Certamente, alguns podem argumentar que a quantidade de código na amostra acima já justifica a criação de uma classe dedicada que contém a lógica. Isso também é sugerido pela regra "As classes anônimas do Sonar não devem ter muitas linhas" .
Curiosamente, esta regra também especifica que:
squid: S1188 - Enquanto aguarda o suporte ao fechamento em Java, as classes anônimas são a maneira mais conveniente de injetar um comportamento sem precisar criar uma classe dedicada. Mas essas classes internas anônimas devem ser usadas apenas se o comportamento puder ser realizado em poucas linhas. Com código mais complexo, é chamada uma classe nomeada.
No entanto, como os fechamentos ainda não chegaram ao Java, minha pergunta é se existem soluções mais elegantes do que :
- escrever um monte de código dentro de classes anônimas que tem todos os tipos de desvantagens (reutilização limitada, navegação mais lenta no código, ...)
- criando um grande número de classes dedicadas, as quais podem ter funcionalidades muito limitadas (por exemplo: excesso de engenharia, ...)
Para estender minha pergunta: eu também gostaria de saber quais são as melhores práticas com relação a esse aspecto dos aplicativos de UI baseados em Java? Existem padrões bem estabelecidos?
fonte
Respostas:
O único padrão que vi, que funciona, é "Quando o código fica difícil de entender o que está acontecendo, é hora de parar de usar uma classe anônima".
No seu exemplo, o corpo do método é a classe anônima. Eu poderia mover o "novo SelectionAdapter" para sua própria linha, para tornar a abertura um pouco mais óbvia, mas, caso contrário, tudo bem. O problema é quando uma pessoa aleatória não consegue mais descobrir onde estão a classe anônima e o código do método.
Eu também criei uma variável privada ou método para armazenar a classe anônima. Coloquei esse tipo de coisa no final da aula, fora do caminho. Meio que preenche a lacuna entre toda uma nova classe e a mantém no meio do código. Algumas pessoas consideram o estilo ruim, mas minha regra geral é codificar a legibilidade primeiro.
fonte
Classes internas anônimas são uma coisa puramente estilística; eles não existem como tal dentro da classe que contém o nível do arquivo .class que é criado durante a compilação; todas as classes internas anônimas criam um arquivo .class separado como se fossem escritas como classes de nível superior.
Você pode ver isso se você navegar para o diretório de saída (normalmente chamado "out") e procurar a classe interna por nome. Você verá um arquivo de classe separado para sua classe interna. Pelo que me lembro, seu nome é OuterClassName $ InnerClassName.class. O construtor de uma classe interna anônima (que é criada mesmo que você não a escreva) recebe uma referência a "this" que, obviamente, é a classe externa que contém.
Portanto, não baseie sua decisão em nenhuma preocupação que você tenha sobre "fazer muitas aulas". É uma coisa puramente estilística.
Quando iniciei o Java, as classes anônimas pareciam uma grande bagunça para mim só porque violavam o ritmo da classe, que era algo como o método de variável variável, e de repente essa pilha de código apareceu. Na verdade, eles ainda me irritam levemente.
Sua suposta vantagem é que eles facilitam a compreensão do código - você não precisa ir para outro arquivo para ver o que o método da classe interna anônima fará. Mas é isso.
Portanto, a decisão é estilística e nada mais. Se você gosta, use, se não, não.
só queria adicionar rapidamente isso - você pode revisitar sua ideia de que conter funcionalidade limitada, digamos 1 método curto, dentro de uma classe dedicada constitui excesso de engenharia. A classe, pelo menos em Java, é a unidade de coesão. O excesso de engenharia não é medido nos métodos por classe ou mesmo na contagem de classes. OE é inteiramente ortogonal a ambos.
fonte