Como usar Transfer Object?

O que voce chama de objetos super-dotados?

O que voce chama de objetos super-dotados?[/quote]

Implicitamente: são objetos com muitos comportamentos.
O que nos leva a uma chamada recursiva nos topicos “programação procedural - objetos burros” , que só pode ser finalizada quando todos souberem que objetos são formados por comportamentos + dados.

Essas tópicos longos com opniões diferentes são o bicho. xD .

Nem sempre é preciso utilizar patterns. Mesmo quando utilizadas, suas patterns não precisam ser identicas ao do autor do livro ou artigo, é preciso saber ser flexivel e toma-las como uma base segura para a sua propria criação. Ou utilizar tim tim por tim tim se ela “te cair como uma luva”.

A grande dificuldade que eu vejo nas duvidas comoe sta eh uma soh: separar responsabilidades.

[quote=faq]
Nem sempre é preciso utilizar patterns. Mesmo quando utilizadas, suas patterns não precisam ser identicas ao do autor do livro ou artigo, é preciso saber ser flexivel e toma-las como uma base segura para a sua propria criação. Ou utilizar tim tim por tim tim se ela “te cair como uma luva”.[/quote]

O mesmo com paradigmas (como OOP), a questao eh que ate agora, neste ou em tantos outros topicos, ainda nao vi um caso onde realmente fosse rpeciso adaptar os conceitos drasticamente.

Por isso são patterns.

[quote=carneiro]Para mim sempre foi regra que: aluno.save() é ruim!
[/quote]

Dependendo de como você vai fazer, pode ser bom ou ruim. Eu, por exemplo, implementei o Active Record (o padrão que botaria o “save()” no aluno) com uma única interface (usando AOP) e sem adicionar uma linha de código nas classes do modelo (o Aluno, Turma, Disciplina, Produto ou seja lá o que for).

O que você tem que garantir é que a coisa seja maleável, que seja fácil de dar manutenção e de testar (não ficou tão fácil de testar quanto eu pensava, entretanto…).

Como ja mencionei algumas vezes aqui, ao inves de AR puro e simples, eu prefiro uma abordagem baseada em Observers.

Quando o objeto muda de estado (ou quando recebe um .svae(), mais pratico e usavel) ele avisa seus observadores, o DAO, Repositorio, whatever eh um destes.

IMHO, se seu objeto estiver super dotado é pq ele tem responsabilidade demais, e ele entaum poderia ser quebrado em mais classes de negócio. Assim, todos seus objetos se manteriam simples!

Mas pq ficou mais difícil de testar? Por causa do AOP? Ou por causa do ActiveRecord?

Quando eu testo, eu apenas passo um mock para minha classe de negócio, e no final do teste verifico se o método dao.save(aluno) foi realmente chamado e se recebeu o objeto correto por parâmetro.

UserStorie userStorie = null;
Mock mockPM = null;

public void setUp() {
	userStory = new UserStory("Saving a user story");
	userStory.setContent("XPTurbine must save user stories.");
	userStory.setEstimatePoints(2.5f);
	
	mockPM = new Mock(PersistenceManager.class);
}
	
public void testSaveUserStorie() {		
	mockPM.expectVoid("save", userStory);
	
	ReleaseManager manager = new ReleaseManager();
	manager.setPersistenceManager((PersistenceManager)mockPM.proxy());
		
	manager.saveUserStory(userStorie);	
}

public void tearDown() {
	mockPM.verify();
}

Entaum, baseado no exemplo acima, apesar de não ser exatamente um AR, acredito que testar um AR não deve ser muito diferente disso!

Estou errado?:smiley:

Abraços!
Thiago

Thiago, o singular de “user stories” eh “user story” :wink:

Valeu Carlos, vou arrumar os lugares onde cometi este pequeno deslize! :smiley:

Por causa da AOP, o meu código não fica nas classes do modelo como o seu. É difícil de explicar :lol:

Quando você mexer no AspectJ vai entender :mrgreen:

[quote=pcalcado]Como ja mencionei algumas vezes aqui, ao inves de AR puro e simples, eu prefiro uma abordagem baseada em Observers.

Quando o objeto muda de estado (ou quando recebe um .svae(), mais pratico e usavel) ele avisa seus observadores, o DAO, Repositorio, whatever eh um destes.[/quote]

Isso parece legal, mas quais as vantagens em cima de uma simples chamada ao DAO/Repository/WTFory?

[quote=LIPE]
Isso parece legal, mas quais as vantagens em cima de uma simples chamada ao DAO/Repository/WTFory?[/quote]

Imagina seu Façade:

void createNewBugbear(){
  bugBear b = bugBearFactory.create();
  b.save();
}

Ou

void createNewBugbear(){
  bugBear b = bugBearFactory.create();
  bugBearDao.save(b);
}

Fora que assim você poderia passar seu objeto diretamente à camada cliente e ela salva-lo quando apropriado (ainda não pensei sobre isso direito).

Não expressei minha dúvida corretamente. Gosto sim de AR, o que te perguntei foi relacionado à aplicação de Observer :smiley:

Ah tah :stuck_out_tongue:

Você pdoe até não usar um observer:

class Bugbear{
  BugBearRepository home = null;

 public BugBear(BugBearRepository home){
   this.home=home;
 }

 public save(){
  home.save(this);
 }

}

Mas eu prefiro algo mais genérico:


//TODO: Extract Superclass

class Bugbear{
  List<Observer> myObservers = new ArraylList<Observer>();

 public void register(Observer o){
   myObservers.add(o);
 }

 public save(){
  for(Observer observer : myObservers)
    observer.notify(this);
 }

}

Não consigo imaginar um real bom motivo para observers quando você só tem um observer, mas não consigo gostar da primeira estratégia :frowning:

hehe foi esse lance de um Observer que pensei Shoes.

Disso aqui você não gosta?

[code]
class BugBear {
private Repository home;

public void installRepository( Repository home ) {
    this.home = home;
}

public void save() {
    home.save( this );
}

}[/code]

Se sim, por quê?

É disso mesmo :P.

Os repositórios ficam entre os clientes (BugBearManager) e o domínio e referenciar uma camada superior de uma inferior é problema (e isso já deu uma bela discussão na lista de domaindrivendesign).

Se você colocar repositórios como observadores, elimina essa relação baixo-cima com uam abstração.

Aí na minha humildérrima opinião é perfumaria à toa. Além de gerar outro problema: como diferenciar os diferentes métodos a serem chamados no Repository sendo que com Observer tudo o que pode se fazer é um notify?

se protege do olhar assassino de Shoes

:evil: :evil: :evil:

Ok, mas se tiver algum outro observador, eu padronizaria isso

void notify(Object objeto)
if(objeto no sgbd)
 update(objeto);
else
 save(objeto);

Complexidade?

Isso é fácil quando utilizando o Hibernate.

E o delete()? E se o método create() deve retornar a chave primária? E no caso de load()?

[quote=LIPE]
E o delete()? E se o método create() deve retornar a chave primária? E no caso de load()?[/quote]

O Repositorio continua existindo apra estas coisas :wink:

A coisa toda é evitar que todo método de uma interface XYZManager fique salvando o bojeto toda hora (se você rpecisa usar dois ou mais destes num caso de uso, se ferra).