Loid 0 Denunciar post Postado Janeiro 4, 2009 Olá pessoal, agradeço o acompanhamento nesta jornada. Bom, lendo sobre os desgin Patterns consegui implementar, não a classe de conexão a banco de dados, mas sim uma forma "Orientada', se tudo estiver correto, de se chamar a classe e permanecer apenas com uma instancia do objeto, mesmo que ela seja requerida em multiplas chamadas. Pensei em fazer classes abastratas ou ate interfaces para definir os metodos que as classes de drives, "mysql e postgres', deveriam ter mas não foi possivel exnteder a classe mysql a mysqli assim optei por não implenta-las com interface o classes abstratas, esta correto? // responsavel por fazer os includes informando o nome do drive class ImplementaDb { // Método Factory parametrizado public static function GetDrive($type) { if (include_once $type.'/'.$type.'.class.php') { return $c = eval($type."::SetConexao();"); } else { throw new Exception ('Driver não encontrado'); } } } //Instanciamos o Objeto caso seja requistada outra chamada será retornado a instancia atual $c = ImplementaDb::GetDrive('mysql'); $c = ImplementaDb::GetDrive('postgres'); //classe mysql e que possui SetConexao que verifica se o objeto ja foi iniciado //Singleston class mysql extends mysqli { private static $instancia; private function __construct(){ echo 'mysql'; } public static function SetConexao(){ if(!isset(self::$instancia)){ self::$instancia = new mysql; } return self::$instancia; } } //identico a classe acima verificando se o objeto ja foi requisitado class postgres { private static $instancia; private function __construct(){ echo 'postgres'; } public static function SetConexao(){ if(!isset(self::$instancia)){ self::$instancia = new postgres; } return self::$instancia; } } Bom pessoal, consegui aprender isso durante este tempo, acho que para aprender dedicação é fundamental. Não vou falar que sou o cara programando de forma procedural, consigo resolver meus problemas aqui. Mas se tratando de oop a história é outra. Grato, pela atenção. Jefferson. Compartilhar este post Link para o post Compartilhar em outros sites
eibon 2 Denunciar post Postado Janeiro 5, 2009 Ta belezinha.Mas seta o __clone como private,senão não adianta nada. Abraço! Compartilhar este post Link para o post Compartilhar em outros sites
Fabyo 66 Denunciar post Postado Janeiro 5, 2009 Acho legal você usar autoload em vez de include dentro da classe da uma olhada no exemplo que postei sobre factory, pode ser util mas lembre-se eu postei isso em 2006. Abstração de Objetos & Factory http://forum.imasters.com.br/index.php...&hl=factory Compartilhar este post Link para o post Compartilhar em outros sites
Loid 0 Denunciar post Postado Janeiro 5, 2009 Bom é interessante saber, então, consegui alcançar o objetivo neste script? Há, claro acho que tenho que esclarecer também que tive que ler bons tutoriais... se não fica parecendo que apenas coloei e copiei, mas a idéia não foi essa, esse pelo menos eu entendi.. Value, abraço.. Compartilhar este post Link para o post Compartilhar em outros sites
Fabyo 66 Denunciar post Postado Janeiro 5, 2009 digamos que chegou perto, ainda da pra melhorar um pouco, mas tabom uma coisa que você poderia melhorar é ter uma classe singleton para estanciar as outras assim você nao precisa ter todas as classes com singleton. Compartilhar este post Link para o post Compartilhar em outros sites
Loid 0 Denunciar post Postado Janeiro 5, 2009 Esta class que instanciaria as outras seria a controller? Compartilhar este post Link para o post Compartilhar em outros sites
Loid 0 Denunciar post Postado Janeiro 5, 2009 Editado.. Para realizar esta sua sugestão e torna-la eficas, as classes devem ter todas seu __construct private certo? Compartilhar este post Link para o post Compartilhar em outros sites
Fabyo 66 Denunciar post Postado Janeiro 5, 2009 veja meu exemplo que postei acima Compartilhar este post Link para o post Compartilhar em outros sites
Loid 0 Denunciar post Postado Janeiro 5, 2009 Bom, consegui realizar esta alteração, só que o construtor da class mysql esta public, e creio que se ele estiver public não faz sentido o singleton na class anterior. Porque no caso da class mysql ter um construtor private ficaria assim a chamada self::instancia =eval( $type.'::SetConexao;'); Mas ele não esta verificando de acordo com a parte anterior do singleton. if(!isset(self::$instancia)){ self::$instancia = new mysql; } return self::$instancia; Compartilhar este post Link para o post Compartilhar em outros sites
Loid 0 Denunciar post Postado Janeiro 5, 2009 Certo, interessante o uso de da classe abstrata. Mas, o problema é usar o singleton que faça referencia a outros arquivos. Ex: Class 'singleton é responsavel por verificar se elas ja foram instanciadas se ja forem instanciadas retornara o valor do objeto. A Class 'mysql será responsavel por iniciar a conexao com o drive mysql e deverá ter seu metodo __construc private. (Creio que se este metodo não estiver private o objetivo do Padrão Singleton não será alcançado.) O problema esta em fazer a class 'singleton verificar este valores. Caso ele não esteja instanciado o valor retornado seria. A função autoload é responsavel por incluir a class. if(!isset(self::$instancia){ self::$instancia = eval($type.'::SetConexao('.$type.');); } return self::$instancia; Normalmente esta ocorrendo o seguinte erro: Notice: C:\xampp\htdocs\anime\class\controller.class.php(17) : eval()'d code line 1 - Use of undefined constant mysql - assumed 'mysql' Compartilhar este post Link para o post Compartilhar em outros sites
Fabyo 66 Denunciar post Postado Janeiro 6, 2009 você nao esta entendendo o uso do singleton e factory uma vez que estancio uma classe e uso o mesmo objeto é pra isso que serve eu nao preciso ter todas as classes como __construct private pra que isso seja feito. Compartilhar este post Link para o post Compartilhar em outros sites
Loid 0 Denunciar post Postado Janeiro 6, 2009 Ta, mas supondo que a class C que faz esta instancia e verifica o objeto na class B. Mas se a classe B permite que seja acessada : $c = new ClassB; Não fugiria do escopo do padrão? Ou eu teria que falar para a classe B que as requisições só podem ser feitas da classe C informando o type do objeto. Compartilhar este post Link para o post Compartilhar em outros sites
Fabyo 66 Denunciar post Postado Janeiro 6, 2009 Entao é isso que você nao esta entendendo exemplo: class ABC { public static function AbrirConexao() { if(!(self::$instancia instanceof Mysqli)){ self::$instancia = new Mysqli(); } return self::$instancia; } } o que importa pra mi é a classe "Mysqli" e nao a classe ABC dai minha classe Mysqli sempre tera uma unica estancia do objeto "Mysqli" muita gente confunde isso, mas eu posso ter uma classe e dentro estanciar outra normal. e pra concluir nao tem o que fugir do escopo mesma coisa você ta criando uma classe singleton pra estanciar a Mysqli e eu posso muito bem chamar $my = new Mysqli() sem depender da sua classe singleton entendeu agora? Compartilhar este post Link para o post Compartilhar em outros sites
Loid 0 Denunciar post Postado Janeiro 6, 2009 Bom, este código ele instância apenas um objeto, no caso o primeiro que foi chamado, acho que se chamasse tanto o mysql e o postgres ele deveria chamar os dois não? <?php function __autoload($class) { require_once($class.'/'.$class.'.class.php'); } /** * Enter description here... * */ class ImplementaDb { private static $instancia; /** * Enter description here... * * @param unknown_type $type * @return unknown */ public static function GetDrive($type) { if (!isset(self::$instancia)) { self::$instancia = new $type; return self::$instancia; } return self::$instancia; } private function __clone() { trigger_error('Clone is not allowed.', E_USER_ERROR); } } $d = ImplementaDb::GetDrive('postgres'); $d = ImplementaDb::GetDrive('mysql'); Compartilhar este post Link para o post Compartilhar em outros sites
Fabyo 66 Denunciar post Postado Janeiro 6, 2009 E seu exemplo ta errado quando se trabalha com varias classes como no caso que você ta querendo é melhor usar um static array dai você testaria public static function GetDrive($type) { if (!isset(self::$instancia[$type])) { self::$instancia[$type] = new $type; } return self::$instancia[$type]; } Compartilhar este post Link para o post Compartilhar em outros sites
Loid 0 Denunciar post Postado Janeiro 6, 2009 Para finalizar este tópico... Bom, parece que não tem problema a class mysql estar com o construct public, ainda esta confuso para mim porque creio que o __construct deveria estar private, porque eu quero justamente que ela não seja instanciada mais de fez, se não no scritp o cara pode chama-la pela class singleton ou chama-la diretametne, e chamando diretamente ele poderá abrir várias conexões, certo? Não é isso que estamos querendo restringir? Bom vou postar aqui o código final, há valeu pela dica do array, relamente nem tinha passado pela minha cabeça! function __autoload($class) { require_once($class.'/'.$class.'.class.php'); } /** * Enter description here... * */ class ImplementaDb { private static $instancia; /** * Enter description here... * * @param unknown_type $type * @return unknown */ public static function GetDrive($type) { if (!(self::$instancia[$type] instanceof $type)) { self::$instancia[$type] = new $type; } return self::$instancia[$type]; } private function __clone() { trigger_error('Clone is not allowed.', E_USER_ERROR); } } class mysql //Oque esta me encomodando é este bendido __construct estar public! <?php class mysql extends mysqli { private static $instance; public function __construct(){ echo 'Estou usando o drive do mysql!'; } // Previne que o usuário clone a instância private function __clone() { trigger_error('Clone is not allowed.', E_USER_ERROR); } } class postgres { private static $instance; public function __construct(){ echo 'Estou usando o drive do postgres!'; } // Previne que o usuário clone a instância private function __clone() { trigger_error('Clone is not allowed.', E_USER_ERROR); } } Obrigado pela pasciência e colaboração de vocês! Compartilhar este post Link para o post Compartilhar em outros sites
Fabyo 66 Denunciar post Postado Janeiro 7, 2009 ainda esta confuso para mim porque creio que o __construct deveria estar private, porque eu quero justamente que ela não seja instanciada mais de fez, se não no scritp o cara pode chama-la pela class singleton ou chama-la diretametne, e chamando diretamente ele poderá abrir várias conexões, certo? entao como ja expliquei fazendo direito a classe mysqli sera estanciada apenas 1 vez, mas você ja ta imaginando outras coisas tipo "o cara pode chama-la" isso nao existe, porque você desenvolve um sistema e nao tem esse "cara" ai que estraga tudo, se esta trabalhando em equipe a equipe trabalha da mesma forma, mas foi o que falei, você restringe a classe mysqli com medo que ela estancie mais que uma vez, mas eu posso simplesmente pegar a classe mysqli e estanciar quantas vezes eu quiser, e ai?, entendeu? singleton nao é pra proteger um script de program-amadores o singleton é para proteger do proprio sistema, por exemplo você chama varios scripts e sem querer chamando o mesmo o singleton nao deixa a classe ser estanciada de novo, ou cair num loop infinito, etc..., mas o singleton ou o seu melhor script nao tem como se proteger de outros programadores. a ideia é entender o conceito e saber onde aplicar Compartilhar este post Link para o post Compartilhar em outros sites
Loid 0 Denunciar post Postado Janeiro 7, 2009 Há...agora sim entendi. "..Porque você desenvolve um sistema e nao tem esse "cara" ai que estraga tudo, se esta trabalhando em equipe a equipe trabalha da mesma forma.." È justamente, vejo que é mais dificil abstrair os objetos e identificar os padrões, onde cada um deve ser aplicado e garantir melhor entendimento e performace do script. Este tipo de explicação que falta nos artigos, como deve ser empregado e a real finalidade de um Desgin Patterns. "... singleton nao é pra proteger um script de program-amadores o singleton é para proteger do proprio sistema..." Muito bom, obrigado! Compartilhar este post Link para o post Compartilhar em outros sites