Alexandre,
Muito obrigado. Entendi perfeitamente agora. Basicamente, o Visitor serve
para encapsular uma operação que depende da interface da classe concreta que
é visitada.
O Visitor do seu exemplo, que deve calcular o salário total, depende
claramente da classe concreta do empregado. Neste caso, para calcular o
salário total de Empregado basta pegar o getSalario(), mas para a classe
Chefe é necessário o getSalario() + getGratificacao().
Caso o Empregado e o Chefe tivessem a mesma interface para operações sobre
rendimento, não seria necessario utilizar o Visitor. Mas eles tem interface
diferentes, logo foi feito uma classe SalaryVisitor, que trata
diferentemente objetos Empregado e Chefe.
E a grande malandragem está em o objeto visitado chamar de volta o Visitor
se passando por referência. O comportamento polimórfico do método
visit(Empregado) permite calcular diferentemente o rendimento.
Estou certo? Não percebi algum detalhe?
valeu
Jorge
-----Original Message-----
From: Alexandre Rodrigues Gomes
[mailto:[EMAIL PROTECTED]]
Sent: quarta-feira, 4 de abril de 2001 11:57
To: '[EMAIL PROTECTED]'
Subject: [java-list] RES: Visitor (errata)
Desculpe, mandei o link errado. Este é o correto.
http://www.patterndepot.com/put/8/JavaPatterns.htm
By Alê!
-----Mensagem original-----
De: Alexandre Rodrigues Gomes
Enviada em: quarta-feira, 4 de abril de 2001 11:42
Para: '[EMAIL PROTECTED]'
Assunto: Visitor
vou te dar o exemplo do livro The Design Patterns - Java Compainion.
Suponha que vc tenha um objeto que modele sua empresa. Suponha que
esta empresa seja composta por diversos empregados. Logo, a sua classe
Empresa haverá uma referência para uma Collection de Empregados.
public class Empresa
{
public Empregado[] empregados;
}
public class Empregado
{
protected String nome;
protected int salario;
public String getNome()...
public int getSalario()...
public void setNome()...
public void setSalario()...
}
Agora, suponha que vc queira, por algum motivo, calcular os gastos
da sua empresa com salários. Ora, a abordagem mais natural seria fazer um
laço de repetição que fizesse um somatório dos salários individuais através
do método getSalario() mas, como o que queremos é demonstrar o Visitor,
utilizazá-lo-emos. :o)
A idéia é que tenhamos um objeto que visite todos os empregados da
empresa e vá calculando os custos parciais.
public abstract class Visitor
{
public abstract void visit(Empregado emp);
}
desta forma, podemos criar uma classe mais especializada:
public class SalaryVisitor extends Visitor
{
protected int salarioTotal;
public void visit(Empregado emp)
{
salarioTotal =+ emp.getSalario();
}
public int getSalarioTotal()
{
return salarioTotal;
}
}
O funcionamento é o seguinte: para uma classe ser visitada, ela deve
implementar algum método que possibilite esta visita.
public void accept(Visitor v)
{
v.visit(this)
}
Deu pra entender mais ou meons a idéia ? Para um Visitor visitar
alguém, ele chama o método accept daquele alguém. Por fim, o objeto visitado
retorna uma chamada ao método visit do Visitor passando uma referência de si
mesmo como parâmetro.
+---------+ visited.accept(this) +---------+
| | ----------------------> | |
| Visitor | <---------------------- | Visited |
| | v.visit(this) | |
+---------+ +---------+
Ok, e agora, como faremos as visitas ? Assim, ó:
//No cliente
SalaryVisitor sal = new SalaryVisitor();
for (int i = 0; i < empregados.length; i++)
{
empregados[i].accept(sal);
}
System.out.println("Orçamento com salários = " + sal.getSalarioTotal();
Você deve estar se perguntando por quê devemos implementar o método
visit(Empregado). Considere que existe um tipo de empregado, o Chefe, que
além do salário comum ainda possua uma gratificação:
public class Chefe extends Empregado
{
protected int gratificacao;
public int getGratificacao() { return gratificacao; }
public void accept(Visitor v)
{
v.visit(this);
}
}
Aí o Visit deverá ter algumas modificações
public class SalaryVisitor extends Visitor
{
protected int salarioTotal;
public void visit(Empregado emp)
{
salarioTotal =+ emp.getSalario();
}
public void visit(Chefe chf)
{
salarioTotal = salarioTotal + chf.getSalario() +
chf.getGratificacao();
}
public int getSalarioTotal()
{
return salarioTotal;
}
}
O exemplo não é dos melhores, mas é mais fácil de visualizar a utilização.
Para maiores (e melhores) informações, veja em
http://www.labsoftware.com/Patterns/index.htm
By Alê!
------------------------------ LISTA SOUJAVA ----------------------------
http://www.soujava.org.br - Sociedade de Usuários Java da Sucesu-SP
dúvidas mais comuns: http://www.soujava.org.br/faq.htm
regras da lista: http://www.soujava.org.br/regras.htm
para sair da lista: envie email para [EMAIL PROTECTED]
-------------------------------------------------------------------------