Visualizzazione dei risultati da 1 a 6 su 6
  1. #1
    Utente di HTML.it L'avatar di citrus
    Registrato dal
    Feb 2002
    Messaggi
    774

    Singleton pattern - però interno ad una classe

    salve a tutti...
    ho una classe in cui è contenuta, tra le proprietà, una istanza dell'oggetto DOMDocument caricata con l'opportuno xml.
    la maggior parte dei metodi implementati dalla classe lavora continuamente su questa istanza perciò mi farebbe molto comodo poterla creare una volta sola e restituirne una copia ogni qual volta essa viene richiesta, anzichè crerne una nuova ogni volta.
    (premetto che un oggetto dentro ad un altro oggetto non persiste alla sessione, ed è per questo motivo che non istanzio la proprietà una volta per tutte nel costruttore ma sono costretto a ricrearla ad ogni chiamata di funzione).

    per poter ottenere questa cosa ho pensato di ricreare una specie di variante del design pattern chiamato "Singleton".
    questo pattern permette di controllare che non venga creata più di una istanza di una classe, e nel caso esista gia, ritorna un riferimento a questa invece di crearne una nuova.

    La differenza è che il classico Singleton è riferito a tutta l'applicazione,
    mentre a me serve che l'istanza dell'oggetto DOMDocument sia unica solo all'interno della classe che la contiene.

    ecco il codice così come lo avevo pensato:
    codice:
                 protected $objXML=null;
                 .....
    	protected function loadObjXML(){
    		if($this->objXML == null){	
    			$this->objXML=new DOMDocument();
    			$this->objXML->loadXML($this->xml);
    		}
    		return $this->objXML;
    	}
    purtroppo però la cosa non funziona...
    alla prima chiamata tutto ok, ma dalla seconda in poi viene restituito un oggetto di tipo DOMDocument completamente vuoto, perchè non sopravvissuto alla sessione!!!
    quindi il controllo if($this->objXML == null) non funziona perchè cmq un istanza dell'oggetto DOMDocument c'è... solo che è vuota!
    come posso fare ad accorgermi di questo e ricreare l'istanza?
    anch l'operatore "istanceof" è inutile in questo caso...

    grazie mille a tutti
    citrus

  2. #2
    Utente di HTML.it L'avatar di citrus
    Registrato dal
    Feb 2002
    Messaggi
    774
    up

  3. #3
    Utente di HTML.it L'avatar di citrus
    Registrato dal
    Feb 2002
    Messaggi
    774
    provo a rispiegare meglio la domanda nella speranza che qualcuno capisca e mi aiuti

    allora...
    ho scritto una classe A, tra le cui proprietà è contenuta l'istanza di un altra classe B.
    i metodi della classe A lavorano tutti con l'istanza della classe B.

    io vorrei fare in modo che l'istanza della classe B venisse creata una volta soltanto, che venisse immagazzinata in una delle proprietà di A e che ne fosse restituita una copia ad ogni metodo che la richiede... invece che crearne una nuova ogni volta!

    per fare questo ho creato un metodo apposito "loadB()" che controlla se tra le proprietà di A è gia presente una istanza della classe B; se è presente ne ritorna direttamente una copia, altrimenti prima di ritornarla la crea.
    In pratica è un Singleton.. perchè l'istanza di B deve essere sempre e solo una... solo
    che il suo scope è privato ed è quindi valido solo all'interno della classe A.
    .. mentre nel singleton classico lo scope è static e l'istanza è unica per tutta l'applicazione!

    il problema nasce dal fatto che l'istanza della classe A viene salvata nella sessione,
    e siccome alla sessione sopravvivono solo gli oggetti di primo livello l'istanza di B, contenuta al suo interno, non sopravvive.
    o meglio... rimane istanza di B ma risulta vuota.. tutte le sue proprietà vengono azzerate...
    facendo un print_r ne esce una cosa tipo: "class B()"... completamente vuota!

    quindi quando controllo se B==null il codice rileva la sua presenza e non la ricrea prima di restituirla... restituendo così un oggetto B vuoto! ... e quindi inutilizzabile... e qui errori a manetta!!!

    scrivo un po' di codice per spiegarmi meglio:
    codice:
    class A{
      private $var1;
      private $var2;
      ...
      private $B=null;
    
      function loadB(){
        if($this->B==null)
          $this->B = new B($param1,$param2, ... );
        return $this->B;
      }
    
      function prova1(){
        $objB=$this->loadB();
        $objB->funzione1();
      }
    
      function prova2(){
        $objB=$this->loadB();
        $objB->funzione2();
      }
    
    }
    ovviamente il codice è solo a titolo esplicativo.. non ho riportato il mio codice esatto perhè sarebbe un casino... cmq la struttura è quella...

    e quindi il domandone è:

    visto che il controllo if($this->B==null) si accorge solo se l'istanza di B esiste ma non se è ancora intatta ..
    come posso fare questo controllo???

    spero di essere stato più chiaro...
    ho davvero bisogno d'aiuto non so più dove sbattere la testa

    grazie
    citrus

  4. #4

    ..........

    Ciao.
    La butto lì e se usassi semplicemente extends ?
    Oppure con aggregation (passi l'oggetto al costruttore
    con cui inizializzi una proprietà)
    Mi sembra danno una lettura veloce al post
    che non hai bisogno di un singleTon.

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

  5. #5
    Utente di HTML.it L'avatar di citrus
    Registrato dal
    Feb 2002
    Messaggi
    774

    Re: ..........

    Originariamente inviato da whisher
    Ciao.
    La butto lì e se usassi semplicemente extends ?
    Oppure con aggregation (passi l'oggetto al costruttore
    con cui inizializzi una proprietà)
    Mi sembra danno una lettura veloce al post
    che non hai bisogno di un singleTon.

    ciao, grazie per la risposta
    estendere la classe non è la soluzione che cerco, anche perchè l'oggetto B dell'esempio è in realtà di tipo DOMDocument (per la manipolazione di xml) mentre la classe A si occupa di gestire una applicazione basata appunto su xml...
    insomma.. estendere la classe B creando la A su di essa non mi serve.. è un casino... io devo solo poter usare questo oggetto per la manipolazione dell'xml nella mia classe e vorrei poterlo istanziare solo una volta... anche perchè è piuttosto pesante in termini di prestazioni ricrearlo ogni volta....


    questa cosa dell'aggregation invece non la conosco.. di cosa si tratta esattamente?
    come funziona?

    grazie
    citrus

  6. #6

    ...

    Codice PHP:
    <?php
    class A
    {
        public function 
    __construct()
        {
        }
        public function 
    displayA()
        {
            echo 
    "Hi B ;)";
        }
    }
    class 
    B
    {
        private 
    $_a;
        public function 
    __construct(A $objA)
        {
    //aggregation 
            
    $this->_a $objA;
        }
        public function 
    displayB()
        {     
            
    $this->_a->displayA();
        }
    }
    $a = new A();
    $b = new B($a);
    $b->displayB();
    ?>
    Se vuoi approfondire



    qui

    a c'è pure la composition .........


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

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 © 2025 vBulletin Solutions, Inc. All rights reserved.