Newsgroup: it.comp.www.php
Titolo: Consiglio su OOP

E' da poco tempo che ho iniziato a programmare  ad oggetti, ora
mi servirebbe un consiglio su come evitare di inserire delle variabili 
globali all'interno
del costruttore di una classe.
Vi espongo brevemente cosa ho "combianto" per arrivare ad utilizzare delle
variabili globali:
Ho un file di configurazione ("config.inc.php") in cui ho memorizzato tutti 
i dati necessari
per il funzionamento dell'applicazione, come quelli per l'accesso al 
database e il percorso
nel quale desidero creare un file di log per eventuali errori.
La classe per utilizzare il database l'ho chiamata "Mysql", mentre quella 
per salvare gli errori
"LogFile".
Siccome la classe "LogFile" verrà sempre chiamata all'interno di un'altra 
classe,
per poter passare la variabile $pathfilelog contenuta in "config.inc.php", 
sono stato costretto
ad utilizzare il global.
Per farvi capire meglio cosa ho fatto, vi scrivo un frammento di codice 
delle due classi
----------------- CLASSE MYSQL ------------------------------------
include_once ("LogFile.php")
class Mysql {
    ...
    ...
    private logfile;
    __construct ($host, $user, $pass, $name){
        ...
        ...
        $this->logfile = new LogFile();
    }
    public openConnection(){
       // -> In caso di errore attraverso il die, chiamo una funzione della 
classe "LogFile" per
       // per scrivere su un file di testo l'errore scaturito.
        $this->con = mysql_connect ($this->host, $this->user, $this->pass) 
or die ($this->logfile->scriviLogFile($msg));
    }
}
----------------- CLASSE LOGFILE ------------------------------------
class LogFile {
    ...
    ...
   private $path;
    __construct (){
        ...
        ...
       //-> ecco ciò che vorrei evitare, sono costretto ad utilizzare global 
per leggere
      // il valore di $pathlogfile.
       global $pathfilelog;     ////<----- GLOBAL :-(
      $this->path = $pathfilelog;
    }
  public function scriviLogFile($msg){
     //scrivo sul file di log
     error_log ($msg, 3, $this->path);
 }
   ...
    ...
}
-------------------------------------------------------------------
Ora immagino che con un approccio OOP l'utilizzo di una variabile globale
all'interno di un costruttore non rispecchii principi dell'incapsulazione 
dei dati.
Quindi mi consigliate un sistema per evitare cio?
Grazie anticipatamente per le vostre risposte
Nicola

 Quindi mi consigliate un sistema per evitare cio?
Usa delle costanti, passa il valore nel costruttore, definisci una
classe di configurazione singleton ed usa quella per fornire i dati di
configurazione, etc. etc.
-- 
I am what I am, I do what I can
Sei un newbie? Leggi questo 
http://url.repository.biz/go/3C
Vuoi supportarmi? 
http://url.repository.biz/go/3E
Do. Or do not. There is not try.

 configurazione, etc. etc.
Grazie per la risposta...
sinceramente non ho capito molto bene cosa intendi... un piccolo 
esempio...please

 sinceramente non ho capito molto bene cosa intendi... 
Che cosa non hai capito molto bene?
-- 
I am what I am, I do what I can


 Che cosa non hai capito molto bene?
Non ho capito, o meglio non sò cosa sia una classe SingleTon e
come utilizzarla per fornire i dati di configurazione.

 come utilizzarla per fornire i dati di configurazione.
Google.com -> classe singleton -> Mi sento fortunato ...


 Google.com -> classe singleton -> Mi sento fortunato ...
gli ho dato uno sguardo molto ma molto e veloce...
e non ho capito come possa servirmi.
Domani quando avrò più tempo leggerò la pagina con più attenzione.
Grazie per le risposte

 Google.com -> classe singleton -> Mi sento fortunato ...
ho guardato la classe singleton e da quanto ho capito
mi basta creare una classe con tutte le varibili
statiche.
E' esatto? Cosě devo risolvere il mio problema? 

 E' esatto? Cosl devo risolvere il mio problema? 
Ti ho indicato 3 differenti soluzioni, sta a te decidere quale
utilizzare.


 utilizzare.
utilizzo le costanti....grazie

  
wrote:

Sono (tutti) metodi che violano l'incapsulamento (anche se sicuramente  
piu' pratici delle soluzioni al problema).
Cerca "Dependency Injector" e "Service Locator" su google.
Leggi il sito (è ricco di articoli di interesse generale) di PicoContainer.
Tac
-- 
La netiquette prevede sign di al massimo quattro righe.
Purtroppo la mia sign in quattro righe non ci stà.

 Perche' non usi delle costanti invece di variabili?
Perchè stà cercando di muoversi in direzione esattamente opposta.
http://www.c2.com/cgi/wiki?GlobalVariablesAreBad


 sicuramente  piu' pratici delle soluzioni al problema).
Un classe signleton viola l'incapsulazione?
-- 
I am what I am, I do what I can


 Un classe signleton viola l'incapsulazione?
Beccato, ho letto troppo di fretta.
Passare il valore nel costruttore (o tramite un setter) è la soluzione  
probabilmente piu' flessibile.
Gli altri metodi violano l'incapsulamento.
A parte il singleton, che crea dipendenza fra classi concrete.


 PicoContainer.
grazie.... 

 rappresentano delle costanti violo l'incapsulamento?
Non capisco. Fammi un esempio pratico.
$myClass->setPath( MY_PROJECTROOT ); //nessuna violazione.
Se invece fosse
class MyClass {
	function printPath ()
	{
		echo PROJECTROOT; //violazione del principio
	}
}
Detto questo non è detto che violare il principio non possa andar bene,  
dipende da dimensione e importanza del progetto.


 dipende da dimensione e importanza del progetto.
Io ho fatto così:
----------------------------------------------------
include_once ("class.LogFile.php");
include_once("config.inc.php");
class Mysql {
    ...
    ...
    private logfile;
    __construct ($host, $user, $pass, $name){
        ...
        ...
        $this->logfile = new LogFile(PATH_LOG_FILE);     //-> passo una 
costante al costruttore
    }
    public openConnection(){
       // -> In caso di errore attraverso il die, chiamo una funzione della 
classe "LogFile" per
       // per scrivere su un file di testo l'errore scaturito.
        $this->con = mysql_connect ($this->host, $this->user, $this->pass) 
or die ($this->logfile->scriviLogFile($msg));
    }
}
--------------------------------
Sbaglio a passare una costante nel costruttore? Io penso di no.....forse 
avrò capito male il tuo post precedente 

 avrò capito male il tuo post precedente
Lo sbaglio è qui:
     function __construct ($host, $user, $pass, $name){
         ...
         ...
         $this->logfile = new LogFile(PATH_LOG_FILE);     //-> passo una
costante al costruttore
     }
Non nella classe LogFile, ma nel metodo costruttore della classe che hai  
mostrato.
Le violazioni all'incapsulamento:
	- usare una costante (dovendo usare la classe in un'altro progetto  
dovresti settare la stessa identica costante anche nell'altro progetto)
	- istanziare la classe logile direttamente nel metodo openconnection.
 
Lo stesso metodo potrebbe essere riscritto così:
  	function __construct ($host, $user, $pass, $name, $LogFile){
         ...
         ...
         $this->logfile = $LogFile;     //-> passo una
costante al costruttore
     }
  e quindi:
  $db = new Mysql ( 'localhost','root','','test', new LogFile  
(PATH_LOG_FILE) );
In questo modo l'incapsulamento della classe Mysql viene rispettato.
Non che non si possa fare come hai fatto tu, c'è ben di peggio.
Il principio (tell, don't ask) da seguire è che la classe non dovrebbe mai  
far richiesta di nulla al sistema (ad esempio instanziare una classe di un  
certo tipo), al contrario, dovrebbe essere il sistema a dire alla classe  
cosa instanziare (utilizzando i metodi della stessa o passando parametri  
nel costruttore)


dovresti settare la stessa identica costante anche nell'altro progetto)
Infatti, se dovessi utilizzare la classe "Mysql" in un altro progetto sarei 
costretto
a settare anche "$LogFile".. e se non volessi utilizzare la classe "LogFile" 
che farei?
Alla fine ho scelto la soluzione delle costanti, perchč nessuno  mi vieta di 
passare
nel costruttore delle variabili anzichč delle costanti,
mi basterebbe fare una piccola modifica:
logfile = new LogFile("PATH_LOG_FILE");
mi basterebbe racchiudere il parametro tra virgolette, per farlo diventare 
una variabile
e utilizzare la classe anche in altri progetti, senza essere costretto ad 
utilizzare per
forza un file di configurazione.
Grazie

 forza un file di configurazione.
Che c'è di male in un file di configuraione ?
