Essas respostas substituem as do FAQ - Básico já que conceitos mais avançados já foram ministrados neste momento.
Como exibir na GUI o resultado de uma consulta que retorna uma coleção de dados como resposta?
Como implementar o padrão de projetos Singeton? (use isso para garantir que apenas uma instância da fachada é criada no projeto)
RESPOSTAS
O ideal é fazer o reuso da coleção de dados, assim o tipo da resposta deve ser a interface negócio-dados (RepositorioClasseBasica), onde deve ser criada uma nova instância da coleção com os elementos que satisfazem o critério da busca.
Uma maneira é utilizar o padrão de projetos Iterator, e definir uma coleção de dados iterável, a qual permite varrer os objetos incluídos na mesma. Assim os repositórios devem ter o método getIterator() que retornam uma coleção iterável com os elementos contidos nos mesmos. Por exemplo, este método deve ser chamado da coleção de dados retornada como resposta de uma consulta, como dito no item anterior, para listar na GUI os objetos retornados como resposta.
Ao invés de manipular diretamente um objeto javax.swing.JList você deve associar ao JList (vide o método setModel) um objeto que é como um vetor de objetos. Este objeto é da classe javax.swing.DefaultListModel. Qualquer objeto adicionado no DefaultListModel será exibido pela lista. Se remover algum objeto do DefaultListModel ele deixará de ser exibido pela lista.
Veja exemplo de código que cria uma JList para exibir objetos do tipo Conta retornados em um IteratorContas pela classe fachada.Banco fachada = ... IteratorContas iterator = banco.getContas(); JList lista = new JList(); DefaultListModel vetor = new DefaultListModel(); lista.setModel(vetor); while(iterator.hasNext()) { vetor.addElement(iterator.next()); }Neste exemplo, o texto que aparecerá na lista é o retorno do método String toString() da classe Conta. Redefina este método na sua classe básica para definir o que deverá ser exibido ao incluir um objeto da mesm em uma lista.
Use o método estático showMessageDialog da classe JOptionPane do pacote swing.
Ex.: JOptionPane.showMessageDialog(this," MENSAGEM");
De modo a manter a transparencia do meio de armazenamento para as Coleções de Negócio, a Interface Negócio-Dados deve usar a exceção RepositorioException para indicar quaisquer erros específicos do meio de armazenamento. Por exemplo, erros de bancos de dados, como queda da conexão, coluna não encontrada, chave primeria violada (SQLException em geral), ou erros de arquivo não encontrado, caso a implementação da interface use arquivos para armazenar os objetos, etc.Note que a exceção RepositorioException encapsula a exceção específica, a qual pode eventualmente ser recuperada para um tratamento específico, se for o caso. A classe RepositorioException dará como mensagem a mensagem da exceção que foi emcapsulada. O mesmo acontece caso outros os métodos, como printStackTrace(), seja chamado.
Utilize o método lancaAplicacao da classe Aplicacao para centralizar um objeto de qualquer subclasse de Window.Ex.:
FameBanco f = new FrameBanco(); Aplicacao.lancaAplicacao(frame);
DialogConta dc = new DialogConta(this); Aplicacao.lancaAplicacao(dc);
Para exemplificar a utilização do iterator, vamos demonstrar seu uso em um certo pacote. Pacote de clientes.O repositório de clientes (Coleção de dados) possui 5 métodos que fornece serviços para a coleção de negócio (Cadastro).
public interface RepisitorioClientes { public void inserir(Cliente cliente); public void remover(int codigo); public void atualizar(Cliente cliente); public boolean existe(int codigo); public Cliente procurar(int codigo); }Com esses cinco métodos nós podemos cadastrar clientes, remover, atualizar, obter dados de um cliente a partir de seu código, podemos verificar se existe um cliente com um certo código.
- E se quisermos imprimir na tela o nome de todos os clientes do meu repositório?
- E se quisermos invocar um método em cada um dos clientes?
Nestes casos a solução é criar um objeto que forneça serviços para acessarmos todos os clientes do repositório de forma sequencial. Para isto, apenas dois métodos são necessários:
public interface IteratorClientes{ public boolean hasNext(); public Cliente next(); }Onde o método public Cliente next() só deve ser invocado se o método public boolean hasNext() retornar um valor true. O método hasNext() informa se ainda tem clientes para ser referenciado. Portanto, se houver invoque o método next() que retorna uma referência para o próximo cliente.
Com esses dois métodos podemos referenciar todos os clientes de forma sequencial e uniforme.
Exemplo:
IteratorClientes iteratorClientes = repositorioClientes.getIterator(); Cliente cliente = null; while (iteratorClientes.hasNext()) { cliente = iteratorClientes.next(); System.out.println(cliente.getNome() + "\n"); }Perceba que não é necessário saber como o iterator é implementado, o importante é que os dois métodos funcionem corretamente, e observando isso, podemos imaginar uma certa implementação para ele.
Observe que o método IteratorCliente getIterator() do repositorio retorna uma referência de uma interface. Já o objeto que implementa tal interface pode conter vários métodos que ajudem na sua implementação, mas quem utiliza o mesmo só enxerga e só precisa dos 2 métodos publicados pela interface.
Exemplo:
public class IteratorClientesArray implements IteratorClientes { public IteratorClientesArray() { ... } public Cliente next() { // implementacao da interface ... } public boolean hasNext() { //implementacao da interface ... } public void x() { // metodo que me auxilia na implementacao ... } private void y() { // metodo que me auxilia na implementacao ... } public adicionar(Cliente cliente) { // metodo que me auxilia na imlementacao ... } }O método IteratorClientes getIterator() deve estar presente dentro da definição da classe que implementa o repositório de clientes, porque é lá onde temos realmente acesso aos objetos, pois se o repositório de clientes foi implementado utilizando um array de Clientes, podemos, neste caso, ter acesso a cada um deles percorrendo o array. Se a implementação foi feita em Lista simplesmente encadeada, temos acesso aos objetos da lista de forma recursiva ou até mesmo de forma iterativa.
Exemplo de como implementar o método IteratorClientes getIterator() na classe RepositorioClientesArray:
public IteratorClientes getIterator() { IteratorClientesArray iterator = new IteratorClientesArray(); ... //temos que preencher o iterator antes de retornar return iterator; }Se não preenchermos o iterator, o método hasNext() sempre retornará false, e o método next() não poderá ser invocado.
Devemos implementar o método public void adicionar(Cliente cliente) na classe IteratorClientesArray que será responsável por preencher o iterator antes de retornar-lo. O método adicionar(Cliente) deverá ser invocado tantas vezes quanto for o número de objetos dentro do repositório, como no exemplo a seguir.
public IteratorClientes getIterator() { IteratorClientesArray iterator = new IteratorClientesArray(); //-------inicio do preenchimento do iterator for (int i = 0; i < quantidadeObjetos; i++) { iterator.adicionar(clientes[i]); } //-------fim do preenchimento do iterator return iterator; }Caso o repositório de clientes seja implementado em lista:
public IteratorClientes getIterator() { IteratorClientesArray iterator = new IteratorClientesArray(); carregaIterator(iterator); return iterator; } public carregaIterator(IteratorClientesArray iterator) { if (this.cliente != null) { iterator.adicionar(this.cliente); this.proximo.carregaIterator(iterator); } }
Este padrão de projetos tem como objetivo garantir que apenas uma instância de um objeto seja criada. Isto é util para impedir que várias instâncias da fachada sejam criadas gerando inconsistências no projeto.
- Torne o construtor da classe private
- Defina a seguinte variável estática na classe: private static NomeDaClasse singleton
- Defina o método estático a seguir que será responsável por instanciar um objeto da classe apenas uma vez.
public static NomeDaClasse getInstance() { if(singleton == null) { singleton = new ...; } return singleton; }- Agora é so acesar a instância única da classe da seguinte forma: NomeDaClasse.getInstance()
- Normalmente a prova da disciplina tem 3 ou 4 questões.
- Sempre têm questões práticas e teóricas.
- A prova é baseada no assunto dado em sala e no projeto desenvolvido durante o semestre.