Usamos cookies para medir audiência e melhorar sua experiência. Você pode aceitar ou recusar a qualquer momento. Veja sobre o iMasters.
Boa tarde a todos!
Estou iniciando meu primeiro sistema em PHP orientado a objetos depois de muitos anos nas profundezas do Classic ASP.
Imagino que todos que já programam OOP devem ter passado por momentos difíceis logo no início. Esse negócio de classes, abstração, interfaces, métodos, etc ainda são confusos para mim.
O sistema que estou trabalhando é um gerenciador de clientes e processos de um consultoria imobiliária.
Bem, minha primeira dúvida é: neste sistema terei clientes e funcionários acessando o sistema. Os clientes terão mais informações no banco do que o funcionários. Logo de cara eu pensei: "Vou criar uma classe de clientes e outra para funcionários". Depois eu percebi que ambos, na verdade, são usuários do sistema e compartilham métodos. Pergunto: O mais correto seria criar uma classe usuarios com métodos comuns e depois criar classes funcionario e cliente que herdam esses métodos?
Outra dúvida: Também criei uma classe Validacao, que verifica os dados recebidos (cpf, senha, nome, etc) e cada classe (cliente e funcionário) utiliza os métodos da classe Validacao para verificar os dados recebidos. Isso é correto ou o certo seria implementar a validacao dentro das classes de usuários?
No final das contas ainda acho que estou apenas criando um bando de funções dentro de classes. Não estou com a impressão de que estou no caminho certo.
Abs.
Legal Henrique! Muito obrigado pela resposta e pela clareza do exemplo.
Realmente isso tudo ainda é bastante confuso, principalmente depois de anos de programação procedural. É difícil saber o que usar e quando usar.
Vou pesquisar sobre o Strategy e aos poucos sobre o MVC.
O que você quis dizer com isso?
>
[...] O mais correto seria criar uma classe usuarios com métodos comuns e depois criar classes funcionario e cliente que herdam esses métodos? [...]
Na verdade o que imagino é:
um cliente e um funcionário são usuários do sistema. Cada um com tipos de acesso diferentes e atributos diferentes. Um funcionário não precisa ter o atributo "imóvelComprado", mas o cliente sim. Então eu imagino que o correto seria criar uma classe Usuarios com atributos comuns aos usuários e dessa classe eu criaria as classes Funcionario e Cliente que herdariam a Usuarios. Esse pensamento está correto?
O que eu acho compliado na OOP é que os textos e livros sobre o assunto são muito teóricos... Na prática você fica meio perdido. Como não tenho alguém que possa ensinar, com certeza vou demorar muito para aprender na prática sobre a utilização da OOP.
Ainda bem que nos fóruns encontramos pessoas com vontade de ajudar.
vou começar a mudar a ideia de validação.
Obrigado!
Se Funcionario e Cliente têm atributos comuns, o melhor é reunir esses atributos numa classe abstrata. Seu pemsamento está correto.
abstract class Usuario{...}
class Cliente extends Usuario{...}
class Funcionario extends Usuario{...}
Então cara... Utilizando MVC, você percebe que esse tipo de método não pode ficar na mesma classe que contem as informações do usuário.
A classe Usuario seria uma entidade, que faz parte do model. Você precisaria de uma outra classe para executar operações sobre o usuário. Eu costumo chamar essas classes de 'ApplicationModels', então você poderia ter uma UsuarioAppModel.
Observe que herança só faz sentido se a intersecçao entre dois tipos é relevante. Por exemplo, ambos os tipos de usuário têm acesso ao sistema? Ambos possuem interações com o sistema parecidas?
Caso julgue que sim, essa classe (UsuarioAppModel) poderia tratar objetos de uma classe abstrata AbstractUsuario, a qual seria derivada por Usuario e Funcionario. Lá dentro da classe UsuarioAppModel, poderia fazer algumas condicionais para verificar se estás trabalhando com Usuário ou Funcionario (imagino que sejam 2 tabelas diferentes no BD). Isso se você tem CERTEZA ABSOLUTA que seu sistema não terá outros tipos de usuários, caso não tenha, é preciso repensar um pouco.
[]
Menino Levado, obrigado pela resposta. Acho que aos poucos estou encontrando o caminho.
Rick, pelo pouco que vi do mvc acho que no nível em que estou na OOP ele vai trazer mais dúvidas do que soluções. Você não acha que o ideal é progredir aos poucos?
O sistema, pelo menos foi o pedido do cliente, está previsto para ter 3 tipos de usuários: clientes, funcionários e diretoria (sim, funcionários e clientes tem tabelas diferentes). funcionários e diretoria tem os mesmos atributos, o que muda é que a diretoria terá acesso a relatórios e alguns campos que os funcionários não têm. Não acredito que isso vá mudar, mas ninguém pode garantir.
Outra dúvida: Como eu poderia fazer a implementação de segurança dos registros que serão inseridos no banco de dados? Criaria um nova classe Seguranca ou seguiria o mesmo conceito de padrão Strategy que você indicou?
Se os conceitos de interface e abstração ainda estão confusos, imagine acrescentar novos conceitos como o MVC? :)
Você tem alguma sugestão de site para estudar o MVC?
Pra finalizar, coloquei seu código de exemplo para testar e não entendi um erro: na linha:
private $nome = new Campo('', new ValidacaoNaoVazio());
informa um new "Não esperado"...
Só funciona se eu coloco o private $nome = new Campo('', new ValidacaoNaoVazio()); dentro da função inserirUsuario. Além disso, também tenho que remover o private...
Tem ideia do motivo?
Pois é... de fato pode levantar algumas dúvidas...
Aqui tem um exemplo bem simples em PHP mesmo: http://www.revistaph...rtigo.php?id=50
O MVC foi concebido inicialmente para a linguagem Smalltalk, que funciona de uma maneira um pouco diferente, pois é feita para aplicações desktop.
Em linguagens web, boa parte da camada de Controle é feita automaticamente pelo navegador. A camada de Visão possui uma linguagem própria [(x)HTML].
Eu recomendo a você então pelo menos separar a apresentação da lógica do negócio. Tenha arquivos com classes que te retornam o resultado que deseja e arquivos apenas para apresentação, contendo essencialmente HTML e os dados prontos para apresentação ao usuário.
Para a camade de segurança, é diferente. Perceba que um padrão representa um problema em específico. Seu uso em lugares incorretos ou desnecessários também representa um erro.
Está usando qual SGDB? MySQL?
A maneira mais simples de se evitar um ataque via SQL injection no MySQL é utilizar a função real_escape_string.
Caso esteja utilizando a extensão OO e melhorada mysqli, utilize o método mysqli::real_escape_string($input) em todos os dados provenientes do usuário.
Para outros tipos de segurança, eu recomendo você dar uma olhada no padrão Intercepting Filter. A maioria dos exemplos você encontrará em Java, mas não é difícil adaptá-los para o PHP.
Como é um sistema pequeno, prefiro dar pequenos passos para não atravessar o aprendizado.
Bom os detalhes do sistema é que será em php com mysql e estou utilizando o Smarty para separar o código da apresentação.
Como é meu primeiro sistema OOP eu acho que vou colocando partes do sistema aqui para a galera avaliar a ajudar.
Bom, vou reescrever o que já fiz.
Muito obrigado pela ajuda.
Sim, claro... tem que saber dimensionar esforço e retorno.
Mas você não pode nunca subestimar o seu sistema.
Pense que amanhã seu cliente pode querer uma nova funcionalidade, ou alterar uma já existente.
Não estou dizendo para você aprender tudo de uma vez e só depois começar a desenvolver, não é assim, temos contas a pagar B).
Digo isso para que você continue sempre buscando um aperfeiçoamento, para evitar dores de cabeça depois.
Te dou um exemplo: há 3 anos eu comecei a desenvolver um 'projetinho'. O problema é que o projetinho cresceu e virou um 'projetão'.
Quando comecei a desenvolver era iniciante, como você. Acontece que quando a coisa foi crescendo, virou uma bola de neve, ficou difícil de dar manutenção, cada mudança era uma dor de cabeça, cada funcionalidade adicionada era um sacrifício.
Até hoje eu ainda faço muita cagada, mas é um processo looongo. Um dia eu chego lá... você também...
Boa sorte aí,
[]
Pois é, eu recentemente passei por isso. Desenvolvi um sistema em ASP por conta da rapidez que o cliente demandava e, como eu sabia programar rápido em ASP, não pensei duas vezes... Hoje quando preciso alterar qualquer coisa é um sufoco! Foi por isso que resolvi aprender OOP e me aprofundar no PHP.
Valeu pela ajuda. Vou tentar começar pelo começo! :) Devagar e sempre.
Dica:
:seta: Curso PHP Orientado a Objetos :seta: http://pro.imasters.com.br/online/cursos/php-orientado-objetos
:seta: Curso MVC em PHP na Prática (construindo um sistema de pedidos) :seta: http://pro.imasters.com.br/online/cursos/mvc-em-php-na-pratica-construindo-um-sistema-de-pedidos
Cara... eu recomendo a você estudar sobre MVC para facilitar [ou não] sua vida.
O que você quis dizer com isso?
Segundo, sobre a validação, na minha opinião, nenhum dos dois é correto.
Qual a diferença de criar uma classe 'Validacao' que contenha vários métodos estáticos para TODOS os tipos de validação do seu sistema e criar um bando de funções para fazer o mesmo?
Colocar a validação na classe de usuários seria atribuir responsabilidades demais a essa classe.
O que fazer então?
Cara, é meio complicado fazer 'do jeito certo'...
A validação se diz respeito a um dado atributo, certo?
Então cada atributo da classe deveria ser validado individualmente, certo?
Você deveria então não utilizar valores primitivos para os atributos da classe, mas sim encapsulá-los em uma classe, exemplo: classe 'Campo', que conteria o valor primitivo do campo e uma outra propriedade para definir como seria feita a validação.
Recomendo você pesquisar sobre padrões de desenvolvimento, em especial para este caso, sobre o padrão 'Strategy'.
Ele se encaixa perfeitamente aqui, pois ele representa um 'algoritmo flutuante', já que a validação varia de campo para campo.
Aquela propriedade seria uma 'estratégia de validação' que seria executada antes de inserir os dados.
Eu sei que é meio confuso, mas vou dar um exemplo bem simples aqui:
<?php
class Campo {
interface iValidacao(){
class ValidacaoEmail implements iValidacao(){
class ValidacaoNaoVazio implements iValidacao(){
class Usuario {