faces
domain
persistence
util
Nomenclatura apenas ou alguma razão especifica?
BO = VO auto-suficiente???
onde auto-suficiente seria: Para fazer login ele tem as propriedades necessárias e também sabe como fazer o loning,seria isso?
[quote=antoniopopete][quote=sergiotaborda ]
use domain em vez de bo e persitence em vez de dao.
[/quote]
faces
domain
persistence
util
Nomenclatura apenas ou alguma razão especifica?[/quote]
Domain é muito mais que “BO” (o que quer que isso seja). São repositorios, serviços , entidades e factories
Com esses nomes ou não, se todas as classes que manipulam regras ou dados de negocio estivem aqui fica mais claro.
Dao é um padrão dos possiveis em relação a persistencia. persistencia é mais generico. Ele contém objetos de query , intrepretadores , a interface do dao e um subpacote a implementação para uma tecnologia especifica.
Uma coisa que eu particularmente abomino é nomenclaturas assim
org.xyz.bo.ClienteBO
org.xyz.bo.ClienteVO
org.xyz.dao.ClienteDAO
é meio redundante…
org.xyz.domain.Cliente
org.xyz.domain.AccountService
org.xyz.domain.ClienteRepository
org.xyz.persistence.PersistenceManager
org.xyz.persistence.Criteria
org.xyz.persistence.QueryResult
os nomes dos pacotes devem apresentar com clareza o que está lá dentro
e não devem ser ligados a nenhum dos objetos lá dentro
javax.swing
javax.util.concurrent
javax.security
e não
javax.screen
javax.bloquingqueue
javax.user
antoniopopete,
Se vc se basear em DDD(domain-driven design) sim ele sabe como e onde procurar essa informação.
eu recomendo dar uma olhadinha nesse post: http://www.guj.com.br/posts/list/87774.java os caras tiram mtas duvidas lá. sobre DDD
[quote=antoniopopete]BO = VO auto-suficiente???
onde auto-suficiente seria: Para fazer login ele tem as propriedades necessárias e também sabe como fazer o loning,seria isso?[/quote]
Esse exemplo do login é ruim para explicar o problema dos velhos BO. (digo velhos porque ninguem mais usa isso… certo? 8) )
A questão é a separação de responsabilidade. Quando vc separa demais dá m@#$@#$
A ideia é separar, mas não demais
certo
SecurityService
signIn(User user): Signature
errado
Pessoa
datanascimento
PessoaBO
idade(Pessoa p, Date data): int
No primeiro o usuário não tem responsabildiade de se logar isso é um trabalho para o serviço de segurança.
No segundo o calculo da idade depende do proprio atributo privado da pessoa.
O segundo pode ser movido para Pessoa, o primeiro não pode ser passado para User.
P.S. “Não pode ser movido” significa “a responsabilidade não pode ser movida” e não “o codigo não pode ser movido”
[quote=sergiotaborda][quote=antoniopopete][quote=sergiotaborda ]
use domain em vez de bo e persitence em vez de dao.
[/quote]
faces
domain
persistence
util
Nomenclatura apenas ou alguma razão especifica?[/quote]
Domain é muito mais que “BO” (o que quer que isso seja). São repositorios, serviços , entidades e factories
Com esses nomes ou não, se todas as classes que manipulam regras ou dados de negocio estivem aqui fica mais claro.
Dao é um padrão dos possiveis em relação a persistencia. persistencia é mais generico. Ele contém objetos de query , intrepretadores , a interface do dao e um subpacote a implementação para uma tecnologia especifica.
Uma coisa que eu particularmente abomino é nomenclaturas assim
org.xyz.bo.ClienteBO
org.xyz.bo.ClienteVO
org.xyz.dao.ClienteDAO
é meio redundante…
org.xyz.domain.Cliente
org.xyz.domain.AccountService
org.xyz.domain.ClienteRepository
org.xyz.persistence.PersistenceManager
org.xyz.persistence.Criteria
org.xyz.persistence.QueryResult
os nomes dos pacotes devem apresentar com clareza o que está lá dentro
e não devem ser ligados a nenhum dos objetos lá dentro
javax.swing
javax.util.concurrent
javax.security
e não
javax.screen
javax.bloquingqueue
javax.user
[/quote]
A nível de código…Fica mais claro CleinteDAO,CLienteBO…ou não?
Se você dividir a regra de negócio por objetos, talvez prefira…
org.xyz.domain.Cliente
org.xyz.domain.AccountService
org.xyz.domain.ClienteRepository
org.xyz.persistence.Client
org.xyz.persistence.Criteria
org.xyz.persistence.PersistenceManager
Dai vc teria uma classe ‘Client’ para persistir o objeto ‘Client’ da camada de negócios… acho que serve melhor para ‘documentar’ seu código, mas tudo depende de uma metodologia a ser abordada por todo o time de desenvolvimento.
PS: Acho que “A NÍVEL DE” não corresponde a um Design Pattern da gramática portuguesa.
[quote=zwingli]Se você dividir a regra de negócio por objetos, talvez prefira…
org.xyz.domain.Cliente
org.xyz.domain.AccountService
org.xyz.domain.ClienteRepository
org.xyz.persistence.Client
org.xyz.persistence.Criteria
org.xyz.persistence.PersistenceManager
Dai vc teria uma classe ‘Client’ para persistir o objeto ‘Client’ da camada de negócios… acho que serve melhor para ‘documentar’ seu código, mas tudo depende de uma metodologia a ser abordada por todo o time de desenvolvimento.
[/quote]
Só que ai vc tem duas classes com o mesmo nome e quando tiver que escrever
Cliente cliente ;
cliente.persist(cliente);
fica meio confuso…
Nem tanto ao mar, nem tanto à terra…
Não. Dao é um padrão não é uma classe. Não faz sentido chamar algo de DAO… o mesmo para DTO, VO, BO, etc… fora que depois vc tem que escrever esses sufixos a toda a hora… Tudo bem, para DAO até que passa, mas para os outros é pura perda de tempo.
O objeto centrar é a entidade e ele deve ter o nome simples: Cliente. O resto deve ter um nome que designa o que ele faz a esse objeto. ClientRepository : repositorio de clientes , AccountService : serviço relacionados a contas …
Mas o ponto não era esse. O ponto é que o nome do pacote não deve ser o nome de nenhum das classes dentro dele e sim o nome do aspecto do problema que o pacote “resolve”. segurança, log, serviços, dominio, etc…
rs[quote=zwingli]
PS: Acho que “A NÍVEL DE” não corresponde a um Design Pattern da gramática portuguesa
[/quote]
Mas para quem lê o codigo, vai ver um Client recebendo um Client.Ficaria meio estranho, tudo bem que descreve no pacote, mas você ler o pacote para saber o que a classe é, não fica tão interessante assim.
[quote=sergiotaborda][quote=antoniopopete]BO = VO auto-suficiente???
onde auto-suficiente seria: Para fazer login ele tem as propriedades necessárias e também sabe como fazer o loning,seria isso?[/quote]
Esse exemplo do login é ruim para explicar o problema dos velhos BO. (digo velhos porque ninguem mais usa isso… certo? 8) )
A questão é a separação de responsabilidade. Quando vc separa demais dá m@#$@#$
A ideia é separar, mas não demais
No primeiro o usuário não tem responsabildiade de se logar isso é um trabalho para o serviço de segurança.
No segundo o calculo da idade depende do proprio atributo privado da pessoa.
O segundo pode ser movido para Pessoa, o primeiro não pode ser passado para User.
P.S. “Não pode ser movido” significa “a responsabilidade não pode ser movida” e não “o codigo não pode ser movido”
[/quote]
Cara vc esta confundindo muito as coisas. Vamos lá:
Primeiro estou um pouco decepcionado com o fato de o pessoal estar tão apegado a nomes: BO, Domain, Model é tudo a mesma coisa. (Ponto final eu espero)
Todos eles tratam da regra de negócio, cabe a vc não criar classes anêmicas, com forte acoplamento e baixa coesão. Isso vem da Orientação a Objetos e não são meia dúzia de Design Patterns que vão mudar essa velha idéia.
DAO é um pattern da Core JEE Patterns e é muito usado e muito conhecido. Provavelmente pq ele é um bom Pattern.
BO + VO + DTO são Patterns para sistemas distribuídos que não é o caso aqui.
PORÉM é preciso de uma classe que represente a regra e ela tem que representar algo do mundo real ou o mais próximo disso (DDD).
Boim eu vou parar por aqui pq essa thread esta indo longe demais por nada.
boa sorte no seu projeto Antonio…
O jeito é ter Cliente e ClienteDAO
Se não nos apegarmos as definicoes ficamos sem saber diferenciar os conceitos.
Há muito tempo Value Objects deixaram de ser isso!
Não são não. BO é uma forma de solucionar um problema, domínio é problema que sua aplicação resolve e model é um modelo, que pode ser expresso por BOs ou Não. Um Domain Model, é uma alternativa ao BO.
Pela importância entre as diferenças é que este apego à nomenclatura é importante.
Errado. Um BO é uma “classe de lógica”, que fere Orientação a Objetos.
Um pattern é “bom” ou “ruim” apenas quando relacionado à um contexto, não há comoa firmar que o DAO por si só é bom ou ruim. E ser famoso nunca tornou anda bom, aliás.
Dos que você citou apenas DTO é para sistemas distribuídos.
Fui pesquisar sobre os Patterns da Sun e achei BO, a pergunta dessa thread é se ainda é válido usar BO + DAO. Então segundo o catalogo da Sun esse lance de BO fica atrás da Session Facade. E a definicção da Sun para BO é:
BusinessObject
The BusinessObject is a role object that facilitates applying different strategies, such as session beans entity beans and a DAO (see the next section, “Strategies”). A BusinessObject provides data and/or some service in the class diagram. The SessionFacade interacts with multiple BusinessObject instances to provide the service.
https://cis.med.ucalgary.ca/http/java.sun.com/blueprints/corej2eepatterns/Patterns/index.html
Então pcalçado quando eu digo que o Pattern DAO é bom, sim isso depende do meu problema e se ele resolve o meu problema de forma elegante, mas talvez por ignorância eu DESCONHEÇO qualquer outro Pattern que faça esse papel de ?espelhe? meus objetos com meu banco de dados.
Desses três tipos de classes BO + VO + DTO apenas DTO/TO é para sistema distribuído como você mesmo disse. Eu errei nessa afirmação.
Domínio segundo o que você disse (domínio é problema que sua aplicação resolve) refere-se à aplicação toda.
Modelo refere-se a uma parte do domínio e pode ser representada por um BO.
Quando estamos criando nossos pacotes precisamos nomeá-los de acordo com o aspecto que as classes representam então meu pacote com os modelos poderia chamar-se tanto:
br.com.empresa.modelo
quanto
br.com.empresa.BO
mas nunca
br.com.empresa.dominio (por que domínio refere-se ao sistema todo)
Quando você diz Um Domain Model, é uma alternativa ao BO. Um BO representa uma classe de negócio QUE contêm lógica, não concordei quando você disse que um BO É uma classe de lógica. Lógica esta presente em todas as partes(na minha opnião). E o Domain Model veio para trazer nossos objetos mais próximo ao modelo de negócio, mas não consegui entender como desenvolver uma classe real de Domain Model, mesmo após ler esse artigo no wikipedia.
[/]'s
Então no caso de uma boa arquitetura, teremos classes domains que contém as propriedades dos objetos do domínio do sistema e nessas mesma classes teremos as lógicas de negócio desses objetos?
Eu pensei depois do que li aqui em montar a arquitetura da seguinte maneira:
dominio
----persistencia
------exceptions
----pojos (objetos,get/set)
classes de negocio ficariam dentro do pacote dominio
faces
util
Na classe util, teria uma classia BeanFactoryHelper ,idéia sugerida por um colega daqui do GUJ (du123)
E esse helper faria chamado aos daos do spring que usariam templates do hibernate para criar os objetos.
Ai faria as chamadas da seguine maneira
faces->dominio (como serviços,precisaria de uma interface?)->persistencia
transitando o pojo referente ao domínio…
Exemplo na tela de inserção de uma instituição…
como uso jsf ,eu teria um atributo do faces InstituicaoModel que passaria ele preenchido para o serviço que invocaria a classe helper para obter o dao correto e faria a persistencia…
no caso de existirem regras de negócio, as faria na chamada do faces.
Em cascata, faria chamada de serviços, para cada classe de serviço…
O aplication-context do spring ficou assim:
[code]<?xml version="1.0" encoding="UTF-8"?>
<bean id="dataSourceMonografias"
class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName"
value="org.gjt.mm.mysql.Driver" />
<property name="url"
value="jdbc:mysql://localhost:3306/monografias" />
<property name="username" value="root" />
<property name="password" value="popete" />
</bean>
<bean id="sessionFactoryMonografias"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSourceMonografias" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">
org.hibernate.dialect.MySQLDialect
</prop>
<prop key="current_session_context_class">thread</prop>
<prop key="cache.provider_class">
org.hibernate.cache.NoCacheProvider
</prop>
<prop key="show_sql">true</prop>
<prop key="connection.pool_size">10</prop>
</props>
</property>
<!--
<property name="mappingClass">
<list>
<value>br.ucsal.projeto.model.AutorModel</value>
<value>br.ucsal.projeto.model.CursoModel</value>
<value>br.ucsal.projeto.model.InstituicaoModel</value>
<value>br.ucsal.projeto.model.DocumentoModel</value>
</list>
</property>
-->
<property name="mappingDirectoryLocations">
<list>
<value>classpath:/br/ucsal/projeto/model</value>
</list>
</property>
</bean>
<bean id="hibernateTemplate"
class="org.springframework.orm.hibernate3.HibernateTemplate">
<property name="sessionFactory">
<ref bean="sessionFactoryMonografias" />
</property>
</bean>
<bean id="instituicaoDao"
class="br.ucsal.projeto.dao.impl.InstituicaoDAOImpl">
<property name="hibernateTemplate">
<ref bean="hibernateTemplate" />
</property>
</bean>
<bean id="autorDao"
class="br.ucsal.projeto.dao.impl.AutorDAOImpl">
<property name="hibernateTemplate">
<ref bean="hibernateTemplate" />
</property>
</bean>
<bean id="cursoDao"
class="br.ucsal.projeto.dao.impl.CursoDAOImpl">
<property name="hibernateTemplate">
<ref bean="hibernateTemplate" />
</property>
</bean>
<bean id="documentoDao"
class="br.ucsal.projeto.dao.impl.DocumentoDAOImpl">
<property name="hibernateTemplate">
<ref bean="hibernateTemplate" />
</property>
</bean>
[/code]
e o BeanHelper ficou assim:
[code]package br.ucsal.projeto.util;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class BeanFactoryHelper {
public static ApplicationContext contexto;
static{
contexto = new ClassPathXmlApplicationContext(ProjetoConstantes.ARQUIVO_CONFIG_SPRING);
}
private BeanFactoryHelper() {
}
public static ApplicationContext getInstance(){
return contexto;
}
public static Object getBean(String bean){
return contexto.getBean(bean);
}
}[/code]
bem como um exemplo de um dao
[code]package br.ucsal.projeto.dao.impl;
import java.util.Collection;
import org.springframework.dao.DataAccessException;
import org.springframework.orm.hibernate3.HibernateTemplate;
import br.ucsal.projeto.dao.AutorDAO;
import br.ucsal.projeto.model.AutorModel;
public class AutorDAOImpl implements AutorDAO {
private HibernateTemplate hibernateTemplate;
@SuppressWarnings("unchecked")
public Collection<AutorModel> findAll() throws DataAccessException {
return this.hibernateTemplate.loadAll(AutorModel.class);
}
public void delete(AutorModel autorModel) {
this.hibernateTemplate.delete(autorModel);
}
public AutorModel get(AutorModel autorModel) {
return (AutorModel) this.hibernateTemplate.get(AutorModel.class,
autorModel.getId());
}
public AutorModel load(AutorModel autorModel) {
return (AutorModel) this.hibernateTemplate.load(AutorModel.class,
autorModel.getId());
}
public AutorModel save(AutorModel autorModel) {
return (AutorModel) this.hibernateTemplate.save(autorModel);
}
public void update(AutorModel autorModel) {
this.hibernateTemplate.update(autorModel);
}
public HibernateTemplate getHibernateTemplate() {
return hibernateTemplate;
}
public void setHibernateTemplate(HibernateTemplate hibernateTemplate) {
this.hibernateTemplate = hibernateTemplate;
}
}[/code]
e de utilziação da arquitetura:
[code]package br.ucsal.projeto.faces;
import java.util.ArrayList;
import java.util.List;
import javax.faces.model.SelectItem;
import br.ucsal.projeto.bo.InstituicaoBO;
import br.ucsal.projeto.model.CursoModel;
import br.ucsal.projeto.model.InstituicaoModel;
public class CadastroMapaFaces {
private CursoModel cursoModel;
private List<SelectItem> instituicoes;
private List<SelectItem> cursos;
private InstituicaoBO instituicaoBO;
public CadastroMapaFaces() {
instituicaoBO = new InstituicaoBO();
this.limpar();
}
private void limpar() {
this.cursoModel = new CursoModel();
this.cursoModel.setInstituicaoModel(new InstituicaoModel());
this.getInstituicoesCadastradas();
this.cursos = new ArrayList<SelectItem>();
}
private void getInstituicoesCadastradas() {
this.instituicoes = new ArrayList<SelectItem>();
for (InstituicaoModel instituicaoModel : this.instituicaoService.findAll()) {
this.instituicoes.add(new SelectItem(instituicaoModel.getId()
.toString(), instituicaoModel.getSigla()));
}
}
public CursoModel getCursoModel() {
return cursoModel;
}
public void setCursoModel(CursoModel cursoModel) {
this.cursoModel = cursoModel;
}
public List<SelectItem> getInstituicoes() {
return instituicoes;
}
public void setInstituicoes(List<SelectItem> instituicoes) {
this.instituicoes = instituicoes;
}
public List<SelectItem> getCursos() {
return cursos;
}
public void setCursos(List<SelectItem> cursos) {
this.cursos = cursos;
}
}
[/code]
e então?O que acham?
[quote=Giulliano]Fui pesquisar sobre os Patterns da Sun e achei BO, a pergunta dessa thread é se ainda é válido usar BO + DAO. Então segundo o catalogo da Sun esse lance de BO fica atrás da Session Facade. E a definicção da Sun para BO é:
BusinessObject
The BusinessObject is a role object that facilitates applying different strategies, such as session beans entity beans and a DAO (see the next section, “Strategies”). A BusinessObject provides data and/or some service in the class diagram. The SessionFacade interacts with multiple BusinessObject instances to provide the service.
https://cis.med.ucalgary.ca/http/java.sun.com/blueprints/corej2eepatterns/Patterns/index.html
[/quote]
Logo…?
Sim, procure ler o Pattern of Enterprise Application Architecture e voc6e vai ver outros meios de persistir objetos -DAO não espelha nada, ele mapeia.
Isso Não faz o BO "a mesma coisa"que domínio.
Não existe regra ou mesmo padrão para nomenclatura de pacotes. Se você quer boas instruções sobre o tema leia Robert C. Martin.
[quote=Giulliano]
Quando você diz Um Domain Model, é uma alternativa ao BO. Um BO representa uma classe de negócio QUE contêm lógica, não concordei quando você disse que um BO É uma classe de lógica. Lógica esta presente em todas as partes(na minha opnião). E o Domain Model veio para trazer nossos objetos mais próximo ao modelo de negócio, mas não consegui entender como desenvolver uma classe real de Domain Model, mesmo após ler esse artigo no wikipedia.
[/]'s[/quote]
http://www.fragmental.com.br/wiki/index.php?title=Evitando_VOs_e_BOs
Então no caso de uma boa arquitetura, teremos classes domains que contém as propriedades dos objetos do domínio do sistema e nessas mesma classes teremos as lógicas de negócio desses objetos?
[/quote]
Uma boa arquitetura é aquela que cumpre seu objetivo com eficiência. Existem casos onde usar BO/TO faz sentido (apesar de sinceramente não lembrar de nenhum) e existemc asos onde Domain Model faz sentido.
O problema BO/TO vs Domain Model que você vai ver no fórum é que todas as vezes que eu já vi alguém usando BO neste fórum e em qualquer outro lugar era porque a pessoa não entendia que esta não deve ser a primeira opção.
Respondendo a pergunta: Sim, isso seria um bom design a princípio, mas o que é certo ou errado depende do contexto.
Voc6e está desenhando uma arquitetura ou pacotes? Para desenhar a arquitetura o ideal é você se expressar através de padrões arquiteturais, apenas olhando uma hierarquia de pacotes não me diz muito, não dá para opinar nada.
Não sei porque a pessoa sugeriu isso mas… qual o problema em ter uma Façade que através de AOP ou anotações faz commit na sessão após ser executada?
Em momento algum eu disse que existem regras para nomes de pacotes, até onde me lembro o nome dos pacotes deveriam seguir o padrão:
br.com.MinhaEmpresa.
br.org.MinhaEmpresa.
edu.MinhaEmpresa.
e após xxx.xxx.MinhaEmpresa
.DAO
.BO
.utils
.POJO
Vou dar uma pesquisada em outros patterns além do DAO. Provavelmente quando o DAO não resolver os meus problemas de mapeamento(isso nunca aconteceu). Quando eu escrevi espelhar escrevi entre “aspas”, por algum motivo não apareceram. Não achei a palavra certa para descrever a função do DAO naquele momento.
BO e Domínios são difrentes. Talvez algumas excessões (Num sistema que só existe uma classe Cliente e esse sistema só cadastra Clientes, a minha classe Cliente será meu Dominio e ao mesmo tempo meu Modelo, certo?)
Quanto ao Logo?
Eu sugiro o uso de BOs e DAOs. Não só eu como a própria Sun que embora não seja referência para Patterns ainda sim possui algumas idéias legais.
[quote=Giulliano]
Eu sugiro o uso de BOs e DAOs. Não só eu como a própria Sun que embora não seja referência para Patterns ainda sim possui algumas idéias legais.[/quote]
A existência de um modelo de Business Objects no EJB 1.x-2.x oi um dos grandes motivadores para a existência do EJB3, qu preza por um Domain Model. A Sun não recomenda mais objetos burros há algum tempo, os Core Patterns são beeeeem antigos.
Mas é claro que o ato de X ou Y não recomendarem ou condenarem não significa que todos tenham que fazer isso mas seria legal se você desse seu parecer de em qual cenário e porque um BO seria melhor que um Domain Model.
[quote=Giulliano]
Vou dar uma pesquisada em outros patterns além do DAO. Provavelmente quando o DAO não resolver os meus problemas de mapeamento(isso nunca aconteceu).[/quote]
m comentário quanto a isso: é sempre bom ler sobre outras opções mesmo quando você não precisa delas. Da mesma forma que uma chave de fenda serve para fazer quase qualquer coisa o DAO resolve qualquer problema de persistência. O problema é que se você não sabe que existe um martelo vai perder muito tempo fixando pregos com a chave de fenda, é possível mas existem opções melhores.
Livros de padrões são geralmente chatos e difíceis de ler mas eu recomendo que se leia pelo menos um padrão aleatório por semana, nunca se sabe quando eles serão úteis.