Objeto salva a si mesmo, ou delega esta tarefa?

parece que essa discussao é antiga aqui no forum, mas mesmo pesquisando nao achei nada alem de discussoes desconexas e sem fim … hehehe

o que é melhor ou mais correto, ou uma pratica mais coerente, enfim

isto …

Funcionario func = new Funcionario() func.salvar()

ou talvez

Funcionario func = new Funcionario() ClasseAuxiliar funcAux = new ClasseAuxiliar(); funcAux.Salvar(func);

desculpem caso tenha perguntado alguma absurdidade hehe …
[…]s

Como você mesmo disse, é uma discussão sem fim. Eu sou adepto das classes DAOs. Até hoje não vi uma implementação de ActiveRecord que me convencesse. Ma há quem diga o contrário. Então use a que você melhor de adaptar.

[]'s

Rodrigo C. A.

Como o Rodrigo disse, é uma discussão sem fim…
Eu particularmente prefiro delegar essa terafa para uma camada que faça somente persistência como DAO, pois acho que issnão é u comportamento do objeto de negócios…mas…é uma discussão longa, baseada na preferência de cada um…

entendo, eu particularmante acho mais elegante fazer o proprio objeto salvar a si mesmo … mas eu nao sei se é muito correto, pois teoricamente este objeto deveria se preocupar unica e exclusivamente em efetuar suas funcionalidades, e nao em como ele deveria persistir. lembrando que esta é apenas minha humilde opiniao…

e tbm, eu estou implementando um sistema pequeno, queria fazer desta forma para testar… mas no meio do caminho surgem varias duvidas hehe … devo postar aqui no desenrolar do topico …

enfim, continuem postando suas opinioes!
[…]s

Pense comigo…vc tem uma entidade do tipo “Automovel”, um exemplo esdrúxulo…dentre as funcões de um automóvel estão tipo:

  • acelerar;
  • frear;
  • virar pra esquerda;
  • virar pra direita;

ae vc vem com funções do tipo:

  • persistir;
  • remover;
  • listar;

sinceramente…eu, PESSOALMENTE, costumo seguir a ideologia de Domain Driven Design, onde acho que esse tipo de coisa não se encaixa muito bem…não acho intuitivo.
Abraço!

pra mim soa muito intuitivo, apesar de algo me dizer “NÃO FAÇA ASSIM!!”…

a ideia de utilizar como no seu exemplo

me parece muito boa … mas eu gosto de ouvir a opinião de todo mundo e nunca me convenço de alguma pratica assim tao facilmente ^^ …

mas ai surgem duvidas hehe,
por exemplo, se eu tivesse um metodo

esse metodo retornaria uma nova instancia de automovel ou atualizaria a instancia que o chamou?

devolve uma collecion de automoveis?? sim, ai me parece um pouco estranho …

[…]s

Eu acho q quanto mais desacopladas forem as funções… melhor

Tbm sou adepto dos DAOs… que na verdade costumo utilizar apenas um… default… + a ajuda do Hibernate… pronto… funciona beleza…

Faço isso simplesmente pensando pra frente… imagine um sistema complexo… onde cada objeto eh responsavel por sua persistencia…

Ficaria muito dificil depois de fazer qualquer padronização… o refactor seria muito grande… e sem motivo… já que poderiam estar desacopladas a persistencia dos objetos desde o inicio…

Bem, aí depende do que lhe serve melhor.
Ou você pode colocar em uma classe específica de persistência, como um DAO
Ou seguir o padrão do Martin Fowler conhecido como active record:
http://www.martinfowler.com/eaaCatalog/activeRecord.html
(Que é você colocar os comportamentos e relacionamentos com persistência, dentro do próprio objeto: Pessoa.salvar(), Pessoa.atualizar())

O que eu tenho feito:
Juntado os dois, o objeto tem seu método de persistência, e a implementação deste método, delega para uma classe de persistência a repsonsabilidade.
Ex:

class Pessoa{
void salvar(Pessoa pessoa){
pessoaDAO.salvar(pessoa);
}

Use transações declarativas e pare de se preocupar com isso :wink:

Mas geralmente vai de cada necessidade. Leia o livro do Fowler onde existe uma discussão interessante a respeito.

Rafael nunes, voce chegou no ponto em que eu queria na discussão …

eu iria justamente perguntar se é coerente eu ter minhas DAOS, e ainda assim ter metodos no proprio objeto que façam sua propria persistencia utilizando essas mesmas DAOS …

pcalcado, esse livro que vc me indicou tem na biblioteca da minha universidade hehe, pena que nao pode ser retirado, ta la somente pra consultas … desculpe a ignorancia, transaçoes declarativas??? :frowning:

vlw galera …
a opiniao de voces ajuda a desanuviar um pouco minha mente hehe …
[…]s

Rafael,

Depende…!

Active Record (AR) é interessante para aplicações onde a lógica de negócio não é muito complexa. Por que? Porque esse padrão cria um acoplamento dos seus objetos com a estrutura do banco, tornando seu domain model menos flexivel. Se você precisa lidar com uma lógica de negócio mais complexa, provalmente irá querer fugir da estrutura do seu banco relacional e criar relacionamentos diferentes (e MUITO mais completos) no seu domain model. Nesse caso, se vc estiver usando Domain Model (objetos de domínio que contém dados + comportamentos, em oposição ao Anemic Domain Model), você poderá usar o padrão Data Mapper (atrás de um outro padrão chamado Repository)! Mas se estiver usando Transaction Script, dê uma olhada no TDG (Table Data Gateway). Ah, mas é possível misturar um pouco de Active Record com Transaction Script também, onde todo código orientado a dados estaria no AR, e o resto em Transaction Scripts.

TDG é o que conhecemos por DAO? Bem, mais ou menos! DAO (Data Access Object, catalogado no J2EE Design Patterns) é mais genérico, e não fica preso a um tipo de data source específico (ex. banco). Já o TDG é voltado exclusivamente a bancos relacionais. Aliás, pra mim, DAO tem um significado tão vago que, na prática, é preciso ver se esse “DAO” está servindo apenas para isolar o acesso a dados ou, mais do que isso, fazendo o papel de permitir a troca de implementação do tipo de persistencia (através do uso de Abstract Factory). DAO se parece mais com os padrões Gateway e Repository, ambos catalogados no PEAA (Fowler).

Sou mais um que irá aconselhar a leitura do livro PEAA. Aliás, uma outra boa leitura é o ‘POJO in Action’, que, entre outras coisas, explica como resolver alguns problemas encontrados ao usar Rich Domain Model com frameworks de persistencia e IoC, que é proximo ao cenário que voce descreveu, onde o seu domain model precisa acessar um Repository para persistencia. E se não conhece os patterns do GoF, então esqueça tudo, e comece por ele primeiro!

Confuso? Esse é o mundo da arquitetura… :smiley:
É seu papel, como arquiteto, escolher a arquitetura mais adequada aos requisitos. E, para escolher o próximo da melhor, só conhecendo mesmo os prós e os contras de cada arquitetura.

Ultimamente tenho acompanhado o projeto Active Record, do Castle Project (só que para C#/.NET). Ele trabalha em cima do NHibernate. Pode ser uma boa dar uma espiada, pois é bem simples de entender!

Ah, mais uma outra coisa! Esse seu “Active Record” tá meio esquisito!..
Por que passar um objeto do tipo Pessoa por parametro? Ele nao está atuando na instancia da própria classe Pessoa? Os métodos Finders tudo bem, inclusive eles devem ser implementados como static (static finders), mas os métodos de inserção, atualização, por ex, não tem porque não utilizar a própria instancia! Aliás, o legal no AR é isso, e não criar uma classe que simplesmente mistura um model e métodos do “DAO”. No caso dos métodos finders, é possível separar em uma outra classe, como acontece no Row Data Gateway (do PEAA tambem).

Gerson, vc estava falando com o Rafael nunes certo!??

eu tbm achei essa implementação que ele colocou estranha, acho que ele se enganou …

voce citou muitos termos com os quais nao estou familiarizado hehe … acho bom começar a ler e muito :frowning:

nao sei se é muito interessante … eu estava escrevendo algumas interfaces e tal, modelando algumas coisinhas aqui outras ali … e foram surgindo algumas ideias, e gostaria de saber o que voces acham …

lembrando que to implementando um sistema pequeno … mas que nao é dos mais simples, mas ainda sim é pequeno …

exemplo da minha implementacao …

imaginem essas 2 classes simples aqui …

[code]public class Contato {
private int id;
private String nome;
private String email;
private String telefone;

// getters and setters
}

public class Aluno {

private int id;
private String nome;
            private String endereco;
            ...
            private Lista contatos;

// getters and setters
}[/code]

para utilizar faria desta forma …

[code]Aluno aluno = new Aluno();

aluno.procurar(1);
aluno.getContatos().adicionar(contato1);
aluno.getContatos().adicionar(contato2);
aluno.getContatos().salvar();[/code]

ah, nas minhas implementações estou utilizando muitos casts, isso é uma pratica saudavel!???

[…]s

Nem um pouco interessante, você deveria estar utilizando genéricos :stuck_out_tongue:

Sobre os objetos se salvarem, eu só acho meio “trash” de se fazer em Java. Um exemplo bem interessante é listar os objetos de um certo tipo no banco de dados. Seria ótimo se eu pudesse fazer algo do tipo:

Collection<Aluno> alunos = Aluno.getAll();

E isso não é difícil de se implementar, o problema é que a implementação seria praticamente a mesma se eu fosse fazer isso pra uma classe Professor, por exemplo. Com uma ferramenta de ORM a única mudança que seria necessária seria a alteração do parâmetro com o tipo da classe, só que eu não poderia reaproveitar essa implementação com um método estático entre várias classes diferentes, porque com o método estático eu não tenho como saber em qual tipo este método está sendo invocado, pra reaproveitar a implementação esse método de “trazer todos” teria que ser um método de instância, o que vai deixar o código horrível, porque eu vou ter que instânciar um aluno pra poder trazer todos os alunos do banco de dados.

Acho que se não fossem esses problemas de reaproveitamento de implementação, fazer um ActiveRecord em java seria realmente ótimo.

Eu acho que os objetos de negócio podem ser inteligentes sem ter acoplamento com a persistencia.
Eu acho (e pelo que já li em diversas literaturas) que o exemplo do Rafael é bem próximo de um modelo interessante.
Eu só não colocaria um método que explicitamente faz a persistencia no meu bean.
ex:


class Cliente  {
   public void cadastrar() { // metodo de negócio
       // delega para o DAO.
       ClienteDAO.incluir(this);
  }

  public void fazerPagamento(float valor) { // método de negocio
     Pagamento pagamento = new Pagamento();
     pagamento.setCliente(this);
     pagamento.setValor(valor);

     PagamentoDAO.incluir(pagamento)
  }
}

Cliente cliente  = ClienteDAO.consultar(1);
cliente.fazerPagamento(15.0);

O ideal seria ter herança multifacetada e mixins, de forma a ter o melhor das duas soluções sem os problemas que elas carregam.

Pena que Java não tenha isso :frowning:

[quote=Gerson]Ah, mais uma outra coisa! Esse seu “Active Record” tá meio esquisito!..
Por que passar um objeto do tipo Pessoa por parametro?
[/quote]

Na verdade foi só pra exemplificar de onde veio o objeto pessoa que é passado para o DAO, realmente ficou bem estranha a leitura. Melhor assim:

class Pessoa{ void salvar(){ pessoaDAO.salvar(this); }

Pena que Java não tenha isso :([/quote]

Sim, como não tem, o jeito é fazer o menor comprometimento possivel, que no caso do Java é usar DAOs, na minha opinião.

Também acho, já tentei implementar active records usando AOP, mas o resultado não foi tão simples quando eu queria, principalmente na hora de testar.