Poder ou Simplicidade?

28 respostas
saoj

Tenho a mania de trocar poder por simplicidade. As vezes isso me ajuda, as vezes atrapalha. Mas uma coisa eu não tenho dúvida: Aumenta e muito a produtividade!

A complexidade e o receituário de EJB me deprimem.

Hibernate eu não conheço muito ainda, mas já dei uma olhada e achei legal. Entretanto eu tenho uma outra mania que é não gostar de arquivos de configuração, principalmente arquivos XML. Será que um dia haverá programadores que não precisam programar, mas apenas configurar arquivos XML ??? Essa idéia não me agrada e embora um arquivo de configuração XML traga flexibilidade eles acabam cortando o meu prazer de programar.

Então para a minha camada de persistência (Objetos -> DB) eu resolvi escrever meu próprio framework o mais simples possível e sem arquivos de configuração.

Apesar de simples, ele fornece o indispensável, por exemplo, ele só faz update dos campos que foram modificados, suporta transações, entre outras coisas.

O que vcs acham? Uso esse DBBean (veja código abaixo) ou melhor aprender Hibernate e começar a configurar os arquivos XML ???

import java.sql.SQLException;

import com.smartjava.dbbean.DBBean;
import com.smartjava.dbbean.DBField;
import com.smartjava.dbbean.DBType;
import com.smartjava.dbpool.ConnectionHandler;

public class Profile extends DBBean { // ou MySqlDBBean ou OracleDBBean 
    
    private static final ConnectionHandler connHandler = ConnectionHandler.getInstance("profile");
    
    private DBField id = new DBField(this, DBType.AUTOINCREMENT, "id", true);
    private DBField username = new DBField(this, DBType.STRING, "username");
    private DBField deleted = new DBField(this, DBType.BOOLEAN, "deleted");
    
    public Profile() {
        super.setConnectionHandler(connHandler);
    }
    
    // função abstrata obrigatória...
    public String getTableName() { return "profiles"; }
    
    public void setId(int id) {
        this.id.setValue(id);
    }
    
    public int getId() {
        return id.getIntValue();
    }
    
    public void setUsername(String username) {
        this.username.setValue(username);
    }
    
    public String getUsername() {
        return username.getStringValue();
    }
    
    public void setDeleted(boolean deleted) {
        this.deleted.setValue(deleted);
    }
    
    public boolean isDeleted() {
        return deleted.getBooleanValue();
    }
    
    public static void main(String [] args) throws SQLException {
    	Profile p1 = new Profile();
    	p1.setId(1);
    	p1.setUsername("soliveira");
    	p1.insert();
    	
    	Profile p2 = new Profile();
    	p2.setId(1);
    	if (p2.load()) {
    		System.out.println("USERNAME: " + p2.getUsername());
    	}
    	p2.setUsername("saoj");
    	p2.update();
    	
    	Profile p3 = new Profile();
    	p3.setId(1);
    	if (p3.load()) {
    		System.out.println("USERNAME: " + p3.getUsername());
    	}
    	p3.delete();
    }
    
}

28 Respostas

Luca

Olá

A vantagem de usar frameworks hype é que, como todo mundo o conhece, fica mais facil você entrar em outros projetos ou outros entrarem no seu projeto.

Desenvolver o próprio framework é um ótimo exercício. Mas para virar um framework com alguma utilidade é preciso escrever um monte de documentos, how-tos, faq, user guide, 1-minute/2-hours/3-days introductions, etc. Esse é apenas parte do tamanho da encrenca. A outra parte é encontrar gente e projetos para validar o framework.

Uma outra consideração é que simplicidade é bom até que não atende um determinado caso e precisa de um puxadinho. Mais ou menos como acontece com casa de pobre. A idéia de configurações externas em xml ou não facilitam a expansão do framework sem precisar escarafunchar o código para ver onde há interferências.

Putz, faltou falar que o que fez parece bonitinho.

[]s
Luca

saoj

“Luca”:
Olá

A vantagem de usar frameworks hype é que, como todo mundo o conhece, fica mais facil você entrar em outros projetos ou outros entrarem no seu projeto.

Acho mais fácil capacitar minha equipe nesse framework mínimo aí em cima do que no Hibernate. Acredito que a produtividade com o DBBean vai ser bem maior do que com o Hibernate. Mas posso estar enganado.

O objetivo não é criar um framework público e sim resolver o meu problema que é: preciso de uma solução simples e eficiente para persistir meus objetos no DB. PRECISO DE PRODUTIVIDADE, ISTO É, O PROJETO É PRA ONTEM !!!

Quando precisar de um puxadinho, isso será feito por fora do framework. Não estou falando de hacks pelo código, mas com a OO e herança vc pode ir fazendo especializações. (Vide MySqlDBBean.java abaixo)

Eu poderia ter criado um arquivo XML para definir os campos do meu bean, aí se eu quisesse incluir ou alterar algum campo eu não precisaria recompilar o código. ISSO É CHATO DEMAIS. Como programador eu prefiro fazer isso:

private DBField id = new DBField(this, DBType.AUTOINCREMENT, "id", true); 
    private DBField username = new DBField(this, DBType.STRING, "username"); 
    private DBField deleted = new DBField(this, DBType.BOOLEAN, "deleted");

Valeu !!! :smiley:

package com.smartjava.dbbean;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public abstract class MySqlDBBean extends DBBean {
    
    public void insert(Connection conn) throws SQLException {
        super.insert(conn);

        DBField f = getAutoIncrementField();
        if (f == null) return;
        
        PreparedStatement stmt = null;
        ResultSet rset = null;
        
        try {
            StringBuffer query = new StringBuffer(100);
            query.append("select last_inserted_id() from ");
            query.append(getTableName());
            
            stmt = conn.prepareStatement(query.toString());
            rset = stmt.executeQuery();
            if (rset.next()) {
                int id = rset.getInt(1);
                f.setValue(id);
            }
        } finally {
            try { stmt.close(); } catch(Exception e) { }
            try { rset.close(); } catch(Exception e) { }
        }
        
    }
}
jack_ganzha

Bem interessante o teu framework mas ele parece atar demais as classes de modelo de forma intrusiva. Eu particularmente gosto de frameworks tão pouco intrusivos quanto possivel. O Hibernate é assim, o OJB parece ser tambem. Se vc não gosta de escrever codigo XML, uma boa pedida seria escrever tags XDoclet e deixar uma tarefa do Ant fazer o resto do serviço. :wink:

valeuz…

saoj

Fala Jack,

Me explica melhor o que vc quer dizer com intrusivo ???

Quanto mais genérico, mais complexo é o framework.

Um abraço,

Sergio

cv1

Antes de mais nada, eu daqui em diante declaro que esta thread nao mais conterá a palavra ‘framework’. Só pq eu posso. :mrgreen:

Gostei bastante da ideia, saoj, mas… (sempre tem um ‘mas…’, ou ninguem teria partido para solucoes de implementacao bem mais complexa como o Hibernate):

:arrow: Voce esta fazendo relacionamentos, queries e tudo mais na unha. Isso ta longe de ser produtivo, e eh esse um dos problemas mais dificeis que o hibernate resolve.

:arrow: Estender DBBean, MySQLDBBean ou o que for eh simplesmente impraticavel. Se voce nao se deu conta do estrago que isso faz, tente fazer um sistema com um domain model maiorzinho :wink:

:arrow: Singleton no ConnectionHandler. AAAAAAAARGH! O JUnit acabou de chorar, ali no cantinho.

:arrow: DBType: pra que ter constantes (AUTOINCREMENT, STRING, etc e tal), se vc poderia ter AutoIncrementType, StringType, etc e tal? O problema, eh claro, que em nenhum dos casos vc esta levando em consideracao tipos customizados. Mas ateh aih, pouquissima gente (ehrhm, eu) usa custom types.

:arrow: O que acontece se eu precisar pegar um porrilhão (vamos entender que ‘porrilhão’ é um número beeeeeeem grande) de registros? Como voce implementaria lazy-loading num modelo desses?

jack_ganzha

“saoj”:

Fala Jack,

Me explica melhor o que vc quer dizer com intrusivo ???


Sergio, vc teve que atar seu modelo ao esse tipo de implementação. Mesmo mantendo os metodos de acesso com tipos primitivos, a implementação está emparelhada com o framew… uops, erhm, do que eu vou chamar agora? Note por exemplo o metodo chamado getTableName() que é obrigatorio. Por que seu modeo deve conhecer a forma de persistencia? Bom, compare com uma classe de dominio assim:

import java.io.Serializable;
public class Profile implements Serializable {
   
    private int id;
    private String username;
    private boolean deleted;
   
    public void setId(int id) {
        this.id.setValue(id);
    }
   
    public int getId() {
        return id.getIntValue();
    }
   
    public void setUsername(String username) {
        this.username.setValue(username);
    }
   
    public String getUsername() {
        return username.getStringValue();
    }
   
    public void setDeleted(boolean deleted) {
        this.deleted.setValue(deleted);
    }
   
    public boolean isDeleted() {
        return deleted.getBooleanValue();
    }
}

Isso vai bem do Hibernate ao Prevayler, não?

valeuz…

saoj

Valeu pelas dicas !!! O objetivo do meu post era esse mesmo: ouvir críticas para pesar os dois lados da moeda na minha cabeça.

Relacionamentos eu não utilizo a nível de código, apenas a nível de DB. Então acho que isso não seria um grande problema pra mim. Já as queries eu realmente tenho que fazer na unha, mas isso não me incomoda muito. Alguma coisa eu tenho que fazer na unha mesmo !!! O Hibernate tem uma query language para fazer queries de objetos, né ??? Deve ser legal, mas não conheço nada dela. Já SQL para fazer queries está no sangue. É quase automático!

Tem uma idéia que não é minha que é fazer um ListLoader. Basicamente quando vc quer carregar um conjunto de objetos persistentes (DBBeans) vc encapsula a sua query dentro de um ListLoader e ele te retorna um Array ou uma List de DBBeans.

Não consegui te acompanhar aqui. A idéia do mysqldbbean é que cada banco tem sua especialidade, principalmente no caso de autoincrement. (claro que vc já sabia disso! :smiley: )

Logo vc pode especializar o DBBean para cada banco. DBBean usa ANSI SQL + JDBC para fazer a persistência, logo funciona em qualquer banco!

:cry: :ConnectionHandler encapsula dentro dela um pool de conexões. Assim como cada pool de conexões deve ser um singleton, cada connection handler para aquele pool tb deve ser um singleton. Mas posso estar errado!

Ou na mão. :cry:

Ou através do ListLoader. Outra idéia boa, que tb não foi minha, é do mesmo jeito que vc tem um load(conn) vc pode ter um load(rset).

Então vc pode carregar um monte de DBBeans na mesma query:

select * from profiles where city = 1;
List list = new LinkedList();
while(rset.next()) {
    Profile prof = profileFactory.createProfile();
    prof.load(rset);
    list.add(prof);
}
saoj

Vc tem toda razão que o fw ficaria mais profissional se não se atasse ao banco de dados explicitamente, como eu fiz.

Mas isso aumentaria MUITÍSSIMO a trabalheira para implementar as entranhas desse modelo.

Focando em Banco de Dados, eu consigo fazer um framework sem bugs, simples, enxuto e eficiente.

O DBBean é apenas para Banco de Dados !!! Se vc quiser que o seu profile venha do disco, por exemplo, esse fw não te atende. Mas o Hibernate tb não, né??? O hibernate é especificamente para persistencia em DB, né?

Daniel_Quirino_Olive

Fico feliz por ver que as pessoas não estão simplesmente abaixando a cabeça e aceitando os hypes como soluções definitivas. Mas acho que sua solução foi uma volta ao passado em relação aos mapeadores O/R por todos os motivos que o CV (sem falar que escrever SQL dentro dó código me dá nojo!). Ok, você não gosta de escrever “heurísticas” em XML? Ótimo! Veja como é implementado o mecanismo de leitura de configurações do Hibernate (por exemplo) e proponha a utilização de alguma outra solução (DICA: Bean Shell, usado pelo DynAOP, ou Groovy podem ser soluções bem mais elegantes). Mas acho que o mundo pode dormir melhor a noite sem mais outra explosão de mecanismos O/R surgindo por aí. :wink:

cv1

[Pascoale]voce pode comecar a nao utilizar ‘a nivel de’, pq a nivel de escrever certo, eh bem errado.[/Pascoale]

Se voce nao utiliza relacionamentos, entao onde voce jogou a OO!? Se eu nao posso fazer um Estoque referenciar Produtos, voce acabou de inventar o problema, nao a solucao.

O Hibernate tem uma query language bastante flexivel e pratica. Envergonhe-se de tentar bolar uma solucao alternativa, sem conhecer seu concorrente primeiro :wink:

Tem isso no iBatis e no Spring. De uma olhada neles.

“saoj”:

:cry: :ConnectionHandler encapsula dentro dela um pool de conexões. Assim como cada pool de conexões deve ser um singleton, cada connection handler para aquele pool tb deve ser um singleton. Mas posso estar errado!

Singleton é errado, e não tem desculpa, a menos que vc esteja falando de um recurso que realmente nao pode existir mais de uma vez - por exemplo, uma porta serial. Vide inumeros posts aqui no GUJ sobre isso.

Vide injecao de dependencias, vide unit testing, vide um monte de boas praticas que o design do seu ConnectionHandler nao seguiu ao fazer isso :wink:

saoj

Recomendo a todos o livro: Better, Faster, Lighter Java da O’Reilly:

Fiquei bastante aliviado em constatar que não estou sozinho na luta por SIMPLICIDADE, custe o que custar:

cv1

Existe uma linha muito tenue entre simplicidade e simploriedade. O que voce propos com os DBBeans eh simplorio: ele simplifica alguns casos, e impossibilita a maioria dos outros, enquanto o Hibernate, apesar de ser uma solucao mais complexa que a sua, eh simples: ele facilita os casos mais comuns, e mantem todos os outros nao soh mais faceis, como tambem possiveis.

saoj

Claro!!! Nunca tive a pretensão de competir com o Hibernate. Só quiz fazer o DBBean para resolver de uma maneira bem simples o problema de mapeamento Objeto => DB. O Hibernate resolve esse problema também, de maneira simples, mas não tão simples quanto o DBBean. Em compensação ele te oferece um monte de outras facilidades que o DBBean nem pensou.

O próprio livro que eu recomendei enaltace o Hibernate. Vou procurar estudar mais a fundo o Hibernate, que parece ser a melhor saída para não usar EJB em 90% dos projetos.

Outra coisa que ele fala bastante nesse livro é: “Do one thing, Do it well!”

O DBBean só serve para persistir objetos num banco de dados, de maneira intuitiva, simples e eficiente. E isso ele faz muito bem através de uma API mínima. Dependendo da complexidade do seu projeto e dos skills do seu time, ele pode ser uma opção viável.

O meu último post acabou ficando fora de foco, no meio dessa discussão sobre persistência.

O recado que eu quiz passar, e que é passado nesse livro tb, foi:

Não interessa o que vc faça, faça da maneira mais simples possível. Evite usar uma bazuca para matar uma mosca. Simplicidade é poder!

Y

Creio que mais de um filósofo já disse: a simplicidade é de ouro (traduzindo: a simplicidade é algo muito valioso).
Por outro lado, construir um framework à medida do que seja necessário ao momento pode levar ao risco de em pouco tempo ter-se uma verdadeira colcha de retalhos, por não ter havido um planejamento desde o início considerando futuras necessidades. Além disto há a questão da padronização, cuja utilização em escala facilita ainda mais a manutenção do código que o utiliza, bem como a própria expansão do framework adotado ou desenvolvido.
Mas também creio que alguns frameworks do mercado possam ser mais complexos do que o necessário - mesmo que sejam extremamente flexíveis, será que são necessários para a grande maioria dos casos ?
Assim, será que no mercado já não exista algum framework que seja razoavelmente simples e eficiente, além de ser útil em boa parte dos problemas dentro de seu domínio? Ou, que seja simples para utilização na maioria dos casos, deixando a complexidade para os problemas já normalmente complexos?

F

Olá,

Sei que diretamente o que vou falar não diz muito respeito a discução. Mas o SAOJ irá entendeu o que eu quero falar.
Eu trabalho com DB (entenda-se SQL) a 3 anos, sempre ouvia falar do Hibernate, mas insistia em escrever meus SQL pois achava que eu teria mais performance com isso. Foi um tempo perdido, hoje vejo isso.
Quer ter simplicidade com Hibernate, monte uma boa arquitetura de com ele e não se preocupe mais com isso, ou se preocupe mas quando surgir um caso muito especial.

]['s

Luca

Olá

É comum a gente ver consultas SQL mal feitas porque o programador nem sempre conhece bem tecnologias envolvendo base de dados. Para mim esta é uma das grandes vantagens dos mapeamentos O/R.

E quando a gente vê um cara como o Fábio que sabe tudo de Oracle dizendo que é melhor usar Hibernate então não dá mais para ter dúvida. Hibernate neles!

[]s
Luca

jack_ganzha

Simplicidade importa muito mesmo e em alguns momentos Java peca nisso se comparada a outras coisas. Por exemplo, como fazer o Apache ter suporte a Java? Se for comparado a coisas como Perl, PHP, Python fica bem pra tras em termos de facilidade de comparação. Lembro que, quando comecei a aprender patterns, queria aplica-los em tudo quanto era canto porque, enfim, eu acreditava que era a coisa certa. Hoje é Do The Simplest Thing That Could Possibly Work e pronto! Nada de 10 camadas para escrever um HelloWorld.

Quanto ao Hibernate, ele é simples mesmo e boas ide’s já têm algum tipo de suporte para xdoclet. Assim vc não tem que escrever os seus XML na marra. Vale uma olhada no HiberClipse tambem. :wink:

valeuz…

caiofilipini

Só uma coisinha: se simplicidade é poder, pq o título do seu post é “Poder OU Simplicidade”?

saoj

Eu quiz colher as opiniões da comunidade sem influenciá-la com o meu ponto de vista.

Depois de ler esse livro fiquei ainda mais certo de que simplicidade é muitíssimo importante em qualquer sistema.

Já tentou fazer alguma coisa simples usando EJB ??? Faça e vc entenderá o que é matar uma mosca com uma bazuca !!! :o

louds

Eu vejo que para usar o Hibernate em vez da solução caseira tem que se ponderam dos beneficios/maleficios dele:

-Curva de aprendizado grande, escrever código é muito mais facil que ler; sem falar que o danado tem muita coisa.
-Muito mais preparado para mudanças, com hibernate vc sabe que se tiver uma encrenca maior ele já vai estar pronto para aguentar ela, não vai precisar ser evoluido para novas demandas.
-Performance, lazy loading, eager loading, 2-level caching, yada-yada-yada; fazer isso não é facil e muito menor fazer direito.
-Configuração com XML, eu acho super útil os XMLs, principalmente quando tua aplicação tem que migrar de base de dados. Já fiz isso, inclusive com mudança estruturais significativas, sem precisar mudar 1 única linha de código java.
-Testado, só os bugs que vc não vai precisar lidar com a solução home-grown justificam usá-lo.

Apesar de ser bem hype, ele faz sua função muito bem e eu acho que o a dor de cabeça inicial para aprender a usá-lo se paga rapidamente. Se o problema é aprender, veja com teu chefe a possibilidade de contratar uma empresa de treinamento pra ajudar a equipe a começar.

Rubem_Azenha

afinal de contas, sergio, onde encontramos esse framework aí q vc mostrou?

plentz

Hm, e depois que a equipe toda sair e um estágiário tiver que dar manutenção no sistema? Será que será mais fácil ele aprender Hybernate com toda a documentação que existe por ai ou aprender o seu FrameworkFoo na unha?

saoj

O meu framework é muito simples… Qualquer um aprende em 5 minutos… Como vc pode ver, tudo que vc tem que fazer é definir os seus campinhos que serão replicados no banco e chamar insert, update e delete.

Entretanto, como falaram aqui nesse post ele só sabe fazer isso… É uma solução básica e simples para salvar objetos no banco de dados, daí o nome DBBean… Poderia ser também DBObject…

O Hibernate, por exemplo, é uma solução bem mais completa, e por isso bem mais complexa também…

Cabe a vc decidir o que vc realmente precisa: JDBC, DBBean, Hibernate, EJB, etc…

A regra de ouro que eu costumo usar é: Só use algo mais complexo, se realmente necessitar…

Rubem_Azenha

perfeito! mas onde vc disponibilizou o seu framework?

saoj

Esse framework está sendo usado por um cliente, e não sei se posso disponibilizá-lo. Mas tenho certeza que seria muito diverito e vc aprenderia muito se fizesse o seu próprio framework de persistencia, ou melhor, o seu próprio motor SQL.

Não é difícil! Tudo que vc tem que fazer é definir um DBField, DBType e um DBBean abstrato e construir as funções para gerar os SQL dinamicamente. Não se esqueça de suportar dirty fields, ou seja, vc só dará um update no campo se ele foi modificado.

É um ótimo exercício de OO !!! Vale a pena tentar fazer o seu, embora nada te impessa de usar alguns milhares já prontos por aí…

Rubem_Azenha

ok ok
mas como vc quer tentar nos convercer de que o seu framework é bom se nem podemos ver ele? :smiley:

saoj

microfilo:
ok ok
mas como vc quer tentar nos convercer de que o seu framework é bom se nem podemos ver ele? :D

Vc pode ver a interface, isto é, sua usabilidade. Veja o exemplo de código que eu coloquei no meu primeiro post…

Só quiz defender que é bem simples fazer um motor SQL para salvar objetos no banco… As vezes vc só precisa disso mesmo, outras vezes precisa de hibernate, e outras de EJB…

LuizAvila

microfilo:
ok ok
mas como vc quer tentar nos convercer de que o seu framework é bom se nem podemos ver ele? :D

bocejo

Criado 18 de agosto de 2004
Ultima resposta 6 de jan. de 2005
Respostas 28
Participantes 12