Ir para conteúdo

POWERED BY:

Arquivado

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

Fabyo

Design Patterns

Recommended Posts

Pessoal vou tentar explicar o uso pratico de classes abstratas e Factory PHP5

 

Minha ideia é mostrar um uso pratico desses metodos, uma vez que vários usuarios podem ter lido no manual mas nao conseguindo entender como funciona acabam nao usando nem aproveitando as vantagens do uso desses metodos

 

Recomendo lerem o conteúdo desse links para um entendimento melhor, como falei vou mostrar só uns exemplos práticos.

 

http://br.php.net/manual/pt_BR/language.oop5.abstract.php

http://br.php.net/manual/pt_BR/language.oop5.patterns.php

 

alias se ler todo o assunto sobre oop é melhor ainda:

http://br.php.net/manual/pt_BR/language.oop5.php

 

vamos la um exemplo de uso de uma classe abstrata

 

nossa classe abstrata:

 

abstract class ClasseAbstrata
{
abstract protected function DoInsert();
abstract protected function DoSelect();
abstract protected function DoDelete();
abstract protected function DoUpdate();

public function Salvar() 
{
	$this->DoInsert();
}

public function Selecionar() 
{
	$this->DoSelect();
}

public function Deletar() 
{
	$this->DoDelete();
}

public function Editar() 
{
	$this->DoUpdate();
}	
}

 

só lembrando:

Abstração de Objetos

PHP 5 introduz métodos e classes abstratos. Não é permitido criar uma instância de uma class que foi definida como abstrata. Qualquer classe que contêm pelo menos um método abstrato deve também ser abstrata. Métodos definidos como abstratos simplesmente declaram a assinatura do método, eles não podem definir a implementação.

 

Quando uma classe herda uma classe abstrata, todos os métodos marcados como abstratos na declaração da classe-pai devem ser definidos na classe filha; além disso, esses métodos devem ser definidos com a mesma visibilidade ou mais fraca. Por exemplo, se um método abstrado é definido como protected, a implementação da função deve ser definida ou como protected ou public.

pronto temos um modelo de uma classe pronta com os metodos obrigatorios para serem implementados

como no exemplo usaremos para manuseio do banco de dados tarefas comuns como Editar, Excluir, Selecionar e Inserir.

 

usei o nome Do (DoSelect) só por convenção que em ingles a grosso modo quer dizer "faça alguma coisa"

 

agora todas as classes que herdar nossa classe "ClasseAbstrata" obrigatoriamente tera que ter os metodos:

 

DoInsert();

DoSelect();

DoDelete();

DoUpdate();

 

se nao tiver algum desses metodos ira dar um erro +- assim:

Fatal error: Class ClassMysql contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (ClasseAbstrata::DoInsert)

 

agora criaremos umas classes para extender da nossa classe abstrata ClasseAbstrata

 

vou criar 3 classes cada uma referente a um banco de dados por exemplo Mysql(Mysql 4), Mysqli(Mysql5) e Postgresql

 

class ClassMysql extends ClasseAbstrata
{
protected function DoInsert() 
{
	echo "Salvando ClassMysql...<br />";
}

protected function DoSelect() 
{
	echo "Selecionando da ClassMysql...<br />";
}

protected function DoDelete() 
{
	echo "Deletando da ClassMysql...<br />";
}

protected function DoUpdate() 
{
	echo "Editando da ClassMysql...<br />";
}	
}

class ClassMysqli extends ClasseAbstrata
{
protected function DoInsert() 
{
	echo "Salvando ClassMysqli...<br />";
}

protected function DoSelect() 
{
	echo "Selecionando da ClassMysqli...<br />";
}

protected function DoDelete() 
{
	echo "Deletando da ClassMysqli...<br />";
}

protected function DoUpdate() 
{
	echo "Editando da ClassMysqli...<br />";
}	
}

class ClassPostgre extends ClasseAbstrata
{
protected function DoInsert() 
{
	echo "Salvando ClassPostgre...<br />";
}

protected function DoSelect() 
{
	echo "Selecionando da ClassPostgre...<br />";
}

protected function DoDelete() 
{
	echo "Deletando da ClassPostgre...<br />";
}

protected function DoUpdate() 
{
	echo "Editando da ClassPostgre...<br />";
}	
}

 

modo de usar:

 

$classe1 = new ClassMysqli();
$classe1->Salvar();

$classe2 = new ClassMysql();
$classe2->Salvar();

$classe3 = new ClassPostgre();
$classe3->Salvar();

 

Como você pode ver, temos um mesmo modelo de classe com o mesmo método "Salvar" em todas as classes só que internamente ele ira fazer coisas diferentes com funções diferentes ou seja do jeito que você quiser, por exemplo para salvar usando Mysqli você ira fazer de um jeito usando as funções do mysqli mysqli_connect, etc... e se você usar o método Salvar da classe Postgresql internamente você ira usar os métodos próprios da função postgresql pg_connect, etc...

viram como ficou mais limpo o codigo e de facil entendimento e manutenção?

e fora que você deixa seu sistema no padrao nao importa que sistema você faça ou qual banco você tera um método padrao para chamar quando quiser salvar ou editar etc...

 

Agora para nos ajudar ainda mais vamos usar o método Patterns e usaremos o Factory lembrando:

 

Factory

O padrão Factory permite a instanciação de objetos em tempo de execução. É chamado de Factory uma vez que é responsável por "produzir" um objeto.

 

dai nosso exemplo poderia ficar assim:

 

Factory:

class Data
{
function factory($classname)
{
	return new $classname;
}
}

 

$classe1 = Data::factory('ClassMysql');
$classe1->Salvar();

$classe2 = Data::factory('ClassMysqli');
$classe2->Salvar();

$classe3 = Data::factory('ClassPostgre');
$classe3->Salvar();

 

pronto só passar o nome da classe que queremos usar e pronto ficou mais facil ainda nao é mesmo?

 

se quiser e ate aconselho criar as classes separadas em arquivos e na hora de usar basta usar assim:

 

function __autoload($class_name) {
  require_once $class_name . '.php';
}

 

ou seja quando uma classe for estanciada o php ira buscar o arquivo na hora para incluir

http://br.php.net/manual/pt_BR/language.oop5.autoload.php

 

recomendo usar tabm um arquivo de configuração para terem mais sucesso e a prova de erros

veja no link mais detalhes

 

http://forum.imasters.com.br/index.php?showtopic=202215

 

agora é com voces para criarem um sistema de verdade usando o metodo que eu passei

 

em anexo o exemplos que eu postei aqui.

 

classeabstrata.zip

 

obs: Para usuario de linux tomem cuidado com o caminho dos arquivos e os nomes dos arquivos tem diferença de maiuscula e minuscula por exemplo DB.php db.php no linux são 2 arquivos diferente eles nao se sobrescreevem por isso para evitar erros deixe os nomes dos scripts tudo minusculo e na função autoload

 

function __autoload($class_name) {
  require_once strtolower($class_name) . '.php';
}

Compartilhar este post


Link para o post
Compartilhar em outros sites

Parabéns, Fabyo ! Mais um dos seus excelentes tutoriais.São iniciativas assim que contribuem para a evolução do desenvolvimento em PHP.Obrigado por partilhar ...

Compartilhar este post


Link para o post
Compartilhar em outros sites

Parabéns, Fabyo ! Mais um dos seus excelentes tutoriais.São iniciativas assim que contribuem para a evolução do desenvolvimento em PHP.Obrigado por partilhar ...

assino embaixo ...muito bom o tutorial, de fácil entendimento ! ps.: O bom de utilizar bons frameworks, os completos é que na maioria das vezes esse pattern ja esta incluso, caso do Zend :D Mas é isso ae ferinha, bem legal o artigomais patterns em http://www.phppatterns.com/docs/?idx=designhttp://www.dofactory.com/Patterns/Patterns.aspx

Compartilhar este post


Link para o post
Compartilhar em outros sites

Fabyo, só uma coisa que ficou meio confusa pra mim, eu fiz um clase para exclusao assim:

 

class excluir{	  	  var $sql;	  var $re;	  var $id;	  	  function excluirDados(){	  	  $id = $_GET["id"];	  	  $sql = "DELETE FROM tbnoticias WHERE id=".$id."";	  	  $re = $this->Exe($sql);}

pelo que eu entendi, eu só preciso fazer assim com a classe abstrata:

 

abstract protected function DoDelete();  public function Deletar()	{		$this->DoDelete();	}

e pronto, minha classe pra deletar ja esta feita???

Compartilhar este post


Link para o post
Compartilhar em outros sites

nao, você vai ter que criar ela, a ideia de abstração é que você pode estanciar a classe que precisa e basta passar o nome dela, por isso dei os exemplos usando Mysql, postgresql, porque você poderia ter feito uma classe voltada para mysql e outra para postgresql, mas a ideia é que seu metodo é o mesmo nao importa o banco você sempre vai chamar Deletar()

Compartilhar este post


Link para o post
Compartilhar em outros sites

<?php			abstract class AbstractDB{				abstract protected function doconecta();		abstract protected function dodesconecta();		abstract protected function doquery($sql);			}		?>
essa minha classe está correta ou eu tenho que colocar os seguintes métodos também?

public function conecta()		{			$this->doconecta();		}				public function desconecta()		{			$this->dodesconecta();		}				public function query($sql)		{			$this->doquery();		}

Compartilhar este post


Link para o post
Compartilhar em outros sites

Carlos fiz um exemplo funcional só pra você entender, mas ja vou avisando fiz agora na correria, nao estou validando nada e é bem simples só pra entender mesmo, claro que para um sistema precisa ser revisto algumas coisas, mas ja da pra você entender:

 

banco:

CREATE TABLE tabela (
 id smallint(5) unsigned NOT NULL auto_increment,
 campo varchar(40) NOT NULL,
 PRIMARY KEY  (id)
)

 

classeabstrata.php

 

<?php

abstract class ClasseAbstrata
{	
abstract protected function DoInsert($sql);
abstract protected function DoSelect();
abstract protected function DoDelete();
abstract protected function DoUpdate();

public function Salvar($sql) 
{
	$this->DoInsert($sql);
}

public function Selecionar() 
{
	$this->DoSelect();
}

public function Deletar() 
{
	$this->DoDelete();
}

public function Editar() 
{
	$this->DoUpdate();
}	
}
?>

 

classmysql.php

 

<?php
class ClassMysql extends ClasseAbstrata
{
protected $args;
function __construct()
{
	mysql_connect("localhost", "usuario", "senha");
	mysql_select_db("banco");
}

protected function DoInsert($sql) 
{
	mysql_query($sql);		

	if(mysql_affected_rows() > 0) {
		echo "Salvo com sucesso...<br />";
	}		
}

protected function DoSelect() 
{
	$re = mysql_query("select * from tabela");
	while($l = mysql_fetch_array($re)) {
		$campo = $l["campo"];
		echo $campo."<br />";
	}
}

protected function DoDelete() 
{
	echo "Deletando da ClassMysql...<br />";
}

protected function DoUpdate() 
{
	echo "Editando da ClassMysql...<br />";
}	
}
?>

 

index.php

 

<?php

function __autoload($class_name) {
  require_once strtolower($class_name) . '.php';
}

$valor = "abc".rand();

$classe1 = Data::factory('ClassMysql');
$classe1->Salvar("INSERT INTO tabela VALUES (NULL , '$valor')");
$classe1->Selecionar();

?>

 

o resto dos scripts pode manter os mesmos, só criar esse banco de dados, e configurar os dados da conexao e testar

Compartilhar este post


Link para o post
Compartilhar em outros sites

Só mais uma coisa!Em quais outras circunstâncias eu posso empregar o uso de abstração de objetos, além de classes para conexão com o bd?

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.