Ir para conteúdo

POWERED BY:

Arquivado

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

criatividade zero

[Resolvido] MVC vantagens/desvantagens

Recommended Posts

peguei inumeros exemplos de MVC e preticamente todos são:

 

class Control{ ... }
class Model{ ... }
class View{ ... }
um chama o outro e o outro...

 

 

queria saber qual a vantagem/diferenca em usar classes como esses modelos

e pq não poderia ser um control com includes

class Control{
 include model
 include view
}

 

alguem poderia me dar essa explicação?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Questão de boa prática... não se dá includes dentro de classes...

O que você pode fazer é uma composição, ou seja, um objeto 'contém' o outro...

 

Na minha opinião, e quem discorda, por favor explique-nos o porquê, o CONTROLLER deve ser uma composição do VIEW e do MODEL...

 

VIEW JAMAIS deve conter um CONTROLLER e acredito que da mesma forma, um MODEL não tem porque conter um CONTROLLER também...

 

Atualmente na minha base de trabalho eu tenho algo assim:

 

class UserController {
	private $view;
	private $model;
	
	public function __construct(){
 	$this->view = new UserView();
 	$this->model = new UserModel();
	}
}

Compartilhar este post


Link para o post
Compartilhar em outros sites

Model, View, Controller

 

Classes de modelo, são a sua lógica de negócio. Se você tem uma aplicação de estatísticas, todo o algoritmo de estatística vai ficar nas suas classes de modelo ( classes de negócio ).

 

View, será a saída HTML a qual um usuário (seja visitante, ou admin) vai ter acesso. pode ser uma home ou um painel administrativo. tanto faz View é a tela. Muita gente usa Engines de template ( a mais conhecida é o Smarty-Template).

 

Controller é o cara que vai receber a requisição. Esse é o cara que recebe as requisições via get ou post. Inicializa os objetos de "negócio" e de "View" (saída html). Esse cara trata a requisição, passa a bola para uma classe de negócio, a classe retorna um resultado e dependendo do resultado ele mostra uma View.

 

por exemplo, pode ser que a requisição retorne um artigo armazenado no banco de dados, ou pode ser que ela dê algum erro. Daí cabe ao contralador (Controller) mostrar uma tela de erro .

 

basicamente é isso.

tem uns frameworks parrudos como ZendFramework, que trabalha assim. Tem um mais simples chamado CodeIgniter, e um recente chamado Sppagetti.

 

Praticamente todos os frameworks acima utilizam mapeamento da URL com expressões regulares no arquivo ".htaccess"

 

por isso. corra atras de aprender expressões regulares.

dê uma olhada em __autoload, uma função mágica do php que ajuda pra caramba.

 

Aqui tem um tutorial de como carregar classes com essa função, é bem mais fácil do que dar include em cada classe que você criar.

 

bom é isso..

qualquer coisa posta aí.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Só um adendo...

A implementação 'na raça' do conceito de MVC leva tempo...

 

Até hoje estou nisso... não pelos conceitos, que acredito ter compreendido mais que bem já, mas tal separação de camadas pode levar a certa duplicação de código, que faz com que o desenvolvimento seja

chato e custoso...

 

Muita gente fala: aprende um framework...

 

Eu acredito que não deva ser assim. Primeiro você tem que aprender na raça, entender as dificuldades e só depois partir para um framework, entender o porque do mesmo realizar uma operação de um jeito e não de outro...

 

Estou nessa há mais ou menos 1 ano e meio, creio que em mais 1 ou 2 anos finalmente vou estar pronto pra largar o trabalho pesado para algum framework e me divertir mais com os projetos...

Compartilhar este post


Link para o post
Compartilhar em outros sites

eu sei o que cada sigla MVC faz

tenho meu MVC rodando sem problemas e sei tudo que cada classe so nao sei o pq de nao usar include

 

class UserController {
        private $view;
        private $model;
        
        public function __construct(){
        $this->view = new UserView();
        $this->model = new UserModel();
        }
}

no seu controller você define a view - $this->view = new UserView();

ela provavelmente sera incluida por uma função na sua classe 'mestre'

 

ja testei uma classe 'mestre' instanciando o controller e nele include pra model e pra view e o resultado foi identico... so nao sei o motivo de não usar include

Compartilhar este post


Link para o post
Compartilhar em outros sites

O problema é ficar dando includes desnecessários...

Pesquise pela função mágica __autoload e você vai entender que não é necessário dar include dentro de classes...

Compartilhar este post


Link para o post
Compartilhar em outros sites

estou citando 2 formas de se fazer e procurando seus pros e contras

 

Amigo,

 

O foco do MVC é a VIEW, ele nasceu para que fosse assim e qualquer interpretação diferente disso está equivocada então, ao construir um MVC, pense exclusivamente na View.

 

O que significa pensar na View ?

 

Pense que a única forma do usuário interagir com sua aplicação é através da View, utilizando sua interface de usuário (GUI), clicando em botões, escolhendo opções em menus e enviando formulários.

 

Toda ação do usuário, através exclusivamente da View, deve ter uma reação, ou seja, se o usuário clicou em um botão "Enviar" ele quer enviar alguma coisa, se ele clicou na opção produtos do menu, ele quer ver os produtos.

 

Para que os produtos sejam exibidos ou os dados gravados em um banco de dados, o participante Controller entra em ação.

 

É o controlador que receberá a requisição do usuário e decidirá o que fazer com ela, é através do Controller que você saberá qual Model será acionada (para exibir os produtos ou gravar alguma coisa) e é exclusivamente através do Controller, que páginas de erro são exibidas ao usuário.

 

O Controller pode fazer uma validação da requisição, segundo regras gerais da aplicação, mas a responsabilidade de validação e tratamento dos dados é exclusivamente da Model que, como o @rodrigo I.O disse, é onde estão suas regras de negócio.

 

Imagem Postada

O diagrama estrutural acima ilustra o que é o MVC.

 

Não é responsabilidade do padrão MVC especificar como seus objetos são instanciados.

Não é responsabilidade do padrão MVC especificar sua estrutura de diretórios ou como você organiza seus arquivos.

Não é responsabilidade do padrão MVC especificar como você localiza, carrega ou executa seu código.

 

O padrão MVC define apenas como o usuário interage com sua aplicação.

 

 

Imagem Postada

Uma vez compreendido que o foco do MVC é definir as regras de como o usuário interage com sua aplicação, utilizando exclusivamente a View, você perceberá que MVC é muito simples e, ao contrário do que muitos dizem, não é necessário frameworks, código complexo nem mágicas desnecessárias.

 

Pense em um combobox:

 

A parte que você vê do combobox é a View.

A parte que controla o clique do usuário, seja na setinha que exibirá o conteúdo interno do combo, ou em um item da lista é o Controller.

Os dados dentro do Combobox vieram da Model.

 

Um usuário entrou na sua aplicação:

 

1. Houve uma primeira requisição ao Controller, que decidiu que deveria carregar a página inicial.

2. Através da página inicial, o usuário clicou no item Produtos do menu.

3. O Controller recebe a requisição "produtos" e decide que deverá entregar a página de produtos.

3.1. Para entregar corretamente a página de produtos, o Controller chama a Model e pede a ela toda a lista de produtos

3.2. Com a lista de produtos, o Controller chama a View de produtos e entrega a lista de produtos.

3.3. A View monta a página corretamente com essa lista.

 

4. O Controller entrega a View produtos, já montada, em resposta à requisição do usuário.

 

Como pode ver, em nenhum momento foi dito, utilize o técnica X para carregar o arquivo Y e instanciar o objeto Z, e não foi dito pelo simples motivo de que isso não é importante e não diz respeito ao MVC.

 

Tudo o que você precisa para montar um MVC é compreender que uma ação do usuário na View espera uma reação e essa reação é de responsabilidade do Controller.

 

simples assim.

 

;)

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

então... um bocado de coisas ai eu ja aprendi em outros topicos com a sua ajuda :)

vamos la

 

Como pode ver, em nenhum momento foi dito, utilize o técnica X para carregar o arquivo Y e instanciar o objeto Z, e não foi dito pelo simples motivo de que isso não é importante e não diz respeito ao MVC.

 

Não é responsabilidade do padrão MVC especificar como seus objetos são instanciados.

Não é responsabilidade do padrão MVC especificar sua estrutura de diretórios ou como você organiza seus arquivos.

Não é responsabilidade do padrão MVC especificar como você localiza, carrega ou executa seu código.

então, seguindo à risca seria correto dar esse exemplo abaixo?

controller

pega informação do request e faz consulta_passarinho

 

model

funcão consulta_passarinho($request){

consulta banco

return resultado_passarinho

}

 

view

echo resultado_passarinho

 

 

nesse exemplo, controller, model e view possuem apenas o codigo de processo, o controller define a model para fazer a consulta

no exemplo do Rick

$this->model = new UserModel()

ele cria uma instancia da classe UserModel no controller

 

ai que fico na duvida de pq não meter um include('UserModel.php') dentro do controller

nao seria a mesma coisa?

apenas nao instanciaria uma classe e trataria as informações como variaveis comuns

 

 

tipo

class Controller{
	function funcao(){
		include('model.php');
		$teste = new teste();
		$var_teste = $teste-> testando();

		include('view.php');
	}
}
na view teria um simples echo $var_teste;

 

manteve os processos separados, apenas mudou a forma de chamada

Compartilhar este post


Link para o post
Compartilhar em outros sites

então, seguindo à risca seria correto dar esse exemplo abaixo?

controller

pega informação do request e faz consulta_passarinho

 

model

funcão consulta_passarinho($request){

consulta banco

return resultado_passarinho

}

 

view

echo resultado_passarinho

 

Sim, é exatamente isso

 

apenas nao instanciaria uma classe e trataria as informações como variaveis comuns

 

tipo

class Controller{
	function funcao(){
		include('model.php');
		$teste = new teste();
		$var_teste = $teste-> testando();

		include('view.php');
	}
}
na view teria um simples echo $var_teste;

 

manteve os processos separados, apenas mudou a forma de chamada

 

Funciona ?

 

Sim

 

É elegante ?

 

Não

 

Apesar de funcional, não é escalável, não é reutilizável e trará, com certeza, problemas de manutenção no futuro.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Apesar de funcional, não é escalável, não é reutilizável e trará, com certeza, problemas de manutenção no futuro.

quais por exemplo?

ainda nao consigo ter essa visão

 

-----

 

então o elegante, escalável, reutilizável e com menores problemas seria, classe + função por pagina

:)

 

class Control{ ... }
class Model{ ... }
class View{ ... }

o controller é individual, certo?!

reutilizável nao deveria ser apenas a model?

 

 

 

ainda tenho uma duvida

pegando o exemplo do Rick

 

class UserController {
        private $view;
        private $model;
        
        public function __construct(){
        $this->view = new UserView();
        $this->model = new UserModel();
        }
}
o controller define a model para fazer a consulta

ja tendo a view definida no controller, como fica se houver erro na consulta pela model?

 

 

controller pega informação do request e faz consulta_passarinho

$this->model = new PassarinhoModel();

$this->view = new PassarinhoView();

 

teria um view previamente definido mesmo sem saber:

se a consulta foi valida -> view_passarinho

se a consulta nao obteve retorno -> view_sem_passarinho

se a consulta foi invalida -> view_passarinho_erro

 

embolei :)

Compartilhar este post


Link para o post
Compartilhar em outros sites

eu penso que dar include de uma class dentro de outra, seria exatamente o mesmo que:

 

<?php
class Controller{
	function funcao(){
		class Model()
		{
			//código da Model
		}
		//continua código da funcao()
	}
}
e sinceramente hein?! =X

 

resposta do interpretador:

Fatal error: Class declarations may not be nested in D:\Arquivos de programas\Apache Software Foundation\Apache2.2\htdocs\index.php on line 4

agora, no teu exemplo, você fez 'pior ainda'!.. você deu include da Model, dentro de um método da Controller!

oras, imagina se você usar outro método depois que tb use a Model:

<?php
class Controller{
	function funcao(){
		class Model(){
			//código da Model
		}
		//continua código da funcao()
	}
	function funcao2(){
		class Model(){
			//código da Model
		}
		//continua código da funcao()
	}
}
hum...

 

$ctrl = new Controler();
$ctrl->funcao();
$ctrl->funcao2();
só nisso, foram 2 includes da Model...

 

tá tá... ai vem as gambiarras...

-> ahh.. usa o _once! :lol:

 

hehe, parece certo:

<?php
class Controller{
	function funcao(){
		include_once 'Model.php';
		//continua código da funcao()
	}
	function funcao2(){
		include_once 'Model.php';
		//continua código da funcao()
	}
}
?

 

tá bom... ai surgirá uma sugestão mais interessante!

-> ahhh.. faz o include no construtor! é lógico!

 

<?php
class Controller{
	function __construct(){
		class Model(){
			//código da Model
		}		
	}
	function funcao(){
		//continua código da funcao()
	}
	function funcao2(){
		//continua código da funcao()
	}
}
parece que melhorou? :lol:

 

acho que ficou pior.. e se você for usar o método funcao3(), que não precisa da Model?

putz... ai fez include da Model dentro da Controller sem a menor necessidade (nem vou comentar sobre o _once ser lento).

 

E se você tiver classes estáticas? putz... ai não tem construtor!

Entendeu os cenários acima ?

Compartilhar este post


Link para o post
Compartilhar em outros sites

quais por exemplo?

ainda nao consigo ter essa visão

 

Essa dúvida já sai do escopo do MVC e entra em orientação a objetos

 

o controller é individual, certo?!

reutilizável nao deveria ser apenas a model?

 

Visto que o Controller apenas trata as requisições e decide o que fazer com ela e a Model está relacionada com as regras de negócio, é possível fazer um controlador reutilizável para N aplicações, mas nem todas as aplicações compartilham das mesmas regras de negócio.

 

Dessa forma, dificilmente você terá Models reutilizáveis, já que elas são específicas para a aplicação, por outro lado, é possível abstrair o tratamento de requisições de forma a se conseguir um Controller reutilizável.

 

o controller define a model para fazer a consulta

ja tendo a view definida no controller, como fica se houver erro na consulta pela model?

 

$this->model = new PassarinhoModel();

$this->view = new PassarinhoView();

 

teria um view previamente definido mesmo sem saber:

se a consulta foi valida -> view_passarinho

se a consulta nao obteve retorno -> view_sem_passarinho

se a consulta foi invalida -> view_passarinho_erro

 

Mas ai é responsabilidade do Controller saber a hora correta para se fazer alguma coisa, por exemplo:

 

class UserController {
public function handle( Request $request ){
	$model = new UserModel();
	$message = null;

	try {
		if ( $request->method() == RequestMethod::POST ){
			$user = $model->login( $request->getField( 'userName' ) , $request->getField( 'userPassword' ) );
			$view = new UserProfileView( $user );
		} else {
			$view = new LoginFormView();
			$message = 'Login do usuário';
		}
	} catch ( InvalidLoginException $e ){
		$view = new InvalidLoginView();
		$message = $e->getMessage();
	} catch ( Exception $e ){
		$view = new GeneralErrorView();
		$message = $e->getMessage();
	}

	$view->draw( $message );
}
}

Compartilhar este post


Link para o post
Compartilhar em outros sites

proximo a esse exemplo que você deu, a logica de um controller para login de usuario seria +- essa:

 

class LoginUserController {
	public function handle( Request $request ){
		$model = new LoginUserModel();
		/*
		no model faço a consulta
		retorna bool e inicia sessão do usuario
		*/
		$returnLogin = $model->login( $request->getField( 'userName' ) , $request->getField( 'userPassword' ) );
		$view->draw( $returnLogin );	//view_true
						//view_false
	}
}

a função da model retornaria true/false e o controller usa como base para a view

sem entrar muito em detalhe e exatidão, apenas a ideia

Compartilhar este post


Link para o post
Compartilhar em outros sites

proximo a esse exemplo que você deu, a logica de um controller para login de usuario seria +- essa:

a função da model retornaria true/false e o controller usa como base para a view

sem entrar muito em detalhe e exatidão, apenas a ideia

 

No exemplo que eu dei, o retorno do método login é uma instância de User (entidade com os dados do usuário) se o login for aceito, isso porque a View precisará das informações do usuário para poder exibi-las.

 

Caso o login seja inválido, eu não retorno FALSE, ao contrário, eu disparo uma exceção que será pega pelo controlador.

 

É uma relação de confiança, o controlador confiará que a Model retornará, sempre, dados para serem utilizados pela View, se a Model não puder devolver dados consistentes, ela dispara uma exceção e a execução continua no catch apropriado.

Compartilhar este post


Link para o post
Compartilhar em outros sites

É uma relação de confiança, o controlador confiará que a Model retornará, sempre, dados para serem utilizados pela View, se a Model não puder devolver dados consistentes, ela dispara uma exceção e a execução continua no catch apropriado.

 

lerei mais sobre essas formas de retornar informação

entendi a ideia

vou por em pratica alguns testes :)

 

valeu a força

depois volto dizendo o que deu

[]s

Compartilhar este post


Link para o post
Compartilhar em outros sites

estudei outros exemplos que baixei, e um deles usa 'resumidamente' esse codigo

pelo que entendi ele usa a fnção define_var para criar e setar o valo da variavel

 

isso é similar àqueles metodos de interceptação?

esta correta essa forma?

 

 

function define_var( $var , $val ) {
	$this-> $var = $val;
}
controller

$teste = 'texto teste';
$this-> define_var( 'teste' , $teste);
$this-> carregaView('view.php');
view

echo $this-> teste;

Compartilhar este post


Link para o post
Compartilhar em outros sites

esta correta essa forma?

Amigo,

 

Como eu disse anteriormente, a forma que você utilizará para entregar e receber os dados das camadas é indiferente, isso não é importante do ponto de vista do MVC.

 

MVC foca na View e define a separação das responsabilidades de cada camada, apenas isso. Se o que você quer saber é como fazer para que as camadas comuniquem entre si, então o escopo é outro, está relacionado à orientação a objetos ou, mesmo que você trabalhe de forma procedural, não tem nada a ver com MVC.

 

A primeira coisa que você precisa decidir é se vai trabalhar com orientação a objetos ou de forma procedural.

 

Cada paradigma tem suas próprias características e você deverá trabalhar em cima dessas características para construir seu MVC.

Compartilhar este post


Link para o post
Compartilhar em outros sites

era so pra saber mesmo se a funcão estava correta

pretendo desenvolver com OO

:)

 

 

embora tenha meu MVC rodando, acho que é melhor eu por a mão na massa refazer do zero... ai depois eu posto um minimal

 

a ideia eu tenho, as funções tb, so preciso reordenar algumas classes

Compartilhar este post


Link para o post
Compartilhar em outros sites

pretendo desenvolver com OO

 

Então o primeiro passo é compreender orientação a objetos.

 

Estude os conceitos de encapsulamento e delegação, trabalhe sobre as interfaces dos objetos, jamais sobre suas implementações.

 

Quando compreender esses conceitos, dedique uma boa parte de seu tempo, modelando a aplicação e, somente então, comece a desenvolver.

 

Lembre-se que MVC foca na View, então comece desenhando as interfaces de usuário, não se preocupe com CSS, imagens, javascript, apenas desenhe as interfaces de usuário e trabalhe em cima disso.

 

Quando sua aplicação for navegável e seus controladores estiverem fazendo o trabalho deles, passe a trabalhar em usabilidade. Quando tudo estiver funcionando, passe a trabalhar com CSS, imagens e o restante do design da aplicação.

 

E nunca, jamais se esqueça, que o Google é seu amigo. Pesquise e estude muito e, se mesmo após pesquisar, restarem dúvidas, poste-as aqui.

 

;)

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.