Varias Classes usando o mesmo objeto

Eu acho que a pergunta é até meio descabida, mas eu não estou conseguindo entender a lógica disso; seguinte:

Eu tenho uma classe escola que tem uma list contendo objetos. Eu usarei essa list em varios lugares do meu código, em outras classes, mais especificadamente em varias telas swing, aonde eu devo instanciar o objeto do tipo escola contendo a minha list para que eu possa usar nas diversas telas?
Pela lógica eu penso que não posso instanciar em cada tela um novo objeto escola, porque seria uma nova list, e não teria os mesmos objetos. Outra coisa não há herança entre minhas telas, por isso eu não herdo a list. Ou seja eu preciso criar um unico objeto do tipo escola e usa-lo por todo o meu código.

Valeu pessoal.

Olá Menkauren,

Para acessar uma instância de uma classe de vários outras classes, é mais simples você utilizar um padrão de projeto chamado Singleton.


http://javafree.uol.com.br/topic-852515-Implementando-o-singleton.html

[]s

Renato

Cara, valeu sua dica foi boa demais!!!

Errado…

Dog dog = new Dog();
List<Dog> list1 = new ArrayList<Dog>();
List<Dog> list2 = new ArrayList<Dog>();
list1.add(dog)
list2.add(dog)

Temos duas listas, objetos diferentes, que contêm o mesmo objeto (dog)

No seu caso, acho q vc vai usar isso só pra mostrar o dog na tela… então não há nem a necessidade de serem os mesmos objetos, basta que sejam “iguais” (possuem os mesmos valores em seus atributos, definido pelo método equals)

Bom, no último parágrafo fiz algumas suposições sobre seu problema, q podem estar erradas, mas talvez vc não precise compartilhar os mesmos objetos pelas telas, a menos q não possa recuperar novamente a fonte de dados q formou os objetos ou q o processamento para gerar esses objetos seja mt custoso.

Talvez mereça uma esplicação melhor:
Eu tenho uma classe Escola, essa classe tem uma lista de cursos, que é outra classe minha. Então eu imagino que tenha que criar uma instancia de escola para usar no meu cadastro de cursos, onde eu crio o curso e adiciono na lista que esta no meu objeo escola. Mas eu também tenho um cadastro de aluno onde tem uma combobox com os cursos que eu cadastrei lá no meu cadastro de curso, pelo que eu imagino para que eu possa recuperar os meus cursos cadastrados e jogar na combobox eu tenha de usar o mesmo objeto escola, por que se eu criar uma nova instancia de escola a lista vira vazia. A minha pergunta é onde criar a instancia de escola, já que nenhuma tela minha estende outra e eu preciso compartilhar a mesma lista entre elas.

Vc não tá usando um banco de dados pra salvar tudo oq vc cadastra?

Ou se vc fecha o programa perde tudo?

Se vc salvar tudo no banco… vc recuperar tudo oq precisar a partir fo banco em casa tela

Não. É trabalho da faculdade, não pode usar banco. É uma aplicação simples, quando fecha perde tudo.

Já q é pra fazer bem simplizinho, vc pode fazer sua lista como um atributo estático de alguma classe, aí todo mundo acessa essa lista de forma estática…

Você pode usar o (argh) padrão Singleton. Ou pode passar sua lista por parâmetro para as várias classes que a utilizam.

A segunda opção é mais trabalhosa, mas gera menos bugs (embora numa aplicação simples dessa, dificilmente você terá problemas com o Singleton, só é bom já pegar o hábito de não usa-lo).

Por exemplo:
Eu tenho minha tela principal, eu posso instanciar o objeto escola na tela principal e depois passar para as outras telas que são JInternalFrame, mas as modificações que eu fizer nesse objeto dentro das outras classes irão modificar o meu objeto criado lá na minha tela principal. Como se fosse um parametro passado por referencia.

[code]import model.Escola;

public class Principal extends javax.swing.JFrame {
Escola escola = new Escola();
public Principal() {
initComponents();
}

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         
    Alunos aluno = new Alunos("Aqui eu passo minha escola");
    dp_desktop.add(aluno);
    aluno.setVisible(true);
}

}[/code]

Aqui tenho a classe aluno que foi chamada conforme o codigo acima:

[code]public class Alunos extends javax.swing.JInternalFrame {
Escola escola;

public Alunos(Escola escola) {
    this.escola = escola;
    initComponents();
}
.
.
.
Aqui eu uso e faço as modificações no meu objeto.

}[/code]

A questao é:
As modificações que eu fizer dentro da minha classe Alunos não ira surtir efeito no objeto escola que foi criado lá na minha classe Principal, correto??

[quote=ViniGodoy]Você pode usar o (argh) padrão Singleton. Ou pode passar sua lista por parâmetro para as várias classes que a utilizam.

A segunda opção é mais trabalhosa, mas gera menos bugs (embora numa aplicação simples dessa, dificilmente você terá problemas com o Singleton, só é bom já pegar o hábito de não usa-lo).[/quote]

Ola ViniGodoy, desculpa a pergunta, mais pq vc nao gosta do padrao Singleton?
E so uma pergunta, eu fiquei curioso.

At

[quote=beowulf][quote=ViniGodoy]Você pode usar o (argh) padrão Singleton. Ou pode passar sua lista por parâmetro para as várias classes que a utilizam.

A segunda opção é mais trabalhosa, mas gera menos bugs (embora numa aplicação simples dessa, dificilmente você terá problemas com o Singleton, só é bom já pegar o hábito de não usa-lo).[/quote]

Ola ViniGodoy, desculpa a pergunta, mais pq vc nao gosta do padrao Singleton?
E so uma pergunta, eu fiquei curioso.

At[/quote]

A pergunta foi pra o ViniGodoy e tenho certeza que ele escreverá uma resposta bem melhor que a minha. Mas acho que ele quis passar o conceito de injeção de dependências. Esse conceito é interessante para vc fazer um código mais testável. Usar um Singleton pode tornar sua classe intestável.

Ex clássico: suponhamos que vc cria uma infra para mandar mails. Então vc cria uma interface que represente e envie mails:

public interface MailInterface { void enviarMail(); }

Aí então vc implementa um mail real, como Singleton, que envia para um monte de pessoas:

[code]package ex;

public class MailReal implements MailInterface {
private static final MailInterface instance = new MailReal();

static public MailInterface getInstance() {
	return instance;
}

@Override
public void enviarMail() {
	System.out.println("Enviando mail para 1000000 de pessoas");
}

private MailReal() {
	super();
	// TODO Auto-generated constructor stub
}

}[/code]

Aí então vc cria um gestor de mail:

[code]package ex;

public class GestorDeMail {
public void enviarMail() {
MailReal.getInstance().enviarMail();
}

static public void main(String[] args) {
	GestorDeMail gestor = new GestorDeMail();
	gestor.enviarMail();
}

}
[/code]

Legal, tudo funcionando e vc não cria vários mails reais apenas um. Mas e se vc kiser testar esse código aí? Vai enviar email pra uma porrada de gente em cada teste? e se para enviar pra tanta gente demorar uns 40 minutos? Vc vai esperar todo esse tempo só pra testar? Então o uso do Singleton de dentro da classe GestorDeMail, vc inviabilzou a realização de testes.

Aí entra a injeção de dependencias. Em vez do Gestor instaciar as classes que precisa, elas são injetadas nele. vamos refatorar. Vamos fazer com que a interface seja injetada através de um método set. Aí a gente precisa injetar a instancia da interface antes de executar. Perceba que estou utilizando a verdadeira refatoração, isto é, alterando o código de forma que ele continue fazendo a mesma coisa, e só a mesma coisa:

[code]package ex;

public class GestorDeMail {
private MailInterface mail;

public void setMail(MailInterface mail) {
	this.mail = mail;
}

public void enviarMail() {
	mail.enviarMail();
}

static public void main(String[] args) {
	GestorDeMail gestor = new GestorDeMail();
	gestor.setMail(MailReal.getInstance());
	gestor.enviarMail();
}

}
[/code]

Agora a instancia é fornecida de fora da classe. Eu até continua injetando a dependecia através de um Singleton, mas minha classe GestorDeMail agora é testável. Isso eu considero um bom uso de Singleton, só que o pessoal não costuma ver muito isso pois em geral é usado um Conteiner para injetar dependêcias, como o Spring.

Mas cade o caso do teste que estou falando? Vamos a ele. Primeiro eu crio uma interface só para testar, que em geral é chamada de Stub, quando não executa nenhuma lógica, e Mock quando executa alguma lógica. Vou usar um Stub:

[code]package ex;

public class MailStub implements MailInterface {
@Override
public void enviarMail() {
System.out.println(“Manda mail só pra mim, pra não incomodar os outros”);
}
}
[/code]

Aí então agora eu posso criar uma classe para testar o Gestor:

[code]package ex;

public class TestarDeGestor {
/**
* @param args
*/
public static void main(String[] args) {
GestorDeMail gestor = new GestorDeMail();
gestor.setMail(new MailStub());
gestor.enviarMail();
}
}
[/code]

Perceba que agora eu consigo testar a classe, coisa que não seria possível com a primeira versão do GestorDeMail. Em geral o pessoal usa frameworks para testes e para produzir os mocks. Mas o importante é o conceito, não as ferramentas.

Espero que o exemplo clarifique as coisas.

[]s

[quote=renzonuccitelli][quote=beowulf][quote=ViniGodoy]Você pode usar o (argh) padrão Singleton. Ou pode passar sua lista por parâmetro para as várias classes que a utilizam.

A segunda opção é mais trabalhosa, mas gera menos bugs (embora numa aplicação simples dessa, dificilmente você terá problemas com o Singleton, só é bom já pegar o hábito de não usa-lo).[/quote]

Ola ViniGodoy, desculpa a pergunta, mais pq vc nao gosta do padrao Singleton?
E so uma pergunta, eu fiquei curioso.

At[/quote]

A pergunta foi pra o ViniGodoy e tenho certeza que ele escreverá uma resposta bem melhor que a minha. Mas acho que ele quis passar o conceito de injeção de dependências. Esse conceito é interessante para vc fazer um código mais testável. Usar um Singleton pode tornar sua classe intestável.

[/quote]

Muito obrigado pela explicacao.