Ir para conteúdo

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Andrey Knupp Vital

Mapper, SQLBuilder, Model .. Integração

Recommended Posts

Carinhas, eu tenho uma dúvida que está me perturbando, no mini-fw que estou fazendo para utilizar nos meus projetos, estou com um problema na parte relacionada ao mapeamento, na verdade, problemas eu ainda não tive em relação a isto, mas é uma dúvida de implementação, eu tenho o seguinte code ( demonstrativo ), também não sei se a implementação está certa, mas ..

 

<?php
      abstract class Mapper {

             private $model ;

             final public function __construct ( ) {
                    if ( $this instanceOf Model ) {
                           $this->model = $this ;
                           if ( ! isset ( $this->model->_table ) ) {
                                  # [ Hahahah, Exception mané ] 
                           }
                    }
             }

             public function save ( DomainObject $domainObject )  ;

             public function update ( DomainObject $domainObject )  ;

             public function delete ( DomainObject $domainObject )  ;

      }

      abstract class Model extends Mapper {



      }

      abstract class DomainObject {

             private $_fields = array ( ) ;


             public function getFields ( ) {
                    return ( array ) $this->_fields ;
             }

             public function addField ( $fieldName , $value ) {
                    $this->_fields [ $fieldName ] = $value ;
             }

      }

 

Estes aí são os componentes que serão utilizados por uma model , e por uma entidade .. logo, essas minhas classes que irão extender a Mapper e DomainObject, terão acesso aos métodos addField ( utilizado nos setters da entidade ) e o save, update, delete ..

 

Perfeito, porém, a dúvida: O mapper extende o banco, ou o banco extende o mapper, porque, eu posso ter um mapper para PgSQL, MySQL .. em que a sintaxe talvez varie, não faz muito sentido pra mim o banco extender o mapper, porque não é o banco quem usa o mapper, e sim o mapper que usa o banco ..

 

Tem também a questão do escritor de SQL, quem iria utilizar ele ? o model também pode ter acesso a este, porque no model eu também posso escrever métodos que o mapper não provê, daí a SQL também seria diferente.

 

<?php
      class Customers extends Model {

             protected $_table = 'Clientes' ;

      }

      class ClientsEntity extends DomainObject {

             private $nome ;

             public function getNome() {
                    return $this->nome ;
             }

             public function setNome( $nome ) {
                    $this->nome = $nome ;
                    $this->addField('nome', $this->getNome());
             }


      }

      $customer = new CustomersEntity();
      $customer->setNome('teste');

      $customers = new Customers();
      $customers->save( $customer ) ;

 

Ou, no model eu deveria ter um método

setDatabaseConnection ( Connection $connection )

 

?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Se eu entendi direito como o Mapper funciona, já que todos os padrões ligados à BD mais do que à outros problemas pareceram meio complicados pra mim, o Mapper USA uma conexão com banco de dados, mas essa necessidade por si só não justifica uma herança.

 

Sendo assim, sua última opção parece ser a mais sensata. De fato eu também a uso pois, até que me ensinem o melhor jeito, preciso da herança disponível para prover métodos como where(), limit() e etc tanto à Mapper::insert(), Mapper::update() e Mapper::delete() como para Mapper::select() que é instância de uma classe própria.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Como eu disse, cada SGBD tem seu mapper próprio, no caso eu vou ter dois, pra PostGres, e MySQL .. são os bancos que utilizo, nesse caso, seriam dois mappers que utilizam a conexão, mas agora eu pensei bem .. e se a conexão do outro banco for em um outro servidor por exemplo ? ou eu tiver setar uma outra conexão na qual o mapper não estaria relacionado.

 

O setDatabaseConnection então fica como melhor opção, mas diz aí, como você faz pra sua model ter acesso aos métodos do escritor de querys ?

 

Nem sempre a sintaxe vai variar, o que torna o mapper um pouco tanto eficaz .. mas ainda sim a melhor opção para esse tipo de coisa, e da mesma forma que eu terei outras models, não é necessário criar um Mapper para CADA model, por isso a definição das propriedades na model já vão ficar definidas, como _table, _map ( para o método find ( padrão ) ), entre outros relacionamentos, como eu terei os métodos ->getParentRow ( Foreign Key Mapping ) etc ..

Compartilhar este post


Link para o post
Compartilhar em outros sites

Quase perdi sua resposta... :P

 

Atualmente, parte da minha estrutura é:

 

abstract class AbstractMapper extends AbstractQuery implements Mapper {

   // Interface Methods Implementation

   public function select() {}

   public function insert() {}

   public function update() {}

   public function delete() {}

   // Abstract Methods Definition

   abstract protected getAdapter();

   // Accessors

   public function getTableName() {}

   public function getFields() {}
}

Os métodos de Interface trabalham com as informações que AbstractMapper::getFields() fornecem, que são, no caso do insert() os campos a serem inseridos e do update() àqueles que serão atualiazados, não importando a ordem.

 

O delete() usa apenas o nome da tabela e o select() é apenas um wrapper que retorna uma instância da minha classe Select.

 

Esse wrapper serve apenas para Models que precisam de um CRUD completo, de ponta a ponta. Se parte da aplicação precisar apenas listar informações, dispesa-se a herança à AbstractMapper podendo estender diratemanente Select ou apenas usá-la, através de instância em propriedade.

 

Tanto AbstractMapper quanto Select estendem AbstractQuery, também abstrata como o nome sugere, que possuei os métodos comuns à todas as operações: where(), orWhere(), order(), limit()...

 

Esses métodos também são apenas métodos de Interface pois eles mesmos não montam a query final.

 

Quem de fato a monta é AbstractQuery::assemble() que identifica as partes da query escolhidas e que deverão ser construídas e invocam, na falta de um nome melhor, o renderizador léxico apropriado.

 

Esse renderizador léxico possui, com algumas exceções, praticamente os mesmos métodos de interface de AbstractQuery e Select juntos e fornecem, com base nos seus parâmetros, as strings que de fato farão parte da query.

 

E, finalmente, aquilo que deve lhe interessar, cada adaptador tem seu próprio renderizador léxico.

 

Como todo adaptador estende de AbstractAdapter tenho nela o método abstrato setRenderer() o quaçl atribui à uma propriedade, no construtor, o objeto do renderizador associado àquele adaptador.

 

Um accessor para essa propriedade também existe, obviamente, afinal, sem ele AbstractQuery e Select nao teriam como trabalhar.

 

E sendo assim, já cada SGBD tem seu próprio renderizador, tenho apenas um único Mapper e um único construtor de queries, que suportam tantos SGBD's quantos adaptadores e renderizadores eu quiser ou puder criar.

 

Claro, aí também existe reutilização de renderizadores. Por exemplo, o renderizador de SQLITE, até o presente uso que tenho dele, é idêntido ao de MySQL, dispensando duplicação.

 

Porém, enquanto os nomes de campos no MySQL devem, até para evitar conflitos, ser envolvidos por crases, no SQLITE não pode.

 

E como usar uma aspa simples também faz com o retorno seja diferente do esperado, o adaptador de SQLITE usa o mesmo do MySQL, porém define o quote identifier como sendo aspa dupla.

 

Falei demais, mas espero que tenha te dado uma luz.

Compartilhar este post


Link para o post
Compartilhar em outros sites

@Andrey Knupp

 

Você está construindo um mini-framework com a implementação de um modelo de domínio genérico e abstrato e um Query Builder? unsure.gif

 

Não tenho certeza se isso irá te ajudar de alguma forma, mas a implementação de um Data Mapper com o Zend Framework é parecida com isto:

 

capturadetela20111227s1.png

Neste caso, o Mapper utiliza um Model e um DbTable, portanto, não justifica uma relação de herança com nenhum deles. O DbTable extende, por sua vez, o Zend_Db_Table_Abstract, do próprio Zend Framework. O Model é a sua entidade do banco de dados.

Compartilhar este post


Link para o post
Compartilhar em outros sites

@Andrey Knupp

...essas minhas classes que irão extender a Mapper e DomainObject...

Bom, eu parti do princípio de que você estava querendo implementar um Data Mapper como Martin Fowler ensina.

 

A minha sugestão para resolver a questão da camada de abstração de dados é utilizar um ORM. Este já irá anular a necessidade de um Query Builder na sequência.

Compartilhar este post


Link para o post
Compartilhar em outros sites

@Andrey Knupp

 

Sim, um Domain Object representa uma entidade relacional que pode, às vezes, ser mapeada por um objeto específico.

 

Você tem alguma necessidade específica que justifica a criação de um framework próprio?

 

Não estou querendo contestar a sua vontade, apenas entender melhor a sua motivação.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Daniel, como você imagina que nasceu o Zend Framework, o Doctrine, o CodeIgniter e outros tantos frameworks e/ou bibliotecas/componentes Orientados a Objetos que aceleram o trabalho de quem os usa?

 

Não foi da noite para o dia, pode apostar. O Andrey já disse estar montando um mini-framework. Desenvolver um framework próprio, além proporcionar a satisfação de usar algo seu, te permite aprender COMO a coisa funciona.

 

De que adianta usar o Zend Framework se, além de us´-los e ter seus Controllers, Models e Views separados, o restante do seu código é uma porcaria sem nexo algum? Isso porque um pseudo-programador acho que ia fazer algo melhor com um framework, pesquisou (ou não) qual o melhor, escolheu um e caiu de cara mal sabendo o bê-a-bá da linguagem.

 

Eu nunca utilizei o Doctrin, mas deu uma olhada por cima no GitHub deles e percebi que é bastante parecido com aquilo que eu tenho programado hoje para acesso e manipulação de dados num banco. O meu tem que melhorar? Claro que tem. Mas é aí que tá a graça da Orientação a Objetos. Você montar seu próprio monstrinho e ver ele caminhar com as próprias pernas.

 

Quem dirá mais. Vai que o Andrey se empenha e nasce um novo framework que daqui há 2 ou 3 anos passe a ser mais usado que os que hoje o são. Tudo é relativo... :thumbsup:

Compartilhar este post


Link para o post
Compartilhar em outros sites

@Bruno Augusto

 

Não me entenda errado, como, aliás, acho que já o fez. Não quero criar uma arena para gladiarmos utilizando as nossas experiências e argumentos um contra o outro. O meu propósito é somente instigar questões que podem ser pensadas antes de se iniciar projetos desse cunho.

 

Daniel, como você imagina que nasceu o Zend Framework, o Doctrine, o CodeIgniter e outros tantos frameworks e/ou bibliotecas/componentes Orientados a Objetos que aceleram o trabalho de quem os usa? Não foi da noite para o dia, pode apostar. O Andrey já disse estar montando um mini-framework. Desenvolver um framework próprio, além proporcionar a satisfação de usar algo seu, te permite aprender COMO a coisa funciona.

Não estou contestando a vontade ou necessidade do Andrey em desenvolver seu próprio framework, apenas indagando a real necessidade disso. Você está corretíssimo ao afirmar que os frameworks que temos hoje em dia não nasceram da noite pro dia, e é por isso que eu estou fazendo este tipo de indagações. Esses frameworks nascem de projetos baseados em diversos fatores, como análise de mercado e de tecnologias. Não são projetos simples, muito menos de pequena equipe de desenvolvimento.

 

Na minha sincera opinião, desenvolver um framework próprio é uma tarefa para aqueles que tem tempo disponível para tal; e mesmo assim, não justificável por diversas razões. Qual o real sentido de reinventar a roda?

 

De que adianta usar o Zend Framework se, além de us´-los e ter seus Controllers, Models e Views separados, o restante do seu código é uma porcaria sem nexo algum? Isso porque um pseudo-programador acho que ia fazer algo melhor com um framework, pesquisou (ou não) qual o melhor, escolheu um e caiu de cara mal sabendo o bê-a-bá da linguagem.

Tenho certeza de que isso não foi uma mensagem indireta para mim ou quaisquer outras pessoas que possam ler este seu comentário. Não somos profissionais e estudamos para julgar os nossos colegas. Pense nisso.

 

Eu nunca utilizei o Doctrin, mas deu uma olhada por cima no GitHub deles e percebi que é bastante parecido com aquilo que eu tenho programado hoje para acesso e manipulação de dados num banco. O meu tem que melhorar? Claro que tem. Mas é aí que tá a graça da Orientação a Objetos. Você montar seu próprio monstrinho e ver ele caminhar com as próprias pernas. Quem dirá mais. Vai que o Andrey se empenha e nasce um novo framework que daqui há 2 ou 3 anos passe a ser mais usado que os que hoje o são. Tudo é relativo...

O fato de você ter algo bastante parecido com o Doctrine, que é um projeto de bastante tempo e credibilidade no mercado, não lhe diz que poderia não ter perdido tempo programando algo que já existe? E você me desculpe, mas orientação a objetos não tem nada a ver com "montar o seu próprio monstrinho e ver ele caminhar com as próprias pernas".

 

Não duvido da capacidade, muito menos da motivação do Andrey ou de qualquer outro profissional da área de iniciar um projeto desse calibre e o mesmo ter sucesso no futuro. O que estou indagando é, novamente, a real necessidade disso.

 

Não me entenda mal, em momento algum tive o intuito de iniciar uma dessas discussões sem fim. Pelo contrário, como já argumentei, queria apenas entender melhor a real motivação e necessidade das coisas.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Daniel, não se trata de reinventar a roda, eu só preciso de uma coisa simples, da mesma forma que escrevo o MVC pra outros projetos, posso muito bem acelerar o processo de fabricação, afinal, o foco - a ideia, é manter simples ..

 

Por exemplo, meu esquema de 'templates', ficou tão simples, que não tive mais nada pra fazer além disso: http://forum.imasters.com.br/topic/451155-view-template/page__view__findpost__p__1783998 ( em relação ao renderer )

 

Entretanto, isso aí já resolve 25% dos meus problemas, não preciso de Partitals, helpers .. nem nada disso .. é apenas superficial, ideia boa é ..

 

Em questão de tempo, acho que pra mim não vai ser problema, afinal, eu preciso de algo simples, mas que quebre a charada, e também, não pretendo escrever tools pra criar controllers, models .. nem nada disso, e se fosse fazer ( o que não vai acontecer ) seria muito fácil, mas minha ideia em relação aos projetos é o COPY - PASTE, copio a pasta do FW , e pronto .. já tá tudo estruturado, com o próprio IDE crio os arquivos em seus lugares ..

 

Cogitei a ideia de ter um DataMapper, mas o buraco é mais acima, e não mais em baixo ..

 

DataMapper não é algo difícil, sei muito bem implementar um, a ideia deste tópico foi propor um padrão e/ou ideia em que as models teriam acesso iminente ( por assim dizer ) aos outros objetos ..

 

O Domain object é apenas faixada, de certa forma ele só me seria útil nas entidades, e no DataMapper, pois nele é que definimos os campos de tabelas e/ou nodes de um XML ( Longe .... )

 

Afinal, não passa de uma ideia superficial, e algo privado =)

A necessidade é mais para acelerar os projetos, ter uma espécie de framework ou package de auxílio não é nada problemático, e que me impeça qualquer outro tipo de integração, para todos os efeitos, eu não gosto do Zend, nem de nenhum framework, eles consomem mais do que a gente tem pra oferecer.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Deixar eu quotar se não me perco... :P

 

@Bruno Augusto

 

Não me entenda errado, como, aliás, acho que já o fez. Não quero criar uma arena para gladiarmos utilizando as nossas experiências e argumentos um contra o outro. O meu propósito é somente instigar questões que podem ser pensadas antes de se iniciar projetos desse cunho.

Longe de mim. Chega de briga por esse ano :lol:

 

Não estou contestando a vontade ou necessidade do Andrey em desenvolver seu próprio framework, apenas indagando a real necessidade disso. Você está corretíssimo ao afirmar que os frameworks que temos hoje em dia não nasceram da noite pro dia, e é por isso que eu estou fazendo este tipo de indagações. Esses frameworks nascem de projetos baseados em diversos fatores, como análise de mercado e de tecnologias. Não são projetos simples, muito menos de pequena equipe de desenvolvimento.

 

Na minha sincera opinião, desenvolver um framework próprio é uma tarefa para aqueles que tem tempo disponível para tal; e mesmo assim, não justificável por diversas razões. Qual o real sentido de reinventar a roda?

Eu não vejo como reinventar a roda. Eu vejo como aprimorar a roda.

 

Se não houvessem aprimoramentos no ramo da tecnologia, ainda usaríamos nossos Ford T para ir trabalhar, compraríamos um jornalzinho meia-boca do garoto da esquina e os leríamos com velas ou lampiões a gás.

 

Eu não programo profissionalmente, mas como gosto da coisa, quando tenho tempo (e força nos braços :cry:) escrevo alguns códigos. O Henrique Barcelos também já disse que faz isso, o Andrey parece estar fazendo e até o próprio João batista também.

 

Tá, envolver o João foi golpe baixo :P

 

Ninguém pretende concorrer com o ZF, CodeIgniter e cia (eu acho), mas todo mundo pode e quer aprender.

Da mesma forma que uma pessoa ou um grupo delas esbarrou na dificuldade, parou e pensou que aquilo poderia ser feito melhor, discutiram, sentaram e fizeram. E nasceram os frameworks.

 

Tenho certeza de que isso não foi uma mensagem indireta para mim ou quaisquer outras pessoas que possam ler este seu comentário. Não somos profissionais e estudamos para julgar os nossos colegas. Pense nisso.

De maneira nenhuma. Nunca vi um código seu pra dizer se você é um bom programdor ou se é mais um sobrinho.

 

Conhecimento na área você demonstra ter :thumbsup:

 

O fato de você ter algo bastante parecido com o Doctrine, que é um projeto de bastante tempo e credibilidade no mercado, não lhe diz que poderia não ter perdido tempo programando algo que já existe?

Se eu trabalhasse com programação, responderia SIM.

 

Mas como é só um hobby, respondo que NÃO.

 

E você me desculpe, mas orientação a objetos não tem nada a ver com "montar o seu próprio monstrinho e ver ele caminhar com as próprias pernas".

Talvez pra você não. Pode até parecer uma colocação ridícula de minha parte, mas desde que eu cai de cabeça na Orientação a Objetos e comecei a entender melhor como essa maquininha funciona, como que tudo está tão ligado e ao mesmo tempo tão desacoplado fiquei maravilhado e porque não orgulhoso de mim mesmo.

 

Foi uma grande "marco" pra mim, ver que meus esforços não foram em vão e que eu realmente tinha talento para coisa.

 

Não duvido da capacidade, muito menos da motivação do Andrey ou de qualquer outro profissional da área de iniciar um projeto desse calibre e o mesmo ter sucesso no futuro. O que estou indagando é, novamente, a real necessidade disso.

Como ele mesmo disse, para fazer as coisas simples.

 

Eu faço porque quero aprender mais e mais a cada dia. Não me surpreenderia se amanhã ou depois isso que eu faço se tornasse um framework. Não tenho intenções disso, mas se rolar...

 

Tá tranquilo cara, só espero que não mutilem esse tópico também... <_<

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.