Usamos cookies para medir audiência e melhorar sua experiência. Você pode aceitar ou recusar a qualquer momento. Veja sobre o iMasters.
Estou estudando o modelo MVC e surgiram algumas dúvidas sobre a arquitetura e sobre boas práticas.
Pelo muito que eu li por ai, a coisa acontece mais ou menos assim na camada Model:
Bean - cliente.class.php
Somente atributos, GETs e SETs.
Acao- clienteAcao.class.php
Cria o objeto cliente (bean) e o envia para o objeto de persistencia DAO.
DAO - clienteDAO.class.php
Recebe o objeto Cliente (bean) e insere seus dados no banco.
Acontece que já vi várias opiniões de programadores experientes afirmando que este formato está errado, pois não está de acordo com os conceitos de orientação a objetos.
O Bean ou entidade é uma classe burra que não reflete o conceito de objeto, pois possui somente atributos. Uma classe deve representa um objeto, que possui atributos (variáveis) e comportamento (métodos). Da forma como está, os atributos estão na calsse Cliente o comportamento na classe ClienteAcao. Portanto, o correto, segundo estes programadores que citei, seria unificar a classe Cliente com a classe clienteAcao.
Bem, eu fiz isso, mas encontrei um grande problema, pois a classe de persistencia DAO recebe um objeto Cliente, mas como fazer isso se é própria classe cliente que chama os métodos da DAO? A única forma que encontrei pra fazer isso foi criar algo semelhante ao Pattern Singleton, ou seja, a própria classe Cliente cria um objeto de si mesma e repassa para a classe DAO. Isto está correto ou é uma gambiarra?
Aqui tem uma referênciasobre o uso de Beans, só q voltado para Java, mas o conceito é o mesmo.
>
Bom, uma vez que você está trabalhando com Cliente e uma empresa pode (e precisa) ter mais do que um cliente, Singleton não é a abordagem correta.
Eu usei uma solução semelhante ao Singleton, onde a Classe retorna uma instância dela mesma, mas não impedi a criação de novos objetos.
Algo mais ou menos assim:
class Cliente
{
private static $objCliente;
private $nome;
public static function getCliente()
{
$objCliente = new Cliente;
return $objCliente;
}
....
public function inserir()
{
$objCliente = self::getCliente();
$dao = new clienteDAO();
$dao->inserir($objCliente);
}
}
>
O tipo Cliente nada mais é que uma estrutura de dados, onde relacionamos os dados do nosso banco com um objeto conhecido, quando fundimos alguns métodos para inserir, atualizar ou deletar um registro no banco podemos chamar de ActiveRecord:
Pois então, como eu andei lendo por ai, estão dizendo que utilizar classes como estrutura de dados (classes burras) é uma abordagem equivocada, pois um objeto tem que ter comportamento também.
>
Porém, independente da abordagem que for utilizada, MVC é uma forma de separar as camadas, deixando o que é referente a banco de dados em uma camada, controle de fluxo em outra e exibição em outra. Você pode utilizar VO + DAO, ActiveRecord ou uma outra forma qualquer, o importante é não misturar banco de dados com exibição e controle.
Estas mesmas pessoas que citei, condenam o uso dos VOs e BOs, conforme este artigo: Evitando VOs e BOs
Não estou defendendo o que estas pessoas estão afirmando, mas quero entender direito os conceitos para evitar de usar OO de maneira estruturada (como andava fazendo).
>
Pois então, como eu andei lendo por ai, estão dizendo que utilizar classes como estrutura de dados (classes burras) é uma abordagem equivocada, pois um objeto tem que ter comportamento também.
Bom amigo, acho que isso já é um tanto pessoal. Eu uso muito classes como tipo:
class User {
protected $name;
protected $email;
protected $pswd;
}
Principalmente quando estou trabalhando com webservices.
Como disse, já estou usando o Active Record (Bean com regras de negócio), mas aliado ao DAO (executa as SQLs), só que estou tendo um problema em passar um objeto de uma classe a outra.
Veja o que acontece:
A classe Cliente instância a classe ClienteDAO. Para eu inserir algo no banco, preciso invocar o método inserir() de ClienteDAO e passar um objeto do tipo cliente. Bem, como fazer isso se eu chamo esse método na própria classe Cliente?
class Cliente
{
private $nome;
private $dao;
public function getNome(){ return $this->nome; }
public function setNome($nome) { $this->nome = $nome; }
public function __construct()
{
$this->dao = new ClienteDAO;
}
public function salvar()
{
if ($this->dao->inserir(---- COMO PASSAR O OBJETO CLIENTE SE ESTOU DENTRO DA CLASSE CLIENTE???? ----))
echo 'salvou o objeto cliente de nome: ' . $this->nome;
}
}
class ClienteDAO
{
public function inserir(Cliente $objCliente)
{
$query = mysql_query("INSERT INTO cliete (nome) VALUES ('" . $objCliente->getNome() . "')");
if ($query)
return true;
else
return false;
}
}
Bem, foi por causa dessa situação que usei aquela solução: criar um método getCliente() na classe Cliente, que cria uma instância dela mesma.
Mas o q quero saber é qual a forma mais elegante de se fazer isso? Utilizar o Pattern Active Record aliado ao DAO sem gambiarra.
Descobri como resolver o problema, só não sei se é elegante. http://forum.imasters.com.br/public/style_emoticons/default/yay.gif
Basta passar o $this como parametro para o método.
O que vocês acham, gambiarra ou não?
Eu uso o Pattern VO (de Value Object) em conjunto com o Pattern DAO (de Data Access Object).
Um ActiveRecord,como proposto pelo batista e por vários programadores é muito interessante,mas tem lá seus problemas,como as duas Patterns apresentadas.Analise o que é melhor para o seu caso.
E no jeito apresentado,é gambiarra sim.Parte do que você fez deve ser implementado em um Controlador,e os comportamentos devem ser mais separados...
class ClienteVO/.../
{
//...
}
class ClienteDAO/.../
{
public function insert(ClienteVO $cliente)
{
//...
}
//...
}
class ClienteController/.../
{
public function indexAction(/*...*/)
{
//...
}
public function extractAction(/*...*/)
{
//...
$clienteDAO = new ClienteDAO();
$clienteVO = new ClienteVO();
//...
$clienteDAO->insert($clienteVO);
//...
}
//...
}
>
Bem, eu fiz isso, mas encontrei um grande problema, pois a classe de persistencia DAO recebe um objeto Cliente, mas como fazer isso se é própria classe cliente que chama os métodos da DAO? A única forma que encontrei pra fazer isso foi criar algo semelhante ao Pattern Singleton, ou seja, a própria classe Cliente cria um objeto de si mesma e repassa para a classe DAO. Isto está correto ou é uma gambiarra?
Bom, uma vez que você está trabalhando com Cliente e uma empresa pode (e precisa) ter mais do que um cliente, Singleton não é a abordagem correta.
class Cliente {
O tipo Cliente nada mais é que uma estrutura de dados, onde relacionamos os dados do nosso banco com um objeto conhecido, quando fundimos alguns métodos para inserir, atualizar ou deletar um registro no banco podemos chamar de ActiveRecord:
class ActiveRecord {
class Cliente extends ActiveRecord {
Porém, independente da abordagem que for utilizada, MVC é uma forma de separar as camadas, deixando o que é referente a banco de dados em uma camada, controle de fluxo em outra e exibição em outra. Você pode utilizar VO + DAO, ActiveRecord ou uma outra forma qualquer, o importante é não misturar banco de dados com exibição e controle.