Estou pesquisando as alternativas para um projeto de sistema distribuidos.
(Depois de 2 meses tentando SOAP…ficarei com RMI mesmo)
A minha duvida é a seguinte: vou precisar das 3 camadas:
a) Business Object: para validação e regras de negocios
b) Transfer Object ( DTO, VO ou o que inventarem…) para serializacao
c) DAO: para persistencia dos dados (nao vou usar EJB).
Meu problema vai ser com certeza a manutencao do sistema, principalmente nas camadas do BO e VO (por exemplo: se alterar
um campo no banco de dados, terei que sair procurando propriedades,
gets e sets respectivametne)
Camadas BO e VO serem totalmente independentes, usando
propriedades explicitas.
public class Pessoa {
private String nome;
public void setNome(String nome) {
// validacoes e regras de negocios aqui.
this.nome = nome;
}
public String getNome() {
return nome;
}
}
// quanto mais leve, melhor....
public class PessoaVO {
private String nome;
public void setNome(String nome) {
this.nome = nome;
}
public String getNome() {
return nome;
}
}
Extender a classe BO da VO:
// quanto mais leve, melhor....
public class PessoaVO {
private String nome;
public void setNome(String nome) {
this.nome = nome;
}
public String getNome() {
return nome;
}
}
public class Pessoa extends PessoaVO {
// normalmente o override dos metodos vai nos set.
public void setNome(String nome) {
if (nome != null && nome.length() < 50)
this.nome = nome;
}
}
Alternativas exoticas: tais como usar HashMap para as propriedades (tentei fazer isso, mas achei pior).
public class Pessoa {
HashMap properties;
public Pessoa() {
properties = new HashMap();
properties.put("nome",null);
}
public setProperty(String key,Object value) {
if ( ! properties.contains(key))
throw new RuntimeException("A propriedade nao existe: " + key);
properties.put(key,value);
}
}
Já passei por esse mesmo dilema e só solucionei a parte de persistência quando comecei a usar Hibernate para persistencia.
É um framework tranquilo de usar e já tem tag XDoclet especialmente para ele.
Se você usa Eclipse, tem vários plugins interessantes para criação e uso do XDoclet. Eu uso o JBossIDE porque trabalho com EJB, mas com certeza existem outros plugins que o pessoal poderia citar.
Pode acreditar, o tempo de estudo compensa, principalmente em um projeto que seus requisitos podem ser alterados em um período de curto prazo.
Agora, sobre o BO, por que não usar EJB ? Você poderia usar o BMP como BO e manter o seu DAO usando Hibernate.
Sinceramente, não tenho idéia de como implementar um BO em um sistema distribuído sem usar EJB!
Não estou usando EJB, por varios fatores, mas principalmente porque
o sistema é de pequeno porte. Serão no máximo umas 30 entidades, e
uns 50 usuários simultaneos. Além disso, EJB para mim é a “ultima fronteira”: estudei quase tudo…só faltou EJB (motivado até pela
reação de várias pessoa, inclusive nesse forum, sobre a dificuldade
de implementacao dos EJB).
A intenção é manter o sistema mais simples e leve possivel, facilitando
o desenvolvimento e principalmente manutencao, pois as regras
de negocios alteram muito.
Infelizmente, eu vejo muitas duvidas sobre DAO e DTO. Sobre a camada
Business Object e validacoes , eu vejo muito poucas duvidas e SOLUCOES.
Então, estou trabalhando em um projeto que deverá ser desenvolvido sem EJB, ou seja, terei q tomar as mesmas decisões que vc. Que tal continuarmos discutindo ?
Para persistencia estou implementando o DAO na estratégia Factory utilizando o padrão Abstract Factory, assim o sistema estará pronto para, por exemplo, caso precisarmos trocar a persistência de DB para XML.
Os meus TO’s são classes com as propriedades dos objetos e seus gets e sets. Esses são os únicos tipos de objetos que estarão transitando entre minha camada de negocio, controle e apresentação.
Um exemplo seria:
public class PessoaTO {
private String nome;
private GrupoTO grupo;
public void setNome(String nome) {
this.nome = nome;
}
public String getNome() {
return nome;
}
public void setGrupo(GrupoTO grupo) {
this.grupo = grupo;
}
public GrupoTO getGrupo() {
return grupo;
}
}
Agrupei meus Casos de Uso por negócio para poder criar meus BOs. Esses ainda não projetei direito, mas estou pensando em colocá-los no contexto da aplicação. Eles implementariam as regras de negócio e receberiam os TO’s necessários para as tomadas de decisão.
Um exemplo seria:
[code]
public class Pessoa {
public void novaPessoa(PessoaTO pessoa) throws BusinessException {
if(pessoa.getGrupo()==null){
throw new BusinessException(" Usuario deve pertencer a um grupo!");
}
SystemDAOFactory mysqlFactory = SystemDAOFactory.getDAOFactory(SystemDAOFactory.MYSQL);
PessoaDAO pessDao = mysqlFactory.getPessoaDAO();
pessDao.insert(pessoa);
}
}[/code]
O que você acha?
Gente, sugestões e críticas são muito bem vindas, pois todos aqui estamos aprendendo!
Vc tem sua classe PessoaTO, declarando as propriedades, gets e sets…
Vc. tem sua classe Pessoa, declarando as propriedades, gets e sets…
Vc nao acha que são muitas re-digitacao de codigo e gets e sets ?
Imagine se vc. tiver umas 30 entidades…A alternativa B, que descrevi acima, oferece uma forma de minimizar este problema.
Fazendo Pessoa extender PessoaTO, vc economiza uma quantidade
consideravel de codigo. Vc. nao precisa re-declarar as propriedades,
e so altera os metodos que vc quiser.
Nao inventei esse padrao, estou descrevendo do seguinte livro:
J2EE Best Practices - Java Design Patterns, Automation and Performance
Tenho ele em PDF, se quiser te mando por email.
Acho correto também passar ValueObject como parametro. Sugiro que
faça isso através de uma interface (como se faz com as classes da
interface List).
public interface ValueObject {
// sem nada mesmo
}
public interface BusinessObject {
public void create(ValueObject properties) throws BusinessException;
public void store() throws BusinessException;
public void findByPrimaryKey(int id) throws BusinessException;
public void validate() throws ValidationException;
...
}
public class PessoaVO implements ValueObject, Serializable {
protected int id;
protected String nome;
protected int grupoId;
... // gets e sets.
}
public class Pessoa extends PessoaVO implements BusinessObject {
private Grupo grupo; // essa é a unica propriedade declarada aqui
public void create(ValueObject properties) throws BusinessException{
this.id = (PessoaVO) properties.getId();
this.nome = (PessoaVO) properties.getNome();
this.grupoId = (PessoaVO) properties.getGrupoId();
grupo.load(this.grupoId);
}
... // continua
}
Somente um detalhe na implementacao da sua classe PessoaTO.
Tenho um livro “Java Enterprise Best Practices” que sugeri que os TO
sejam o mais plano possiveis. No seu caso, dentro de PessoaTO existe
um objeto da classe Grupo. O recomendado é vc. passar apenas o "id"
do Grupo no TO.
Isso mata sua hierarquia de classes. Pense no básico: Um objeto pessoa É UM PessoaVO? Duvido que seja (mesmo porque VO não costuma existir no mundo real…).
Por que você não coloca um objeto Pessoa como atributo do DTO? E por que não pensamos em algo para usar no lugar de DTO?
O VO (dto ou to) é necessário pois será um sistema distribuido. O VO
seria serializado e des-serializado através da Internet. Se eu “colocar um
objeto pessoa como atributo do DTO” , o custo dessa operacao sera muito maior.
Já tentei nao usar VO. A alernativa foi criar um HashMap com as propriedades do objeto. Do ponto de vista “orientacao a objetos” isso é mais absurdo que a situacao que te falei.
O que estou procurando é criar minha classe o mais reutilizável possivel para que possa ser utilizada tanto em um sistema distribuido ou nao.
Pensando dessa forma, EJB podem ser a melhor (e talvez) unica solucao.
[quote=“Comazzi”]O VO (dto ou to) é necessário pois será um sistema distribuido. O VO
seria serializado e des-serializado através da Internet. Se eu “colocar um
objeto pessoa como atributo do DTO” , o custo dessa operacao sera muito maior.
[/quote]
Não tem nada a ver uma cosia com outra, seu sistema pode ser distribuído e não usar DTO.
Colocar pessoa como atributo de DTO só é custoso se você manter seu objeto pessoa real no servidor e usar um proxy como atributo, o que não foi o sugerido.
Fazendo BO extender DTO, você está fazendo sua camada de negócios depender da de aplicação (inferior depender da superior), isso é bem pior.
Mesmo assim, se você definir objetos de negócio corretamente e fugir da salada de padrões oficiais, vai conseguir um bom projeto.
Crie objetos de negócio reais, e não EJB com lógica de negócio. Aliás, EJB não é solução para nada que tenha visto na vida, muito menos a única
estou em um projeto para desenvolver um sistema de medio porte.
O sistema será executado em aprox. 20 filiais. A intencao eh centralizar
a base de dados na Matriz (a base eh Oracle).
A grana é curta. Temos na empresa um pequeno projeto usando
o Windows Terminal Service. Porém para cada usuario precisaria
de R$ 500,00 de licenca (sao quase 80 usuarios, se fosse mais barato
já tinha resolvido meu problema).
Como a grana eh curta, o meio de comunicacao eh internet mesmo
(ADSL nas pontas, e link com embratel na matriz)
O sistema cair por algumas horas nao eh problema. Nao preciso
rodar o sistema “desconectado”.
O sistema exige uma interface boa. Além disso preciso de imprimir
formularios continuos…entao, descarto de cara HTML. A intencao eh
mesmo um aplicativo Swing acesso dados remotos.
6 Já tentei SOAP… nao deu certo. Alias pessima escolha de ferramenta
para um projeto que envolva mais que dois servicos…perdi 2 meses
atras disso.
Estou tentando RMI, usando CommandObjects e ServiceLocator (com cache de stubs…um esquema até que legal). Porém é muito codigo.
Estava pensando em EJB. Dessa forma eu deixo essa parte de servico
para o “framework”.
Eh isso…o que vcs acham ? Vcs. acham que um projeto usando RMI se comporta bem em projetos maiores ?
Talvez hj eu optaria por um servlet sendo responsável pelo Controller, e acessaria este servlet através de HttpURLConnection ou commons-HttpClient assim minha interface poderia ser Swing sem nenhum problema! Se vc der uma olhada no fórum verá q essa solução foi muito falada e até já fiz alguns testes que se comportaram muito bem…
Entretanto na empresa onde trabalho estamos utilizando EJBs.
Temos apenas dois SessionBeans, um com a função de executar métodos nos BOs e outro q serve de factory para criar proxys dos BOs no lado cliente. Até o momento está se portando muito bem! ahh, e abandonamos completamente os VOs, os mesmos fizeram com que o código necessário fosse muito maior e o ganho foi muito pequeno (para não se dizer nulo!!)
Mas é claro que essas soluções se aplicaram adequadamente no meu caso, mas não sei se poderão lhe ajudar…
RMI é plumbing. 99% das soluções distribuídas em Java usam RMi ou HTTP, então sim, ela se aplica, mas RMI sem uma abstração fica um saco.
É uma boa idéia manter Session Beans como fachada para objetos de negócio. Seus Business Objects deveriam ser POJO semrpe que possível, e você pode usar um Hibernate ou outro framework para persistência (fuja de CMP).
Toda esta solução envolve conhecimento sobre EJB, Projeto OO e o frameworkd de persistência. Nada muito caro/complicado