Acho que sempre que trabalho com código da GUI, o código tende a inchar mais rapidamente que outros tipos de código. Também parece mais difícil de refatorar. Enquanto em outros tipos de código eu posso refatorar com bastante facilidade - acho que posso decompor uma classe maior em partes menores de funcionalidade - com a maioria das estruturas de GUI, muitas vezes estou vinculado a uma estrutura que requer meu widget / controle / qualquer classe implementar muito mais coisas diretamente no widget / controle / qualquer coisa. Às vezes, isso se deve à necessidade de (a) herdar algum widget / controle / coisa base ou (b) precisar de acesso a métodos protegidos.
Normalmente, também tenho que, por exemplo, responder a uma grande variedade de entradas via sinais / eventos / o que for da estrutura para implementar todos os modos de interação com o usuário. Talvez eu precise de um widget / controle da GUI para lidar com uma grande variedade de entradas / saídas que podem incluir:
- um clique direito / menu de contexto
- reagindo às seleções do menu de contexto - que podem ser muitas
- uma maneira especial de pintar a GUI
- reagir à entrada do teclado
- botões, caixas de seleção,
- etc etc
... gerencia o tempo todo as classes sob a GUI que representa a lógica de negócios.
Uma GUI simples e direta pode fazer com que seu código cresça rapidamente, mesmo ao separar a lógica de negócios e ao usar o MVC, acho que o código da GUI é um grande ímã para a mudança.
Existe alguma maneira de gerenciar o código da GUI de maneira sã e evitar que ele se torne uma janela quebrada? Ou é uma massa de manipuladores de eventos aleatórios / métodos substituídos realmente o melhor que podemos fazer para o código da GUI?
fonte
Respostas:
O que deve ser lembrado sobre o código da GUI é que ele é orientado a eventos, e o código orientado a eventos sempre terá a aparência de uma massa de manipuladores de eventos organizados aleatoriamente. O que fica realmente confuso é quando você tenta inserir código não orientado a eventos na classe. Claro, ele tem a aparência de fornecer suporte para os manipuladores de eventos e você pode manter seus manipuladores de eventos agradáveis e pequenos, mas todo esse código de suporte extra flutuando faz com que a fonte da GUI pareça inchada e confusa.
Então, o que você pode fazer sobre isso e como facilitar a refatoração das coisas? Bem, eu mudaria primeiro minha definição de refatoração de algo que faço ocasionalmente para algo que faço continuamente enquanto codifico. Por quê? Porque você deseja que a refatoração permita modificar mais facilmente seu código, e não o contrário. Não estou simplesmente pedindo para você alterar a semântica aqui, mas pedindo para fazer um pouco de ginástica mental para ver seu código de maneira diferente.
As três técnicas de refatoração que considero mais comuns são Renomear , Extrair Método e Extrair Classe . Se eu nunca aprendi uma única refatoração, essas três ainda me permitiriam manter meu código limpo e bem estruturado, e pelo conteúdo de sua pergunta, parece-me que você provavelmente se encontrará usando as mesmas três refatorações quase constantemente para manter seu código GUI fino e limpo.
Você pode ter a melhor separação possível da GUI e da lógica de negócios do mundo, e ainda assim o código da GUI pode parecer um código que a minha foi detonada no meio dela. Meu conselho é que não custa ter uma classe extra ou duas para ajudá-lo a gerenciar sua GUI corretamente, e isso não necessariamente precisa ser a sua classe View se você estiver aplicando o padrão MVC - embora frequentemente você encontre as classes intermediárias são tão parecidas com a sua visão que você geralmente sente vontade de mesclá-las por conveniência. Minha opinião é que não é realmente necessário adicionar uma camada específica específica da GUI para gerenciar toda a lógica visual; no entanto, você provavelmente deseja avaliar os benefícios e custos de fazê-lo.
Portanto, meu conselho é:
fonte
Eu acho que muitos dos problemas que você está enfrentando podem ser rastreados até uma causa simples. A maioria dos desenvolvedores não trata o código da GUI como código 'real'. Não tenho evidências ou estatísticas aqui, apenas meu pressentimento.
Talvez eles pensem que é apenas uma apresentação e não é importante. ' Não há lógica de negócios lá ', eles dizem, ' por que testá-lo por unidade '? Eles riem quando você menciona orientação a objetos e escreve código limpo. Eles nem tentam melhorar as coisas. Para começar, não existe uma estrutura, eles simplesmente digitam algum código e o deixam apodrecer, enquanto outros adicionam seu próprio toque ao longo do tempo. Uma bagunça linda, código de graffiti.
O código da GUI tem seus desafios únicos, portanto, deve ser tratado de maneira diferente e com respeito. Precisa de amor e desenvolvedores que queiram escrever. Os que o manterão fino e darão uma boa estrutura e padrões corretos.
fonte
Por alguma razão, o código da GUI cria um ponto cego nos desenvolvedores sobre a separação de preocupações. Talvez seja porque todos os tutoriais agrupam tudo em uma classe. Talvez seja porque a representação física faz as coisas parecerem mais intimamente ligadas do que são. Talvez seja porque as aulas são construídas lentamente, para que as pessoas não reconheçam que precisam de refatoração, como o sapo proverbial sendo fervido lentamente aumentando o calor.
Seja qual for o motivo, a solução é tornar suas aulas muito menores. Eu faço isso perguntando-me continuamente se é possível colocar o que estou digitando em uma classe separada. Se é possível colocar em outra classe, e eu consigo pensar em um nome razoável e simples para essa classe, eu faço.
fonte
Você pode dar uma olhada no padrão Model View Presenter / Passive View. Ray Ryan fez uma boa palestra em um IO do Google sobre as melhores práticas de arquitetura para o GWT.
http://www.google.com/events/io/2009/sessions/GoogleWebToolkitBestPractices.html
É fácil abstrair as idéias para outras estruturas e linguagens. O principal benefício do MVP (na minha opinião) é a testabilidade unitária. E você só consegue isso, se o seu código não estiver inchado e nem espaguete (a julgar pela sua pergunta, é isso que você deseja). Ele funciona introduzindo uma camada lógica de exibição chamada apresentador. A visão real é dissociada disso por meio de uma interface (e, portanto, pode ser facilmente zombada em testes de unidade). Agora, como sua camada lógica de exibição (o apresentador) é liberada das partes internas da estrutura da GUI concreta, você pode organizá-la como um código regular e não está ligada a, por exemplo, a hierarquia de herança Swings. Idealmente, você pode alternar as implementações da GUI em diferentes estruturas, desde que estejam em conformidade com a mesma interface.
fonte
Minha resposta consiste em quatro partes: estrutura, simplicidade, teste e sintaxe.
Os três primeiros são realmente difíceis de fazer!
Estrutura significa prestar muita atenção ao uso da menor quantidade de código e do máximo de estruturas, bibliotecas etc.
Simplicidade significa manter as coisas simples, desde o design inicial até a implementação real. Manter a navegação simples, usar plugins simples, manter o layout razoavelmente "claro" ajudará aqui. Agora eles podem ser "vendidos" para clientes / usuários que podem ver rapidamente as vantagens de páginas que funcionam em computadores, ipad, dispositivos móveis e outros.
Testar significa incluir ferramentas de teste de navegador (webrat e capivara vêm à mente com o meu trabalho de trilhos) que capturam problemas entre navegadores desde o início, quando um código melhor pode ser projetado para lidar com eles no início, em oposição aos frequentes 'patches' de código por diferentes desenvolvedores, pois são 'descobertos' por usuários de diferentes navegadores.
Sintaxe. É realmente útil usar um verificador de código / IDE / plugin de editor, etc. para seu HTML, CSS, Javascript etc. A vantagem que os navegadores obtiveram ao lidar com HTML malformado funciona contra você quando diferentes navegadores têm um desempenho diferente. portanto, é essencial uma ferramenta que verifique seu formato HTML. Ter HTML bem formado é muito útil para ter HTML não vazio porque o código incorreto deve ter mais visibilidade.
fonte
A solução que encontrei é o código declarativo. Usar apenas código processual é uma receita para o código da GUI de espaguete. Certamente, uma "maneira especial de pintar o widget" provavelmente continuará sendo o código. Mas esse é um código isolado em uma classe. Manipuladores de eventos, atalhos de teclado, tamanhos de janelas - todas essas coisas bagunçadas são melhor declaradas.
fonte
Há muitas ótimas respostas aqui.
Uma coisa que me ajudou a simplificar o código da GUI é garantir que a GUI tenha seu próprio modelo de dados.
Para dar um exemplo simples, se eu tenho uma GUI com 4 campos de entrada de texto, tenho uma classe de dados separada que mantém o conteúdo desses 4 campos de entrada de texto. GUIs mais complicadas exigem mais classes de dados.
Eu desenho uma GUI como modelo - visão. O modelo da GUI é controlado pelo controlador de aplicativo do modelo de aplicativo - visualização - controlador. A visualização do aplicativo é o modelo da GUI, em vez do próprio código da GUI.
fonte
Aplicativos como processamento de texto, editores gráficos etc. têm interfaces complexas e seu código não pode ser simples. No entanto, para aplicativos de negócios, a GUI não precisa ser tão complexa, mas de alguma forma ainda é.
Algumas das chaves para simplificar a GUI são (a maioria se aplica ao .NET):
Busque um design mais simples sempre que possível. Evite comportamentos extravagantes se não for solicitado pela empresa.
Use um bom provedor de controles.
Não crie funcionalidade de controle personalizado no próprio código do cliente. Em vez disso, crie controles de usuário que estendam o controle original de maneira que você possa refletir seus comportamentos específicos nos controles, e não no código do formulário / página em uso.
Use uma estrutura (mesmo doméstica) para lidar com internacionalização, gerenciamento de recursos, estilos etc. para não repetir esse código em todas as UI.
Empregue um componente (ou estrutura) para navegação.
Crie diálogos padrão para erros, avisos, confirmação etc.
fonte
Aplique o Design Orientado a Objetos ao seu código e para o desenvolvimento da UI:
Aqui está um aplicativo pequeno, mas não trivial, para ajudar a ilustrar alguns dos meus pontos. Você pode encontrar o código e visualizar o diagrama de interação do modelo aqui: https://github.com/vanfrankie/pushpopbox
fonte
Você quer dar uma olhada no conceito de "ligação de dados" . É uma maneira de conectar elementos da interface do usuário a elementos abstratos do modelo de maneira declarativa, de forma que os elementos do modelo sejam sincronizados automaticamente com o conteúdo da interface do usuário. Há muitos benefícios dessa abordagem, por exemplo, não ter que escrever os manipuladores de eventos para sincronizar os dados.
Há suporte à ligação de dados para muitas estruturas de interface do usuário, por exemplo, .NET e Eclipse / JFace .
fonte