Usamos cookies para medir audiência e melhorar sua experiência. Você pode aceitar ou recusar a qualquer momento. Veja sobre o iMasters.
Olá pessoal, meu nome é Paulo Sakamoto, estou desenvolvendo um novo projeto e vim aqui para saber a opinião de vocês a respeito do padrão de desenvolvimento MVC, mais precisamente sobre validação de dados. Apesar do título sugerir uma gambiarra na programação, não se trata de nada disso, foi apenas uma forma de chamar a atenção, e se você está lendo este texto, quer dizer que funcionou. :thumbsup:
O tema é um pouco batido, mas acho que ainda não há um consenso no que diz respeito à validação de dados, e como não há esse consenso, então não existe certo ou errado. Onde validar ? No Controller ? Na Model ? Já vi casos de pessoas validando na View.
Pesquisando em fóruns na internet, reparei que, as pessoas que fazem persistência na Model, normalmente jogam a regra de negócios (e consequentemente a validação) para o Controller. Faz muito sentido neste caso, pois seria responsabilidade demais para a Model, o código ficaria extenso e de difícil manutenção. Como o Controller tem pouca responsabilidade, passar as regras de negócio para lá parece uma boa idéia.
Pessoas que usam classes específicas para persistência, DAO, normalmente fazem as regras de negócio na Model, deixando o Controller apenas intermediando a Model e a View. Particularmente gosto mais deste modelo, pois o código do Controller fica bem enxuto, de fácil compreensão e manutenção, principalmente se não for você quem irá fazer tal manutenção. Gosto também de usar classes para armazenamento de dados, VO, pois acho que as informações ficando encapsuladas, o código fica mais legível e elimina os perigos de conflitos de nomes das variáveis.
No meu projeto, criei uma DAO genérica para operações de CRUD, e DAOs específicas, para garantir integridade e consistência dos dados. Vou dar um exemplo simples para ficar mais claro.
--
-- Estrutura da tabela Usuarios
--
CREATE TABLE IF NOT EXISTS `Usuarios` (
`Id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`Login` varchar(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'Login Criptografado.\nUsado na autenticação.',
`Senha` varchar(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'Senha Criptografada.\nUsada na autenticação',
PRIMARY KEY (`Id`),
UNIQUE KEY `Login_UNIQUE` (`Login`),
KEY `iLogin` (`Login`(10))
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Tabela de Usuarios do Sistema';
<?phpprivate $Id;
private $Login;
private $Senha;
public function SetId($Id){ $this -> Id = $Id; }
public function SetLogin($Login){ $this -> Login = $Login; }
public function SetSenha($Senha){ $this -> Senha = $Senha; }
public function GetId() { return $this -> Id; }
public function GetLogin(){ return $this -> Login; }
public function GetSenha(){ return $this -> Senha; }
}
interface UsuariosDAOInterface
{
public function Insert(UsuariosDAO $Usuario);
}public function Insert(UsuariosDAO $Usuario);
}
?>
Falta agora garantir a integridade dos dados, ou seja, fazer a validação. Pensando em reaproveitamento de código, e uma melhor organização, resolvi desacoplar este processo da Model, tornando-a um pouco mais enxuta. Criei então uma classe de validação genérica, que tem vários tipos de dados pré-definidos(email, int, alnum,alpha, etc) e então valido através de expressões regulares.
<?php
interface ValidacaoInterface
{
public function Validar($str, $tipo, $min, $max);
}* @return Boolean caso o dado seja válido, falso caso contrário
* @author Paulo Sakamoto, paas@hotmail.comTenho agora duas opções. Ou crio uma nova classe específica para validar dados do tipo UsuariosVO, ficaria bem ornanizado desta forma, porém com uma certa queda de produtividade, ou...validar na própria VO! Calma pessoal, sei que vou receber muitas críticas por isso, mas como eu disse no começo, não existe um consenso geral portando não tem certo ou errado. Apenas deixem-me explicar meu motivo. Se eu tenho uma classe específica para armazenamento, não seria de responsabilidade da mesma garantir a integridade dos dados armazenados nela ? Armazenou então se vira! A classe VO ficaria assim:
<?php
interface VOInterface
{
public function Validar();
}
class UsuariosVO implements VOInterface
{
private $Id;
private $Login;
private $Senha;
public function SetId($Id){ $this -> Id = $Id; }
public function SetLogin($Login){ $this -> Login = $Login; }
public function SetSenha($Senha){ $this -> Senha = $Senha; }
public function GetId() { return $this -> Id; }
public function GetLogin(){ return $this -> Login; }
public function GetSenha(){ return $this -> Senha; }
/**
* Este método valida todas as propriedades da classe, usando o
* método Validacao::Validar()
* @see Validacao#Validar()
* @see VOInterface
* @return Boolean caso o dado seja válido, falso caso contrário
* @author Paulo Sakamoto, paas@hotmail.com
*/
public function Validar() $retorno = true;
$retorno = $retorno && Validacao::Validar($this -> Id, 'mediumint');
$retorno = $retorno && Validacao::Validar($this -> Login, 'loginSenha', 5, 20);
$retorno = $retorno && Validacao::Validar($this -> Senha, 'loginSenha', 5, 20);
return $retorno;
}
}
?>
A Model ficaria responsável por invocar o método Validar. Desta forma consegui um bom reaproveitamento de código nas validações e o código da Model ficou bem mais enxuto.
Qual a opinião de vocês pessoal ? Manerem nas críticas, rs. E para quem quiser criticar baseado em queda de produtividade, digo que este foi um simples exemplo e que é possível melhorar e automatizar os processos getters, setters e validações em uma única classe abstrata base, bastando nas classes extendidas setar propriedades. Mamão com açúcar hein!? Mas isso fica para um outro dia. Abraços.
>
Taí um assunto interessante.
Eu já vi alguns casos e/ou li relatos de programadores dizendo que validam as informações antes de ir pro banco na própria Model.
Apesar de nunca ter visto na real um exemplo desse tipo, me parece errado fazê-lo. Eu penso que a função do Controller é justamente controlar informações e o fluxo delas entre as outras duas camadas.
E por controlar informações vejo como responsabilidade dele verificar, por exemplo, se um parâmetro GET o qual servirá de base para uma cláusula WHERE existe ou não.
Os parâmetros GET são intimamente ligados à Requisição feita e a Model, que interage com o banco não deve saber o quê é uma Requisição, de onde ou como os dados dela vêm.
O que deve importar para ele é que os dados do Resultset a ser retornado deve obedecer à uma condição. Mas a forma como essa condição é criada deve ser indiferente para Model.
mas você esta certo @bruno...deveriamos ter mais artigos falando sobre este tipo de assunto...as pessoas confundem muito coisas basicas...model, modelo ou seja banco de dados, controller, controle ou seja controlar, view, visualizacao ou seja, ver enviar e receber do usuario, nao precisa ler um artigo tecnico de martin fowler pra saber disso, basta o ingles basico...
Uma coisa que eu digo: "Nem todas as regras foram feitas para serem seguidas". Tem gente que escreve talvez 100 linhas de código a mais porque o padrão é aquele.
Temos sempre que analisar qual será a melhor solução para nós mesmos e nossa equipe, analisar bem. Isso incluí performance, código limpo, responsabilidade das entidades, entre outros.
O ideal é sempre discutir com a equipe, ou se você está sozinho, faça do jeito que seja melhor para você. :D
Eu era assim Fernando. Não entendia os padrões, principalmente os de ORM, direito.
Lia, lia, lia, e não via sentido naquilo, com o conhecimento que tenho eu conseguia sim ver várias e várias voltas sendo dadas para chegar numa coisa que, hoje, eu faço de forma simples.
Relutei veementemente em codificar alguns de meus scripts porque ao tentar implementar o padrão, não saia a mesma coisa demonstrada pelos artigos. Eu estava muito focado em seguir, seguir, seguir que sequer tentava fazer o mesmo de outra forma.
Com isso, eu abstraí o máximo dos textos do Martin e de outras fontes e espero ter implementado tudo certo, mas os meus códigos nem sempre se parecem com aquilo que as modelagens indicam ser. Ou, se se parecem, eu não os vejo assim :unsure:
Resolvem os mesmos problemas, mas de forma muito mais simples do que aquelas que são mostradas nos exemplos do livro dele.
>
Eu era assim Fernando. Não entendia os padrões, principalmente os de ORM, direito.
Lia, lia, lia, e não via sentido naquilo, com o conhecimento que tenho eu conseguia sim ver várias e várias voltas sendo dadas para chegar numa coisa que, hoje, eu faço de forma simples.
Relutei veementemente em codificar alguns de meus scripts porque ao tentar implementar o padrão, não saia a mesma coisa demonstrada pelos artigos. Eu estava muito focado em seguir, seguir, seguir que sequer tentava fazer o mesmo de outra forma.
Com isso, eu abstraí o máximo dos textos do Martin e de outras fontes e espero ter implementado tudo certo, mas os meus códigos nem sempre se parecem com aquilo que as modelagens indicam ser. Ou, se se parecem, eu não os vejo assim :unsure:
Resolvem os mesmos problemas, mas de forma muito mais simples do que aquelas que são mostradas nos exemplos do livro dele.
Eu li bastante sobre padrões de projeto e com eles eu entendi o porque de alguns conceitos da orientação a objetos.
Hoje, eu nem sou um especialista em orientação a objetos, nem em padrões, seria bom eu procurar saber mais sobre isso, mas atualmente o modelo de programação aqui é quase sem orientação a objetos. :/
Eu também era assim, ficava desesperado achando que padrões de projeto iam facilitar tudo, a realidade é que, muitos padrões são usados em casos específicos, que não é tão comum ver no dia-a-dia, já outros são bastante usados, como o MVC e Singleton. Outra coisa é que, se você quiser implementar um sistema novo usando padrões de projeto e POO, você vai ter que conversar bastante com a equipe ou pensar bastante sozinho, porque não é nada fácil desenvolver algo usando essas metodologias, já que são conceitos bastante avançados.
Enfim, o cara que criou o tópico, não vejo problema em usar essa metodologia desde que fique fácil para ele ou para a equipe. Além disso, mais pessoas poderiam discutir aqui para termos mais conclusões sobre o assunto. :D
Ressucitando o tópico...
Eu já vi alguns casos e/ou li relatos de programadores dizendo que validam as informações antes de ir pro banco na própria Model.
Apesar de nunca ter visto na real um exemplo desse tipo, me parece errado fazê-lo. Eu penso que a função do Controller é justamente controlar informações e o fluxo delas entre as outras duas camadas.
Não... Está correto, validação de dados para inserção na tabela é sim responsabilidade do model.
No controller vão validações referentes à requisição, como dados vazios, se uma requisição é POST quando deveria ser, etc...
Sem querer ser São Tomé nem nada, mas você pode "provar"?
No caso da programação Web, minha View seria todo HTML que eu iria processar certo?
Se eu quero verificar se os dados estão vazios, tipagem, etc. seria feito no controller? E validação de negócios, como verificar se um cliente é físico ou jurídico, se é menor que 18 anos, etc. é feito na Model? Essas validações da Model geralmente são feitas num método get e set né?
Classes que irão "refletir" a estrutura do banco de dados, e que mapearão dados para o banco de dados, são definidos na Model? Quando falo mapearão, digo tanto atualizar, buscar, inserir, deletar...
Queria saber sobre isso galera :D
>
Se eu quero verificar se os dados estão vazios, tipagem, etc. seria feito no controller? E validação de negócios, como verificar se um cliente é físico ou jurídico, se é menor que 18 anos, etc. é feito na Model? Essas validações da Model geralmente são feitas num método get e set né?
A validação não precisa ser a mesma classe que tem seus métodos get e set.
Exemplo:
class Pessoa {
// propriedades e métodos get e set
}
class PessoaNegocio {
private $pessoa
public setPessoa(Pessoa $pessoa){
$this->pessoa = $pessoa;
}
// validações de negócio e persistência
}Outra coisa é que, se você quiser implementar um sistema novo usando padrões de projeto e POO, você vai ter que conversar bastante com a equipe ou pensar bastante sozinho, porque não é nada fácil desenvolver algo usando essas metodologias, já que são conceitos bastante avançados.
Disse tudo! Padrões de Projeto em Desenvolvimento de Sistema é algo que EU tenho achado um pouco complexo e de difícil implementação. Bom, eu tenho uma necessidade em que preciso implemenar isso, mas estou tentando implementar para aprender, pois só dando "tiro no pé" pra aprender. Sei que possivelmente estou fazendo de forma errada, mas é a forma que EU encontrei para tentar melhorar minha visão e raciocício do OO, além de aprender usar certas coisas do PHP, que acredito ser usado em grande maioria nos Padrões de Projeto.
Estou fazendo errado em usar algo que não preciso? Pode ser que sim, mas e daí? Conheço muitas pessoas que não se aprofundaram em algo por que nunca precisou, aí ficaram / ficam na mesma e não evoluem nunca.
Esses conceitos pode considerar em avançado? :unsure:
Eu não tenho nada de avnançado, é muito pelo contrário! :lol:
A validação não precisa ser na mesma classe que tem seus métodos get e set.
Mas nesse caso, a classe Pessoa tem métodos gets e sets que serão utilizados para retornar dados filtrados ou validar entrada de dados, respectivamente? Isso é, verificar se os dados estão corretos?
Já na classe PessoaNegocio, é feita tanto validação de negócios quanto persistência de dados?
PessoaNegocio fica na Model? Pessoa fica aonde?
Minhas outras afirmações estão corretas?
Sei que possivelmente estou fazendo de forma errada, mas é a forma que EU encontrei para tentar melhorar minha visão e raciocício do OO, além de aprender usar certas coisas do PHP, que acredito ser usado em grande maioria nos Padrões de Projeto.
Uma hora ou outra nós percebemos quando estamos fazendo a coisa certa, ou errada. Para saber se estamos fazendo a coisa certa, leva muito tempo, talvez nunca saberemos. Mas nem sempre fazer um "pouquinho" errado não é prejudicial. Lembrando que é tudo questão de análise também, se for um projeto simples, um pequeno desvio não será fatal, mas numa biblioteca de classes complexa de uma linguagem de programação por exemplo, essa sim requer muita análise.
Esses conceitos pode considerar em avançado? :unsure:
Bom, se é algo extremamente avançado não sei cara, mas não é tão fácil entender de primeira não. O ideal é nunca para de observar esses conceitos, sempre buscando alguns códigos de outros programadores e analisar suas ideias utilizadas neles. :D
Mas nem sempre fazer um "pouquinho" errado não é prejudicial. Lembrando que é tudo questão de análise também, se for um projeto simples, um pequeno desvio não será fatal, mas numa biblioteca de classes complexa de uma linguagem de programação por exemplo, essa sim requer muita análise.
Análise eu já acho mais difícil, e sempre é mais demorada, e é o que ganha mais! kkkkkk
Bom, se é algo extremamente avançado não sei cara, mas não é tão fácil entender de primeira não. O ideal é nunca para de observar esses conceitos, sempre buscando alguns códigos de outros programadores e analisar suas ideias utilizadas neles.
Com certeza não, exige muito estudo. E sempre que tenta implementar algo, no final você olha e diz:
>
Nossa, que porcaria!
:lol: então lá vai de novo analisar o diagrama UML, só que desta vez com mais atenção.
Muita dessa coisa toda já esta pronto nos Frameworks, é importante entender, mas desenvolver novamente, bem... nos dias de hoje... apenas numa necessidade ou para aprender de verdade.
Eu prefiro ganhar dinheiro e fazer meu trabalho direito do que ficar dando voltas.
>
Muita dessa coisa toda já esta pronto nos Frameworks, é importante entender, mas desenvolver novamente, bem... nos dias de hoje... apenas numa necessidade ou para aprender de verdade.
Eu prefiro ganhar dinheiro e fazer meu trabalho direito do que ficar dando voltas.
Eu faço isso pra aprender de verdade, e não quero ficar dependente de Framework algum, além do mais, não vou deixar de trabalhar direito por que estou correndo atrás de conhecimento.
Também prefiro ganhar dinheiro, é obvio, mas só isso pra MIM não basta.
>
Eu faço isso pra aprender de verdade, e não quero ficar dependente de Framework algum, além do mais, não vou deixar de trabalhar direito por que estou correndo atrás de conhecimento.
Também prefiro ganhar dinheiro, é obvio, mas só isso pra MIM não basta.
Isso é pessoal. O mercado pensa um pouco diferente.
Mas ninguém esta obrigado a seguir padrão algum... ou esta?
Sei lá, os Frameworks são muito bons, mas é sempre legal você entender eles, a tal ponto de você ser capaz de reconstruir um sozinho. Mas é lógico que você não iria perder tempo reconstruindo um framework, só digo que é bom você ter um conhecimento nesse nível, pois se um dia você entra numa empresa "f***", provavelmente terá que construir uns frameworks. Acredito que um exemplo seja empresas que desenvolvem jogos, provavelmente elas devem criar um framework para ser usados em seus projetos. Outro exemplo é a Google, que se não me engano, criou o sistema operacional Android né? Então esses dias eu observei um esquema de classes desse sistema operacional.
Imagina que doido um dia você construindo sistemas operacionais para empresas privadas? Isso requer bastante conhecimento... hehe :D
É lógico que isso não é tão comum no dia-a-dia, mas dizem que aquela tal Área 51 (se é que existe), tem um sistema operacional próprio que apenas algumas pessoas sabem usar / relizar manutenção nele. Isso sim deve ser da hora. Mas acho que nesse caso o foco é mais programação em baixo nível.
>
Isso é pessoal. O mercado pensa um pouco diferente.
Mas ninguém esta obrigado a seguir padrão algum... ou esta?
Claro que não, mercado tá nem aí se você sabe vários ou nenhum padrão de projeto, porém quem sabe e entende BEM de OO se destaca e MUITO no mercado, isso eu afirmo com certeza. E para completar, minha resposta é a mesma do FK, é exatamente o que penso.
Usando os mesmos exemplos que ele deu...
Android, sistema operacional, Linux... reuso.
Principal linguagem de programação do Android, Java... reuso.
Isso retira o mérito dos arquitetos que trabalharam no desenvolvimento e aprimoramento desses projetos? Não. E mais, ganharam um monte de tempo e dinheiro. rs
Não quero mudar a opinião de ninguém, alias, nem acho que o faria.
Estou apenas argumentando, não esperava mesmo que concordassem. ;)
Bom, cada um tem sua opnião, você não está errado, são apenas visões diferentes.
Sem querer ser São Tomé nem nada, mas você pode "provar"?
Basta seguir um pouco a lógica.
Como eu valido, por exemplo, um e-mail???
Ele tem lá sua ER de validação.
Agora, quem deve saber como um e-mail válido deve ser? O controller?
Não, o controller (no contexto web) trata de requisição, nada mais...
Na view obvimente também não, então nos resta o model.
Meio simples demais não?
Vamos pensar em algo mais complexo.
Imagine que estamos projetando um sistema de controle de reservas e mesas de um restaurante.
Um dos requisitos do sistema é permitir ao garçom juntar mesas caso haja muitas pessoas juntas.
Ao juntar uma mesa, ele escolhe uma mesa "master", que agregará as outras mesas e terá os pedidos de todas as outras atribuídas a ela naquele momento.
Para juntar mesas, o garçom vai lá no sistema e informa que as mesas foram agrupadas, escolhendo a mesa "master" e a sua nova mesa "filha".
Agora imagine a seguinte situação: o garçom se confunde e escolhe a própria mesa "master" para ser adicionada como "filha".
Vai ser necessário ir até o banco de dados e descobrir qual é a mesa "master" e compará-la com a mesa sendo adicionada.
É papel de quem realizar essa validação? Na minha humilde opinião, ninguém além do model pode ter essa responsabilidade...
Encerro meu caso, meretíssimo...
Programação Orientada à Advocacia :lol:
Valeu por elucidar.
Taí um assunto interessante.
Eu já vi alguns casos e/ou li relatos de programadores dizendo que validam as informações antes de ir pro banco na própria Model.
Apesar de nunca ter visto na real um exemplo desse tipo, me parece errado fazê-lo. Eu penso que a função do Controller é justamente controlar informações e o fluxo delas entre as outras duas camadas.
E por controlar informações vejo como responsabilidade dele verificar, por exemplo, se um parâmetro GET o qual servirá de base para uma cláusula WHERE existe ou não.
Os parâmetros GET são intimamente ligados à Requisição feita e a Model, que interage com o banco não deve saber o quê é uma Requisição, de onde ou como os dados dela vêm.
O que deve importar para ele é que os dados do Resultset a ser retornado deve obedecer à uma condição. Mas a forma como essa condição é criada deve ser indiferente para Model.