Pagina 4 di 5 primaprima ... 2 3 4 5 ultimoultimo
Visualizzazione dei risultati da 31 a 40 su 48

Discussione: Singleton esteso

  1. #31
    Originariamente inviato da Mackey
    appunto... è quello che vorrei fare anch'io... ma non si può riassegnare il $this, altrimenti per assurdo avrei fatto al posto dell'Exception:

    $this = &self::$instanceArray[$className];


    Quello che trovo un po' sconcertante è il fatto del concetto di Singleton in se... ovvero:
    a che serve impostare l'istanza per richiamare metodi che sono nativamente statici?
    anche se l'istanza fosse comunque una (caricata o con il costruttore o con il load) poi comunque richiama metodi statici... tanto vale utilizzare la classe come wrapper... o sbaglio?

    Comunque soluzioni al mio approccio?
    perche' non potresti usare metodi dell'istanza?
    codice:
    class A {
        static private $_a;
        static public function get(){
            return isset(self::$_a) ? self::$_a : self::$_a = new self;
        }
    
        public function write($something){
            echo $something;
            return $this;
        }
    }
    
    function A(){return A::get();}
    
    A()->write('Hello')->write('World');
    Formaldehyde a new Ajax PHP Zero Config Error Debugger

    WebReflection @WebReflection

  2. #32
    Utente di HTML.it L'avatar di Razorblade
    Registrato dal
    Feb 2002
    Messaggi
    1,308
    Ciao Andr3a,
    premetto che ero a conoscenza della possibilità di ritornare l'oggetto stesso per ogni metodo in modo da effettuare concatenazioni in stile jQuery, però in questo caso quello che il costruttore dovrebbe restituire dovrebbe essere l'istanza salvata all'interno dell'array statico ( ovviamente se disponibile )

    Codice PHP:
    class Singleton {
        private static 
    $instanceArray = array();

        public function 
    __construct() {
            
    $className get_class($this);
            if(!isset(
    self::$instanceArray[$className]))
                
    self::$instanceArray[$className] = &$this;
            else
              return 
    self::$instanceArray[$className];
        }

        public static function 
    test() { /* questo metodo è da cancellare */
            
    print "<pre>".print_r(self::$instanceArraytrue)."</pre>";
        }
    }

    class 
    extends Singleton {
        public 
    $prova;
        public function 
    setProva($newValue) {
            
    $this->prova $newValue;
        }
    }

    $a = new A();
    $a->setProva("Stringa Uno");


    $a2 = new A(); 
    $a2->setProva("Stringa Due");

    Singleton::test(); 
    risultato

    Codice PHP:
    Array
    (
        [
    A] => A Object
            
    (
                [
    prova] => Stringa Uno
            
    )


    Perche non 'Stringa Due'?

  3. #33
    Aiuto... forse ho risolto il problema!

    Siccome il $this non si può ri-assegnare... allora ho riassegnato le proprietà e i metodi, passando il puntatore delle relative proprietà e metodi dell'istanza Singleton... ma è possibile che sia corretto o secondo voi può creare problemi?

    Codice PHP:
    <?php

    class Singleton {
        private static 
    $instanceArray = array();

        public function 
    __construct() {
            
    $className get_class($this);
            if(!isset(
    self::$instanceArray[$className]))
                
    self::$instanceArray[$className] = &$this;
            else {
                
    //throw new Exception("{$className} is Singleton");
                
    $arrayVars get_class_vars($className);
                
    $arrayMethods get_class_methods($className);
                foreach(
    $arrayVars AS $i => $v) {
                    
    $this->$i = &self::$instanceArray[$className]->$i;
                }
                foreach(
    $arrayMethods AS $i => $v) {
                    
    $this->$v = &self::$instanceArray[$className]->$v;
                }
            }
        }

        public static function 
    test() { /* questo metodo è da cancellare */
            
    print "<pre>".print_r(self::$instanceArraytrue)."</pre>";
        }
    }

    class 
    extends Singleton {
        public 
    $prova;
        public function 
    setProva($newValue) {
            
    $this->prova $newValue;
        }
    }

    class 
    extends Singleton {

    }

    $a = new A();
    $a->setProva("Stringa da sovrascrivere");

    $a2 = new A();
    $a2->setProva("Stringa DUEEEEEEEEEEEEEEEEEEEEE");

    $a->test();
    //$a2->test();

    $b = new B();
    $b->test();

    ?>
    «Se leggi dimentichi, se vedi capisci, se fai impari» Piaget

  4. #34
    Mackey, secondo me prima di usare un pattern, devi capirlo, nel senso che se pretendi di assegnare valori diversi al costruttore, non ti serve il Singleton, che per natura non dovrebbe permetterti di usare "new Classe", e la logica, che mi sfugge, richiede un altro pattern.

    Insomma, singleton e' un pattern tra decine che ce ne sono, studiateli un po' prima di riconvertire qualunque altro pattern a singleton, e senza motivo ( tipo: voglio un singleton che non fa il singleto ... allora non vuoi il singleton )

    P.S. l'ho gia' scritto, senza static binds, il Singleton in PHP non si puo' estendere. Al primo new Qualcosa, stai fuori pattern
    Formaldehyde a new Ajax PHP Zero Config Error Debugger

    WebReflection @WebReflection

  5. #35
    hai ragione...
    in effetti il pattern è completamente un altro... nel senso che Singleton richiede un costruttore privato e un metodo che restituisca l'istanza per l'utilizzo "non-statico" dell'oggetto...
    ma allora anche la soluzione che hai adottato tu non rispecchia totalmente queste specifiche (se così si possono chiamare)... ma esiste un pattern oltre il Singleton che sia concettualmente vicino alla logica da me proposta?
    «Se leggi dimentichi, se vedi capisci, se fai impari» Piaget

  6. #36
    L'implementazione di un pattern e' un'opinione, nel senso che il pattern consiglia una soluzione ad un problema comune.

    Il Singleton e' una soluzione al seguente problema:
    voglio recuperare facilmente un'unica istanza condivisa in tutto il progetto (da qui la diatriba sul fatto che Singleton === GLOBAL, sul quale sono d'accordo)

    Nel caso di PHP, e' comodo avere un'istanza in Singleton per il semplice fatto che puoi usarne i metodi direttamente
    codice:
    Singleton('MiaClasse')->doStuff();
    questo esempio e' estremamente comodo, ed ecco il perche' del mio pattern: scrivi meno, hai lo stesso risultato.

    Se usi new MiaClasse pero' non stai rispettando regole rudimentali della creazione di istanze, dove se c'e' un new davanti, chiunque si aspetta una nuova istanza e non la stessa di prima (per questo ti dicevo che hai snaturato il singleton, quindi non ti serve il singleton)

    A te serve un singleton vero, o tipo quello consigliato da me, piu' un Factory, ovvero un metodo che, quando serve, ti restituisce nuove istanza di questa o quell'altra classe.

    Poi ci sono altri patterns che ora non ho in mente, magari se ti documenti un po' ne trovi uno che fa esattamente quello che vorresti fare ( perche' io non l'ho capito )
    Formaldehyde a new Ajax PHP Zero Config Error Debugger

    WebReflection @WebReflection

  7. #37
    @

    Codice PHP:
    function Factory($__CLASS__){
        static  
    $list = array();
        if(!isset(
    $list[$__CLASS__]))
            
    $list[$__CLASS__] = new ReflectionClass($__CLASS__);
        
    $arguments func_get_args();
        
    array_shift($arguments);    
        return  
    $list[$__CLASS__]->getConstructor() ? $list[$__CLASS__]->newInstanceArgs($arguments) : $list[$__CLASS__]->newInstance();
    }
    function 
    Singleton($__CLASS__){
        static  
    $list = array();
        if(!isset(
    $list[$__CLASS__])){
            
    $arguments func_get_args();
            
    $list[$__CLASS__] = call_user_func_array('Factory'$arguments);
        }
        return  
    $list[$__CLASS__];

    Scusa ma Factory non restituisce gìà un singleton ?


    Without faith, nothing is possible. With it, nothing is impossible
    http://ilwebdifabio.it

  8. #38
    Originariamente inviato da whisher
    Scusa ma Factory non restituisce gìà un singleton ?
    Factory è un pattern il cui obiettivo è semplificare la creazione di istanze.
    Siccome Factory è usato per generare istanze, e siccome il Singleton è usato per prendere sempre la stessa istanza, ma comunque almeno una ne devi generare, puoi avere la singola istanza creata tramite Factory nel Singleton, ed usare il Factory per generare tutte le altre istanze generiche che vuoi.

    Riassumendo:
    - Factory, crea istanze
    - Singleton, crea istanza una sola volta e permette di usare una sola istanza in tutto il progetto

    Rispettando questi due patterns, con le due funzioni da te quotate hai tutto quello che ti serve
    Formaldehyde a new Ajax PHP Zero Config Error Debugger

    WebReflection @WebReflection

  9. #39
    Grazie della esauriente risposta
    quello a cui avevo pensato
    sbagliando


    per farti capire


    Codice PHP:
    class w_exceptions_FileException extends Exception{}
    function 
    Factory($__CLASS__){
        
    // (C) Andrea Giammarchi - Mit Style License
        
    static  $list = array();
        if(!
    class_exists($__CLASS__)){
            throw new 
    w_exceptions_FileException('The class .'.$__CLASS__.' doesn\'t exist.');
        }
        if(!isset(
    $list[$__CLASS__])){echo "Istanza";
            
    $list[$__CLASS__] = new ReflectionClass($__CLASS__);
        }
        
    $arguments func_get_args();
        
    array_shift($arguments);    
        return  !
    is_null($list[$__CLASS__]->getConstructor()) ? $list[$__CLASS__]->newInstanceArgs($arguments) : $list[$__CLASS__]->newInstance();
    }
    function 
    Singleton($__CLASS__){ 
        static  
    $list = array(); 
        if(!isset(
    $list[$__CLASS__])){ 
            
    $arguments func_get_args(); 
            
    $list[$__CLASS__] = call_user_func_array('Factory'$arguments); 
        } 
        return  
    $list[$__CLASS__]; 
    }
    class 
    A{}
    $aSingleton('A');
    $bSingleton('A');
    $cSingleton('A');
    var_dump($a===$c);//true

    /*
    echo istanza una volta 
    $a= Factory('A');
    $b= Factory('A');
    $c= Factory('A');
    ma questo è false
    var_dump($a===$c);//false
    */ 
    per me era già singleton Factory
    e infatti echo istanza c'è una volta sola
    ma le istanze non sono uguali
    mi sa che mi perdo qc




    EDIT

    LASCIA stare ho capito
    Without faith, nothing is possible. With it, nothing is impossible
    http://ilwebdifabio.it

  10. #40
    non ti perdi niente
    Factory crea istanze
    Singleton restituisce sempre e solo l'unica istanza

    Tu vuoi una sola istanza per tutto il progetto a prescidere da dove questa sia stata creata? (esempio, variabile in scope innestato)

    Singleton('A')->doStuff();

    Se invece vuoi una nuova istanza di qualunque classe, A compresa, usi Factory

    Factory('A') !== Singleton('A') // sempre vero
    Singleton('A') === Singleton('A') // sempre vero
    Factory('A') !== Factory('A') // sempre vero

    Vuoi condividere un'istanza? Usi la funzione Singleton
    Vuoi creare una nuova istanza? Usi la funzione Factory

    più semplice e semantico di così mi resta difficile ... ma sono due funzioni wrapper che rispettano lo scopo finale del pattern, a prescindere dalla classe.
    Se la classe invece è un singleton, non puoi creare un'istanza e ricevi un runtime error, ma se lo è, sei fagiano tu ad usare una funzione Singleton per una classe che è Singleton nativa ... meglio ora?

    P.S. se usi __autoload o spl_auto_load, leva quel throw new Exception dalla Factory o ti perdi la funzionalità
    Formaldehyde a new Ajax PHP Zero Config Error Debugger

    WebReflection @WebReflection

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2021 vBulletin Solutions, Inc. All rights reserved.