Home > Artigos > Engenharia de Software >
OO e padrões de projeto: Criando um novo componente GUI e adicionando a um projeto existente
Publicado por jesuino em 16/08/2009 - 2.137 visualizações
Origem: Esse é mais um artigo/tutorial/exemplo que parte aqui mesmo do JavaFree! Há muitos posts, houve uma pessoa aqui no fórum querendo um elemento como o descrito acima. Eu me interessei pelo problema, por ser uma idéia legal, e fiz uma possível solução, que acabei utilizando em um projeto acadêmico! Mas na época eu era muito novo com Java! Então, recentemente nesse post, uma outra pessoa estava com a mesma dúvida. Não consegui achar o post anterior e resolvi postar novamente o código. Nosso colega do post disse que o código estava muito complicado, não era impressão dele! Estava mesmo, e muito ridículo. Assim, propomos uma nova solução, reutilizável, encaixável em qualquer projeto! Ao longo desse artigo tentaremos observar os problemas que o código anterior poderia trazer, melhorando o mesmo código para ser mais re-utilizável!
O código antigo e seus problemas:
Um explicação do código antigo (Somente a view é necessária para explicar, o restante do código se encontra no post citado acima):
Se estiver perdido, leia um tutorial de como criar janela Swing
Explicando essa tralha toda:
Nosso objetivo é criar um elemento que compõe dois outros elementos já existentes. Conforme vocês podem ver, o código acima resolve o problema de auto-complete. A cada tecla digitada, ele bate no banco de dados, busca e retorna as sugestões, colocando-as em um JComboBox, antes invisível. Com o usuário selecionando um valor, o programa põe esse valor como parâmetro para busca e ainda indica quando não há valores no banco de dados. Isso é feito usando os eventos nos elementos: A cada caracter digitado no campo de texto, vamos para o banco, buscamos nossos campos relacionados e jogamos no JComboBox, como o foco perdido na combobox(o usuário "des-seleciona") passamos o valor como parâmetro de busca...
Se estiver perdido, leia um tutorial de como criar janela Swing
Funcionar até que funciona...
Na verdade isso é muito fácil de implementar, e existem muitas outras formas. Com certeza, não há problemas para o funcionamento do presente frame com o meu atual control! No entanto, temos problemas quanto a flexibilidade, visibilidade de código, reutilização, entre outros. É ai que entra nosso papel de deixar esse código brilhando, sem macumba nem vudu, somente com Orientação a Objeto e Padrões de Projeto.
Vamos analisar o código. Imagine-se na seguinte situação: você tem reutilizar o componente proposto, o projeto já está compilado em arquivos .class, como você vai fazer? Você tem acesso ao Frame, mas e daí? Você quer utilizar somente o recurso de auto-complete. Para os espertinhos de plantão, é possível sim pegar o campo de texto e o combobox do frame, mas isso de nada servirá, pois a lógica de realizar a função destinada está dentro do frame... Enfim, um grande problema! Uma solução é você fuçar no código fonte de sua aplicação antiga e "sugar" a forma que foi feito, para repetir código e gerar outra solução específica. Olha, dois pecados graves: Repetir Código e Gerar uma solução específica. E outro problema maior seria sua demissão, pois até você pegar o código, reler, re-entender, aplicar novamente no seu problema atual: game over...
Onde foi que erramos???
O que gerou nosso problema foi a má idéia de não separar algumas classes da classe que utiliza. Não usamos composição e nem encapsulamento. Também fomos egoístas, fizemos uma solução para este projeto sem pensar nas consequências e nem nos projetos de nossos amigos... Nosso primeiro objetivo é separar o que nos interessa desse frame, que deveria ser feito no primeiro momento, mas não foi!
Muitos podem pensar: "Ninguém deixa um códígo dentro do outro assim, esse é só um exemplo". Sim, nesse exemplo é verdade que está explícita a necessidade de separação, mas podemos achar outros pontos que não são tão visíveis para serem separados, pois podem ser usados futuramente.
Me liberte do seu Control
Temos que libertar a busca de dados para preencher o componente do nosso atual controller. Ou seja: o auto complete não deve conhecer um controller especificamente, mas uma forma genérica de controller.
É bobeira para o nosso componentes conhecer o controller, sendo que ele simplesmente quer os dados. A classe control pode ter diversos métodos, mas você precisa só de um. Você tem que identificar o que é necessário para o seu componente... No nosso caso, por mais que a classe conheça o controller inteiramente você só quer o método que retorna os dados para sugestão de auto preenchimento!
Vamos usar uma interface!!!!!!!!!!!!!!!!!!!!!!!!!!
Assim o autocomplete compõe a interface e não o control, e ele passa a implementar a interface! Observe a simplicidade de nossa interface:
Retomando: Queríamos tirar o autocomplete de nossa telinha de teste para usar em outros projeto, mas ele estava muito ligado ao nosso control. Analisando o código, descobrimos que simplesmente um método é necessário. Assim fizemos uma interface.
Separação fisíca do auto complete
A separação fisíca é mais estética. Optamos por colocar nosso componente em um JPanel simples... Também fizemos métodos de acesso aos dois componentes do painel(O campo de texto e o comboBox). Olhe como ficou:
Para usar esse painel é simples, você somente precisa fazer o control implementar o método!
Terminamos, olhe uma classe de teste, que linda que ficou:
Agora vamos usar em um outro projeto comprovando a flexibilidade!
Errrrr.... não tenho o código dos controllers, eles já estão compilados em bytecodes...
E agora??
O desenvolvedor derrotado, que não leu a teoria dos padrões:
Nossa... Trabalho perdido para projetos já existentes...
Você! A partir de hoje:
Eu tenho uma solução para isso.
Sim, há uma solução! Você pode utilizar uma classe intermediária que implementa a interface (então nosso componente vai "aceitar" a classe) e conhece o controle. Assim você não mexe no seu projeto existente e nem no componente que propomos. O nome desse padrão é Adapter. Ele permite que você conecte dois elementos adaptando interfaces, sendo que os componentes envolvidos não precisam se conhecer! Exatamente a solução para nosso caso. No nosso caso, temos a interface mostrada acima e o nosso controller que precisamos adaptar para a interface sem mexer no código existente. Nossa interface é uma variação desse padrão, olhe como ficou:
Usando o Adapter, finalizamos com um exemplo:
Perceba que instanciamos o ControlAdapter na view, sem mexer sequee uma linha no controller, e temos o projeto funcionando de forma visível, com código limpo!
FAQ's:
->Tem coisas a melhorar???
Muitas!
->Esse modelo pode não ser o mais flexível???
Sim, com certeza existem formas de melhorar esse modelo adotado!
Estamos aguardando sugestões, críticas, comentários no fórum!
Um pequeno desafio:
Desafiamos você a tentar usar esse componente em algum projeto existente e comentar no fórum as necessidades e problemas enfrentados!
- HashSet
- Delphi + Java
- JScrollPane ????? Duvida
- GUI...componentes...
- JTable em JScrollPane
- Livro para iniciante em Java
- JComboBox não exibe
- Mensagens que não tinham tópicos
- Existe alguma classe/Componente GUI onde eu possa formatar
- Interfaces
- JFileChooser - ordem de exibição dos "FileFilters"
- como faço isso
- O PHP É BEM MAIS RÁPIDO EM ACESSO A BANCO DO QUE O JSP!
- Parte complexa em O.O
- Ler um arquivo txt no J2ME


