• Revista PROGRAMAR: Já está disponível a edição #53 da revista programar. Faz já o download aqui!

Nazgulled

Classe ou conjunto de funções para utilização MySQL, what's the point?

38 mensagens neste tópico

Crio este post com uma pequena curiosidade minha que ainda não percebi bem e talvez me venha a ajudar no futuro a fazer algo parecido quando precisar...

Tipo, vejo por ai muitos scripts e sites que têm uma pequena classe (ou conjunto de funções) para gerir tudo que fazem com uma base de dados MySQL, em vez de usarem directamente o mysql_connect(), mysql_query() e por ai fora, usam funções próprias. A minha questão é, qual é objectivo por de trás disso? Até hoje, nunca tive grande necessidade disso, ou se calhar tive só que nunca o soube...

Indo por partes para tentar perceber isto sozinho e assim sem pensar muito, se eu fizesse um conjunto de funções dessas as minhas razões seriam estas:

mysql_connect()

Só vejo duas razões para não se usar isto directamente. Primeiro, podemos incluir na mesma função uma chamada ao mysql_connect() e seguidamente a mysql_select_db(). Segundo, gerar melhor as possíveis mensagens de erro sem que esse código fique misturado com o código principal.

mysql_query()

A única razão para uma função que abstraia o uso directo do mysql_query() é simplesmente para não ter de repetir o mysql_real_escape_string() para cada variável que irá fazer parte da query.

Há mais razões para se ter a necessidade de criar um conjunto de funções parar gerir uma bd MySQL? Por exemplo, já vi alguns exemplos que têm uma função que "constrói" a query a ser feita a bd, passa o comando (INSERT, UPDATE, DROP, etc...) os campos e tabelas que irão ser alterados, e os valores necessários, separando tudo isto por vários parâmetros na função. Qual é a vantagem de se fazer isto? Que propósito serve? Para além dos exemplos que dei mais acima, que mais posso eu fazer com uma função deste género?

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Em PHP, não faço ideia, mas se não te importas, meto o bedelho e explico a minha experiência em Python com coisas iguais :P Em Python também tens uma biblioteca que te permite ligações a BDs MySQL mais ou menos nesses moldes. No entanto, eu criei funções que me poupam trabalho. Por exemplo: num script que fiz, tinha que criar uma BD e preencher uns quantos campos com informação vinda de um parser. Pá, em vez de estar sempre a escrever os comandos "crus" de acesso à BD, que na verdade nem me ocupavam mais que 3 linhas, preferi pegar numa função, mais explícita em termos de nome e mais limpinha em termos visuais, para fazer o trabalho.

No meu caso, uso esse tipo de funções exclusivamente para o código ficar mais legível. Mas também só as uso, se usar a operação mais do que algumas vezes, senão nem me dou ao trabalho :)

(Espero não ter metido o bedelho e ter falado ao contrário :P)

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Nazgulled, aconselhava-te a leres na revista sobre o ADOdb em php :P.

O que é isso? Uma camada de abstracção de SGBD's, ou seja, tanto podes trabalhar com mysql ou com sqlite, ou qualquer outra, que se no fim desejares trocar o SGBD por algum motivo, basta trocares a "connection string" e não as funções todas de uma vez só. Tens algumas facilidades na leitura do código como por exemplo esta:

$RS = $BD->Execute("SELECT * FROM alunos WHERE CodAluno=? AND Sexo=?", array($CodAluno, $Sexo));

Penso que isto é bastante útil em queries grandes, onde não se tem de andar com as plicas e as aspas, mas... just my two cents

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Já viste o exemplo do AdoDb?

A utilidade daquilo é reduzir o número de linhas e simplificar a maneira de como vais buscar rows, sets ou só 1 campo, numa simples linha.

Ainda mais, quase que não perdes desempenho nenhum, e podes meter as queries em cache, o que torna o site muito mais leve, se tiveres vários utilizadores a visualizar sempre a mesma coisa, sem necessidade de actualização.

Claro que podias programar tu isso tudo, mas acredito que em termos de produtividade, é uma boa escolha usar esta interface.

Acho que depende muito do que se esteja a fazer. Num site muito pequeno não vejo grande utilidade, mas em sites já granditos, há sempre a necessidade de reduzir o tamanho do código e simplificar as coisas o mais possível.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Tens várias vantagens, entre elas teres de codar menos (foreach($db->getUsers() as $row) echo $row['nome']."<br />\n"; em vez de mysql_query(...) [...]) e teres um design modular. É um pouco como o usar PHP misturado com HTML. :P

Tu agora fazes uma aplicação para MySQL com uma bd que tu desenhaste, mas o teu cliente quer usar a bd de outro software, usar outro SGDB, wtv. Solução? Alterar a class. :P

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Só para dizer que independentemente do método usado para ligar à BD. É sempre bom por toda a lógica alocada no mesmo sitio do código. Teres a lógica do código separado desta forma tem várias vantagens.

Primeiro torna o código mais legível, já que escusas de ver código da lógica de negócio misturado com código de lógica de acesso à base de dados.

Segundo torna o teu código mais flexível. Se por algum motivo tiveres  que alterar à base de dados ou a forma de fazer a query, o teu código do lado da lógica de negócio continua igual, só tens de mudar o código interno da função. Ou seja mudar a query/mecanismo de BD/etc. É perfeitamente possível passares a usar MySQL para ficheiros de texto com dados para outra forma qualquer sem que todo o teu código tenha que ser alterado.

Isto não é nada novo como podes verificar que toda a gente faz isso. Este modelo normalmente é designado por DAL (Data Access Layer) e muitas vezes é implementado dando uso ao padrão de desenho Active Record, tornado muito popular pelo Ruby On Rails.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

De facto não sei o que seja isso do ADOdb, tenho de ver mais tarde. Mas como disseram, para sites pequenos/aplicações se calhar não compensa e até hoje é só isso que tenho feito. Quer dizer, já fiz algo mais ou menos grande, mas na altura também pouco percebia de PHP para pensar neste tipo de coisas e fazia tudo de forma cru, da única maneira que sabia e era daqueles que só se preocupava em que estivesse a funcionar. Hoje em dia já não sou assim, dai as minhas perguntas.

Quanto ao exemplo do cliente e usar outra BD, pah, não vas por ai, isso para mim é inválido e explico porquê. O cliente quer X, eu dou-lhe X, se depois quiser mudar de software, problema dele, que pague mais e eu faço a alteração. Caso contrário, que explique no inicio o que pretende, se não explicar e depois quiser alterações de maior envergadura, o problema não é meu, eu fiz o que me foi pedido.

E esse exemplo que dês-te do $db->getUsers() não foi dos melhores. Isto porque eu poderia na mesma ter uma função getUsers() e dentro dele fazia as chamadas à db pura e crua e ia dar ao mesmo. Trata-se apenas da abstracção do mysql_connect() e mysql_query(), nada mais.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

E esse exemplo que dês-te do $db->getUsers() não foi dos melhores. Isto porque eu poderia na mesma ter uma função getUsers() e dentro dele fazia as chamadas à db pura e crua e ia dar ao mesmo. Trata-se apenas da abstracção do mysql_connect() e mysql_query(), nada mais.

O objectivo não foi dar um exemplo que não pudesse ser usado para contraargumentar, se não tinha dado código de exemplo.

class db {
    // ...
    function getUsers(){
        return $this->getRows($this->query("SELECT * FROM {$this->usersTable}"));
    }
}

Anyway, não interessa como é o código de cada funcionalidade da interface default, interessa é existir a possibilidade de modificar a interface ao gosto de cada pessoa.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

O único argumento realmente válido é o de usar outro SGBD, todos os outros que voces deram não trazem benificios em relação à biblioteca nativa, podem fazer exactamente o mesmo com ela. Tudo o que disseram até agora.

Mas o tópico é bem claro, fala  de um sgbd em particular.

Tambem é uma das coisas que me interrogo, quando uma aplicação está desenhada para funcionar num sgbd qual é a ideia por detrás de um objecto de base de dados...

penso que é uma coisa desnecesária que se faz por haver um mito que o código é assim que deve ser ou sei lá.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Pedrotuga estás enganado. O argumento é na mesma válido se não tiveres de usar outro SGBD.

Qual é a lógica de se tiveres o mesmo pedaço de código repetido, pegares nele e criares uma função do mesmo, e antes onde tinhas o pedaço de código estares a chamar a função?

Clareza, abstracção, flexibilidade, etc...

Imagina programares sem poderes definir funções....

Este caso é o mesmo. O facto de estares a agrupar a comunicação com a base de dados num ponto. Confere ao teu código, do ponto de vista geral, uma maior clareza, abstracção, flexibilidade, etc...

Como introdução podem dar uma vista de olhos por isto (são os 2 modelos mais populares):

http://en.wikipedia.org/wiki/Multitier_architecture

http://en.wikipedia.org/wiki/Model-view-controller

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Eu até mostro um bocado de código, em Python, para demonstrar o meu ponto de vista:

for entry, value in dct_id2name.iteritems():
    Update_Table(connection, tb_name, ('Gene_Name', value), ('Entrez_ID', entry))
    count += 1
    print 'Inserts left: %d' %(len(dct_id2name)-count)

A função Update_Table é chamada mil e uma vezes ao longo do script, não só neste for.

def Update_Table(connection, table, (column1, value1), (column2, value2)):
    """ Modifies data in a table """
    
    cursor = connection.cursor()
    command = 'UPDATE %s SET %s = ("%s") WHERE %s = %s' %(table, column1, value1, column2, value2)
    #print command # Hunting Bugs!
    cursor.execute(command)
    cursor.close()

Quando mais não seja, fica mais legível ao longo do código, ter uma função UPDATE doque o comando SQL misturado com Python. Agora que me lembro, lembram-se do post das threads com código a mais? Que havia alguém que resmungava de quem postava PHP e HTML tudo junto? Para mim, estas funções evitam misturar Python (ou PHP) e SQL :P

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Tipo, vejo por ai muitos scripts e sites que têm uma pequena classe (ou conjunto de funções) para gerir tudo que fazem com uma base de dados MySQL, em vez de usarem directamente o mysql_connect(), mysql_query() e por ai fora, usam funções próprias. A minha questão é, qual é objectivo por de trás disso? Até hoje, nunca tive grande necessidade disso, ou se calhar tive só que nunca o soube...

Classes em linguagens de scripting sao um bocao inuteis e ainda hoje se debate se sao realmente necessarias. A minha opiniao e' que em certos casos pontuais sao de uma utilidade extrema. A classe DB do Pear e' o exemplo mais gritante.

Eu li este livro http://objectorientedphp.com/ e o que te posso dizer sobre classes e' que torna o teu codigo mais bem escrito no que toca a tudo o que diga respeito ao paradigma de uma linguagem OO. Nao e' apenas um "conjunto de funcoes", e' uma maneira de o teu codigo estar mais organizado.

Se nao utilizas a aproximacao OO no teu codigo, entao sim... e' apenas um conjunto de funcoes.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Eu não gosto de responder assim, mas vou ter que contrariar, betovsky, tu é que estás enganado, ora vê bem...

As classes de ligação de bases de dados não poupam código nenhum. Se reparares todos os exemplos aqui dados afectam um método da classe a uma função da api nativa, e na verdade é com recurso a estas que as primeiras são implementadas.

No teu segundo paragrafo estás claramente a apontar para os modelos do padrão MVC, isso não é de todo o que está aqui em discussão. O que está em discussão são classes de ligação a uma base de dados.

Eu uso o padrão MVC todos os dias e não estou a ver como é que a referencia a este pode ser usada como argumento nesta discussão. 95% das framworks MVC em PHP que por aí andam nem sequer usam uma classe destas que está aqui em causa. Usam no entanto um parente mais ou menos próximo chamado active-record, que pessoalmente tambem não vejo grandes vantagens no seu uso. De resto todas as frameworks deixam em aberto a possibilidade de usar SQL.

Mas ok, ilustrando com código....

//qual a vantagem de escrever ...
$query = $db->query("select * from table");
$row =$db->fetch_row($query);

//...em vez de
$query = mysql_query("select * from table");
$row = mysql_fetch_row($query);

//ou mesmo disto para o caso do activerecord
$db->select_all("table");
$row=$db->fetch_row();

tirando o facto de se poder usar outra base de dados não estou a ver nenuma vantagem nem mesmo em termos de limpeza de código... mas hey... dêm-me um contra exemplo válido e eu mudo de opinião.

Edit:

Evitem responder com chavões tipo "OO premite melhor organização do código" e não caiam no pressuposto errado que programação orientada a objectos é sinónimo de melhor código.

K, eu concordo plenamente cmo o teu último paragrafo, mas não o explicaste e a maior parte das pessoas vai tirar a conclusão errada.

Nomeadamente, este caso aqui discutido é um caso em que se usa frequentemente uma sintaxe de classes e objectos e acaba-se por não se fazer nenhuma programação orientada a objectos.

Usar classes só para empacotar funções não adianta rigorosamente nada e não é programação orientada a objectos.

Sinceramente não estou a ver como se pode tirar partido de polifomismo ou herança de uma classe de ligação a uma base de dados. Mais uma vez, dêm-me um exemplo que eu mudo de ideias.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Eu não gosto de responder assim, mas vou ter que contrariar, betovsky, tu é que estás enganado, ora vê bem...

As classes de ligação de bases de dados não poupam código nenhum. Se reparares todos os exemplos aqui dados afectam um método da classe a uma função da api nativa, e na verdade é com recurso a estas que as primeiras são implementadas.

No teu segundo paragrafo estás claramente a apontar para os modelos do padrão MVC, isso não é de todo o que está aqui em discussão. O que está em discussão são classes de ligação a uma base de dados.

Eu uso o padrão MVC todos os dias e não estou a ver como é que a referencia a este pode ser usada como argumento nesta discussão. 95% das framworks MVC em PHP que por aí andam nem sequer usam uma classe destas que está aqui em causa. Usam no entanto um parente mais ou menos próximo chamado active-record, que pessoalmente tambem não vejo grandes vantagens no seu uso. De resto todas as frameworks deixam em aberto a possibilidade de usar SQL.

Mas ok, ilustrando com código....

//qual a vantagem de escrever ...
$query = $db->query("select * from table");
$row =$db->fetch_row($query);

//...em vez de
$query = mysql_query("select * from table");
$row = mysql_fetch_row($query);

//ou mesmo disto para o caso do activerecord
$db->select_all("table");
$row=$db->fetch_row();

tirando o facto de se poder usar outra base de dados não estou a ver nenuma vantagem nem mesmo em termos de limpeza de código... mas hey... dêm-me um contra exemplo válido e eu mudo de opinião.

Edit:

Evitem responder com chavões tipo "OO premite melhor organização do código" e não caiam no pressuposto errado que programação orientada a objectos é sinónimo de melhor código.

K, eu concordo plenamente cmo o teu último paragrafo, mas não o explicaste e a maior parte das pessoas vai tirar a conclusão errada.

Nomeadamente, este caso aqui discutido é um caso em que se usa frequentemente uma sintaxe de classes e objectos e acaba-se por não se fazer nenhuma programação orientada a objectos.

Usar classes só para empacotar funções não adianta rigorosamente nada e não é programação orientada a objectos.

Sinceramente não estou a ver como se pode tirar partido de polifomismo ou herança de uma classe de ligação a uma base de dados. Mais uma vez, dêm-me um exemplo que eu mudo de ideias.

Agora experimenta fazer isto:


$db->CacheGetOne(3600,'SELECT id FROM t_t WHERE campo=?',$var);
$db->Replace($table,$array,1);

em php tradicional

adodb tem muito mais potencial do que mostras-te agora. lê os docs daquilo e logo encontras funções que te vão facilitar muito o trabalho.

e se "empacotar" dentro de uma classe para reusar código, então, porque não?

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Quanto ao exemplo do cliente e usar outra BD, pah, não vas por ai, isso para mim é inválido e explico porquê. O cliente quer X, eu dou-lhe X, se depois quiser mudar de software, problema dele, que pague mais e eu faço a alteração. Caso contrário, que explique no inicio o que pretende, se não explicar e depois quiser alterações de maior envergadura, o problema não é meu, eu fiz o que me foi pedido.

Só te arriscas é a que o cliente nunca mais te encomende software...

Hoje em dia, qualquer metodologia de desenvolvimento de software em grande escala, deve ver as mudança nos requisitos do sistema como um inevitabilidade. Este é um dos princípio básicos da Engenharia de Requisito.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Agora experimenta fazer isto:

$db->CacheGetOne(3600,'SELECT id FROM t_t WHERE campo=?',$var);
$db->Replace($table,$array,1);

Tipo, não sei o que isso faz... não fizeste qualquer referencia à classe do objecto $db, nem mostraste o código nativo equivalente por isso não tenho hipóteses de saber o que isso faz.

Olhando para isso no entanto parece-me que isso faz o mesmo que se consegue fazer em duas linhas usando a função mysql_result() seguida de um mysql_query() com um update lá no meio. Mas repito, não percebi o que isso é suposto fazer.

e se "empacotar" dentro de uma classe para reusar código, então, porque não?

Porque dessa forma o único código que vais reusar é o do empacotamento, que não era preciso desde ínicio.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

As classes de ligação de bases de dados não poupam código nenhum. Se reparares todos os exemplos aqui dados afectam um método da classe a uma função da api nativa, e na verdade é com recurso a estas que as primeiras são implementadas.

No teu segundo paragrafo estás claramente a apontar para os modelos do padrão MVC, isso não é de todo o que está aqui em discussão. O que está em discussão são classes de ligação a uma base de dados.

Mas a ideia principal não é poupar código mas sim trabalho por parte dos programadores. Os programadores terão uma maior sobrecarga se tiverem que "processar" toda a lógica ao mesmo tempo, em vez de ser por pedaços.
Eu uso o padrão MVC todos os dias e não estou a ver como é que a referencia a este pode ser usada como argumento nesta discussão. 95% das framworks MVC em PHP que por aí andam nem sequer usam uma classe destas que está aqui em causa. Usam no entanto um parente mais ou menos próximo chamado active-record, que pessoalmente tambem não vejo grandes vantagens no seu uso. De resto todas as frameworks deixam em aberto a possibilidade de usar SQL.
Eu fiz referência a MVC porque é dos conceitos mais populares. Acho que o que o Nazgulled estava a referir era até o outro modelo que também referi, o 3-Tier. Mas isto são apenas conceitos abstractos, filosofias por assim dizer, podes implementar como quiseres. A ideia a ter em conta é que convem ser em layers separados.

Mas ok, ilustrando com código....

//qual a vantagem de escrever ...
$query = $db->query("select * from table");
$row =$db->fetch_row($query);

//...em vez de
$query = mysql_query("select * from table");
$row = mysql_fetch_row($query);

//ou mesmo disto para o caso do activerecord
$db->select_all("table");
$row=$db->fetch_row();

Oky eu não digo em PHP porque como devem saber não é o meu forte. Mas a ideia é independente da linguagem. O que me refiro a por em layers diferentes. É que irás ter um módulo onde defines tudo da base de dados. Nas outras secções do código usas esse módulo, mas sem teres qualquer referencia à BD. Vou usar algo pseudo-código OO. A ideia será ir buscar o registo de todos os utilizadores, supostamente é apresentado qualquer informação ao utilizador e lá acaba por acontecer em que é necessário mudar a idade do utilizador cujo nome é "Oscar" para 22.

Na minha opinião a maneira má.

Table t = DB.Query("Select * From Users");
foreach Row r in t.Rows {
   printf "Nome: ", r[0];
   printf "Idade: ", r[1];
   printf "Telefone: ", r[5];
}

// etc e tal e sabemos que temos que actualizar o "Oscar" com 22 anos
String nome = "Oscar";
Int idade = 22;

DB.Query("Update Users Set Idade = $1 Where Nome = $2", idade, nome);

Sim eu sei, que não estou a fazer validações de parâmetros, etc e tal e o código é inseguro. A ideia é que este código é rígido. Se por acaso tivermos que alterar a base de dados. Há uma boa probabilidade de termos que alterar muitas partes do código em vários pontos do nosso programa.

Na minha opinião a maneira correcta:

List<Users> users = DB.GetAllUsers();
foreach User u in users {
   printf "Nome: ", u.Name();
   printf "Idade: ", u.Idade();
   printf "Telefone: ", u.Telefone();
}

// etc e tal e sabemos que temos que actualizar o "Oscar" com 22 anos
String nome = "Oscar";
Int idade = 22;

User user = DB.GetUser(nome);
user.SetIdade(22);
user.Gravar();

Aqui como podem ver, o código não depende da Base de dados. Se por algum motivo tiverem que alterar a Base de dados de alguma forma o código continuará igual. Só é necessário alterar o código interno das funções do módulo responsável por aceder à base de dados.

Neste exemplo que dei, usei o GetUser e o Gravar. Mas podia perfeitamente em vez de usar o GetUser usar antes a lista que tinha obtido anteriormente e percorre-la até obter o User que pretendo actualizar. Em relação à função Gravar, podia perfeitamente fazer o update na BD no momento que faço a função SetIdade, mas aí já é uma preferência minha não fazer update na BD a cada alteração. As alterações que faço é a nivel do objecto que existe na aplicação e depois no fim é que chamo o método Gravar que actualiza todas as alterações na BD. Mas independentemente disso a ideia a ter em conta é que a 2ª versão é muito mais flexível do que a 1ª. E por isso é que acho que se deve sempre por todo o código de acesso à base de dados separado à parte, numa layer dedicada só para isso.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Tipo, não sei o que isso faz... não fizeste qualquer referencia à classe do objecto $db, nem mostraste o código nativo equivalente por isso não tenho hipóteses de saber o que isso faz.

Olhando para isso no entanto parece-me que isso faz o mesmo que se consegue fazer em duas linhas usando a função mysql_result() seguida de um mysql_query() com um update lá no meio. Mas repito, não percebi o que isso é suposto fazer.

Porque dessa forma o único código que vais reusar é o do empacotamento, que não era preciso desde ínicio.

A primeira faz um Select de só 1 campo id, dá-te logo o valor do id e ainda te põe em cache por 3600 segundos.

Tenho um erro no replace:


$db->Replace($table, $_POST, 'id', 1);

Vai ver se na tabela $table tem o 'id' da array $_POST. Se tiver faz Update, se nao tiver faz insert, e ainda tem tratamento para caracteres especiais.

Não percebi bem o que disses-te acerca do empacotamento, mas neste caso, o estares só a chamar uma função em vez de escreveres muitas linhas de código, torna-se, não necessário, mas muito produtivo.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Onde isto já vai..., não li a discussão aqui do pedrotuga vs Betovsky vs Battousai porque são posts muito grandes para os quais não tenho tempo e pelo que li, parece-me que estão a falar de coisas um pouco avançadas para mim. Anyway, vou responder ao que me interessa...

@K

Não percebi a ideia do teu post porque eu não vim para aqui discutir classes, paradigma OO, conjuntos de funções, whatever... Mas sim, qual a ideia de usar funções próprias para se fazer queries a bases de dados quando se tem funções directas. Chama-lhe o que quiseres ao "conjunto de funções".

@Rui Carlos

Desculpa lá mas eu não vou admitir que um cliente me peça detalhadamente isto e aquilo e que fique contente com o trabalho e uns meses depois me venha dizer que agora precisa que aplicação funcione com outra db diferente. Das duas uma, ou paga pelas alterações que irão dar trabalho ou que tivesse detalhado antes que iria querer que funcionasse com várias sgdbs.

Eu vejo isto da mesma forma que alguém encomenda uma aplicação para o Windows e que fica muito contente mas meses mais tarde precisa da mesma aplicação em Linux, não vais cobrar pelo software e fazes-lhe aplicação para Linux ou cobras como se fosse uma aplicação nova? E não digas que usar uma linguagem cross-os (tipo Java) é a solução, pois isso não é argumento a não ser que o cliente tenha requisitado a aplicação nessa linguagem, se não o fez, tu programas na linguagem que queres (desde que funcione no Windows, o que te foi pedido inicialmente) e até podes nem ter conhecimentos de Java, és obrigado a fazer em Java só para assegurar que futuramente o cliente queira a aplicação em Linux? Não faz sentido... Isto é um exemplo um pouco extremo, mas para mim, vai dar ao mesmo.

Mas deixa que eu me preocupe com o facto de o cliente me encomendar mais software ou não...

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

@K

Não percebi a ideia do teu post porque eu não vim para aqui discutir classes, paradigma OO, conjuntos de funções, whatever... Mas sim, qual a ideia de usar funções próprias para se fazer queries a bases de dados quando se tem funções directas. Chama-lhe o que quiseres ao "conjunto de funções".

Se eu lesse o titulo primeiro em vez de saltar para conclusoes e ideias mirabolantes talvez fosse mais fino. Desculpa o que disse ;-) esta' completamente fora do contexto.

Assim sendo: nao consigo imaginar-me a programar PHP sem a classe DB do Pear.

E claro que deves cobrar se o cliente quiser alteracoes. Clientes que nao sabem o que querem e' o que mais ha' por ai e que pensam que o codigo se altera com um peido e uma cambalhota no ar so porque eles conseguem fazer melhor que nos no Excel (palavra de honra, ja tive um assim).

Mas neste caso tambem deves salvaguardar o teu tempo e paciencia. Por isso uma abstraccao da layer da base de dados nao faz mal a ninguem.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Desculpa lá mas eu não vou admitir que um cliente me peça detalhadamente isto e aquilo e que fique contente com o trabalho e uns meses depois me venha dizer que agora precisa que aplicação funcione com outra db diferente. Das duas uma, ou paga pelas alterações que irão dar trabalho ou que tivesse detalhado antes que iria querer que funcionasse com várias sgdbs.

Eu vejo isto da mesma forma que alguém encomenda uma aplicação para o Windows e que fica muito contente mas meses mais tarde precisa da mesma aplicação em Linux, não vais cobrar pelo software e fazes-lhe aplicação para Linux ou cobras como se fosse uma aplicação nova? E não digas que usar uma linguagem cross-os (tipo Java) é a solução, pois isso não é argumento a não ser que o cliente tenha requisitado a aplicação nessa linguagem, se não o fez, tu programas na linguagem que queres (desde que funcione no Windows, o que te foi pedido inicialmente) e até podes nem ter conhecimentos de Java, és obrigado a fazer em Java só para assegurar que futuramente o cliente queira a aplicação em Linux? Não faz sentido... Isto é um exemplo um pouco extremo, mas para mim, vai dar ao mesmo.

Claro que vais cobrar pelas novas alterações. E acredita que vão haver. Se fizeste uma boa aplicação, há uma boa probabilidade de o cliente ficar satisfeito e querer melhorias e/ou novas funcionalidades. E a quem irá primeiro pedir que não a entidade original que a desenvolveu? Agora a questão é se irás ter muito ou pouco trabalho a implementar as novas funcionalidades. Se fores fazer o trabalho e tiveres uma base de código porreira, implementas as novas funcionalidades muito facilmente. Se tivesses um código base mau, terias que "trabalhar" muito mais, o que teria vários pontos negativos. Por exemplo, tendo em principio que tanto numa versão como na outra irias cobrar o mesmo, é óbvio que na primeira irias ter no fim um maior lucro. Se cobrasses mais pode fazer com que o cliente já não esteja disposto a adquirir as novas funcionalidades, ou se mesmo assim quiser, tens sempre o problema que ficas mais tempo preso ao projecto.

E falado de experiência própria, nunca tive um projecto que chegasse ao fim e não tivesse que fazer umas revisões. Nem sempre tudo é bem especificado, ou às vezes o cliente não sabe bem o que quer e não se pensou a situação X e que se isso não estiver contemplado a aplicação deixa de fazer sentido, porque não funciona. E uma pessoa não quer estar a desenvolver uma aplicação para no fim ela ir pró lixo, para além de o cliente ficar insatisfeito e nós não recebermos o guito. Sim, porque normalmente o dinheiro é só recebido no acto da conclusão. E se a aplicação não serve pro cliente, para ele não está concluída.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Tudo bem, eu também nunca tive um projecto que não precisasse de revisões, mas são sempre coisas mínimas onde o suporte está implícito e não funcionalidades de grande porte.

Eu só disse o que disse porque da maneira que o Rui Carlos falou era como se eu fosse obrigado a fazer tudo o que cliente pede, mas isso é errado. Não interessa para a discussão, se tenho uma boa abstracção da base de dados e uma boa base de código, isso são pormenores. O que eu estava a discutir era o facto de o cliente pedir originalmente em X e mais tarde querer Y. Mesmo que eu tivesse implementado um conjunto de funções para me ajudar o código, ele não tinha nada a ver com isso, quer Y, paga Y. No fundo é uma nova funcionalidade que não estava prevista, não é corrigir uns bugs aqui e ali e implementar pormenores pequenos. São versões novas, paga por elas. That's my point.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

@Rui Carlos

Desculpa lá mas eu não vou admitir que um cliente me peça detalhadamente isto e aquilo e que fique contente com o trabalho e uns meses depois me venha dizer que agora precisa que aplicação funcione com outra db diferente. Das duas uma, ou paga pelas alterações que irão dar trabalho ou que tivesse detalhado antes que iria querer que funcionasse com várias sgdbs.

O mundo não é a preto&branco, e as coisas nem sempre são assim tão simples...


De qualquer modo, só tens a ganhar em ter o programa preparado para alterações. Se consegues reduzir o custo de 1000€ para 200€, só tens a ganhar com isso, pois se o cliente te pedir essa alteração, nada te impede de continuar a pdeir os 1000€, e teres um lucro bastante maior.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Vou tentar explicar o melhor que sei. É um post um bocado lento.

ABSTRACÇÃO (Layer/Tier 1)

Esta é a palavra chave para explicar as tuas dúvidas. Em PHP tal como existem essas funções de mysql, existem funções para outras bases-de-dados.

Ao criares a abstracção permites a utilização de qualquer base-de-dados por detrás da implementação.

(Esta implementação pode ser como classe ou funções, é irrelevante, sebem que classes traz vantagens óbvias que posso explicar noutro post)

Padrões: Factory, Strategy

Além do acima referido, temos outras vantagens nesta abstracção. A NÃO repetição de código está nos mandamentos do programador.

Como a utilização de bases-de-dados é sempre repetitiva - query, rows, result, query, rows, result - existem aqui comportamentos que podem ser factorizados.

Por isso, o tratamento de erros é dos primeiros. Com uma layer por cima das queries, results é possivel tratar erros sem estar a repetir código.

Outra tarefa repetiviva é a cache de resultados. Sem uma layer o código torna-se inultimente extenso e mais complexo do que podia ser.

MODELS (Layer/Tier 2)

Alguém falou sobre usar funçoes como: GetAllUsers(). Isto é um bom exemplo, mas não se encontra na secção acima.

A isto chama-se model, ou camada de negócio. Assenta sobre o Tier 1, e permite refactorização de queries, otimização de leitura/escrita de código e acima de tudo extensibilidade.

Nos nossos websites um dos exemplos mais frequentes é a quantidade de vezes que temos de obter uma lista de utilizadores ou os dados dum utilizador especifico.

Sem esta abstração, este é um exemplo típico de como obteriamos os dados (já contando com a camada acima):

$db->query("SELECT * FROM users LIMIT 10")

Repetiriamos este código muitas vezes pela nossa aplicação. Imaginemos agora que alterámos a nossa estrutura, e parte dos dados do utilizador vêem de outra tabela.

Teriamos de percorrer todas as ocorrências e modificar para:

$db->query("SELECT U.*, D.* FROM users U LEFT JOIN details D ON (D.id = U.id) LIMIT 10")

Este tipo de alterações não tem nada a ver com o cliente  :confused: (ehehe), mas sim um update do site, ou um simples melhoramento. Extremamente inefeciente estar a modificar todas as ocorrências. REPETIÇÃO DE CÓDIGO.

Solução?

$usersModel->getList()

...

function getList() {
  return $db->query("SELECT * FROM users LIMIT 10");
}

..

Espero ter esclarecido algumas dúvidas.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Eu uso o padrão MVC todos os dias e não estou a ver como é que a referencia a este pode ser usada como argumento nesta discussão. 95% das framworks MVC em PHP que por aí andam nem sequer usam uma classe destas que está aqui em causa. Usam no entanto um parente mais ou menos próximo chamado active-record, que pessoalmente tambem não vejo grandes vantagens no seu uso. De resto todas as frameworks deixam em aberto a possibilidade de usar SQL.

Só para esclarecer que Active Record, pode ser chamado Tier 3. Tu não ves quando usas, mas ele usa o Tier2, que por sua vez usa o Tier1.

Cumprimentos.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!


Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.


Entrar Agora