Fabyo 66 Denunciar post Postado Novembro 21, 2006 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 ObjetosPHP 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 implementadoscomo 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: FactoryO 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
Epyllion 0 Denunciar post Postado Novembro 21, 2006 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
Void : 0 Denunciar post Postado Novembro 21, 2006 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 66 Denunciar post Postado Novembro 21, 2006 Valeu Void : Compartilhar este post Link para o post Compartilhar em outros sites
Perfect Lion 10 Denunciar post Postado Novembro 23, 2006 Fabão show de bola viu... como sempre nota 10 =) Compartilhar este post Link para o post Compartilhar em outros sites
lefestaf 0 Denunciar post Postado Fevereiro 20, 2007 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
Fabyo 66 Denunciar post Postado Fevereiro 20, 2007 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
Carlos Vital 0 Denunciar post Postado Fevereiro 21, 2007 <?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
Fabyo 66 Denunciar post Postado Fevereiro 21, 2007 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
Carlos Vital 0 Denunciar post Postado Fevereiro 21, 2007 Valeu Fabyo... agora consegui entender. http://forum.imasters.com.br/public/style_emoticons/default/thumbsup.gif Compartilhar este post Link para o post Compartilhar em outros sites
Carlos Vital 0 Denunciar post Postado Março 6, 2007 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
Fabyo 66 Denunciar post Postado Março 6, 2007 leia, acho que você vai entender melhor http://www.php.net/manual/pt_BR/language.oop5.abstract.php Compartilhar este post Link para o post Compartilhar em outros sites
LeoLoko 0 Denunciar post Postado Abril 11, 2007 Cara que utilidade teria o FACTORY ?não poderia apenas usar o new class() ?? Compartilhar este post Link para o post Compartilhar em outros sites
Fabyo 66 Denunciar post Postado Abril 11, 2007 http://www.php.net/manual/pt_BR/language.oop5.patterns.php http://www.dsc.ufcg.edu.br/~jacques/cursos...ractfactory.htm http://www.htmlstaff.org/ver.php?id=4741 Compartilhar este post Link para o post Compartilhar em outros sites