Prática recomendada em relação a classes anônimas em aplicativos de interface do usuário

8

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?

Jérôme
fonte
Você usaria classes anônimas nas quais a probabilidade de reutilização de código é relativamente baixa e precisa de várias implementações de uma interface. Isso evita que você precise escrever uma nova classe para cada implementação. Você viu isso ?
Robert Harvey
@ Robert, estou ciente do fato de que o código anexado a uma classe anônima normalmente não se destina à reutilização. No entanto, encontrei alguns casos em que gostaria de poder fazer isso. Por exemplo, no caso em que um Button e um MenuItem precisam executar o mesmo código, mas apenas com pequenas adaptações e sem violar DRY. Por esse motivo, estou procurando técnicas que permitam uma melhor separação e estruturação do meu código.
Jérôme
Você faz isso promovendo a classe anônima para uma classe real.
Robert Harvey
Como mencionado na minha pergunta, esta é uma das soluções que eu conheço. No entanto, estou procurando outras técnicas ou práticas recomendadas , caso existam . No entanto, se não existe, e temos que escolher entre criar uma classe anônima ou uma classe real, essa também pode ser uma resposta válida: :-) No passado, trabalhei com várias GUIs em vários linguagens de programação diferentes. E do Delphi ao Visual Studio e até ao Eiffel [sic], sempre considerei o modo Java usando classes anônimas bastante detalhadas em termos de LOC que são necessárias para obter um resultado.
Jérôme
1
Isso ocorre porque o Java é inerentemente detalhado. Você não pode consertar estúpido.
Robert Harvey

Respostas:

2

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.

Jim Barrows
fonte
Concordo totalmente com o seu primeiro parágrafo. No entanto, às vezes parece complicado criar uma classe dedicada, especialmente quando algo que começa com algumas linhas cresce com o tempo. Até agora, nunca vi alguém atribuir classes anônimas a variáveis ​​privadas no final da classe pai. No entanto, posso ver o benefício de estruturar o código sem criar muitas pequenas classes dedicadas. Mesmo que seja um estilo ruim, ele responde parcialmente à minha pergunta com relação a quais outras técnicas existem. +1
Jérôme
1

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.

por favor, responda a pergunta
fonte