Newsgroup: it.comp.www.php
Titolo: OOP: le recursioni fanno male?

Mi sembra di aver letto da qualche parte che le ricursioni php le gestisce abbastanza bene, e in teoria non creano problemi.. ma vorrei approfondire la cosa e vedere se è veramente così.
Stò implementanto il pattern DI (dependency injection) per sostituire il singleton, e mi ritrovo in una situazione del tipo: ho una classe watchdog, che serve per loggare gli errori in vari modi, file, database, via mail, o a schermo;
Per loggare gli errori in un file ha bisogno della classe file, che gestisce le paths, permessi e quant'altro.
La classe file a sua volta ha bisogno del watchdog, se fallisce l'apertura o la scrittura di un file deve loggare l'errore.
Quindi mi ritrovo con
$watchdog->file = istanza classe File
$file->watchdog = istanza classe Watchdog
.. il che si risolve in un (teorico) infinito loop.
Ora, averne tanti di questi 'loop' può rallentare significamente o dare altri problemi?
Oppure mi conviene mantenere tutto nel container DI e nel watchdog, quando gli serve il file, richiederlo al containere viceversa nella classe file richiedere il watchdog dal container?

 l'apertura o la scrittura di un file deve loggare l'errore.
Secondo me e` sbagliata l'architettura. Questa classe File andrebbe 
costruita "apposta" per il watchdog, e non dovrebbe averne bisogno, ma 
prevedere un fallback per il logging dei suoi errori.
Il loop che ipotizzi non e` tanto teorico, e bloccherebbe tutto.
Poi potrai avere un'altra classe File generica per il resto 
dell'applicazione, ma questa dovrebbe essere il piu` possibile isolata.
Bye.

 Bye.
Grazie per la risposta, sempre celere e costruttiva ;)

 dell'applicazione, ma questa dovrebbe essere il piu` possibile isolata.
Io infatti non implementerei il watchdog dentro la classe File. Lascerei
il compito allo strato superiore dell'applicazione gestire i messaggi di
watchgod nei punti in cui usa la classe File.
Immagino che la classe File sia abbastanza "atomica": aprirà, chiuderà,
leggerà, scriverà file... Sono operazioni "semplici".
Lascia che sia chi usa la classe File a preoccuparsi dei log.
IMHO
-- 
Aiuta l'Alleanza Ribelle :
http://vwdarkside.com/it/jedi/maestro-padulo-132140

@Mau C: non hai tutti i torti, l'altra opzione era di avere tutti gli helper che ritornano booleani (true successo, false fallimento) e poi lasciare che sia il controller a invocare il watchdog, che tanto poi deve controllare cmq.
Più che altro, se avete 3 secondi, provate a dare un'occhiata a questo link: 
http://www.devshed.com/c/a/PHP/The-Dependency-Injection-Design-Pattern-in-PHP-5/
A me sembra che implementi e descriva il Singleton invece del Dependency Injection.. ho ragione o come al solito non ho capito 'na ceppa?

 }
Ecco, questo e` sbagliato. Non e` watchdog che deve istanziare File, 
altrimenti e` solo dependency o al massimo factory, ma non DI.
Nella DI dovresti fare qualcosa del genere:
$filelogger = new Watchdog_Logger_File('/var/log/ciccio.log');
$watchdog = new Watchdog();
$watchdog->addLogger($filelogger);
Il tutto FUORI da entrambe le classi. Watchdog non deve sapere cosa gli 
passi come logger, ma al massimo deve sapere che rispetta una certa 
interfaccia, e quindi ha dei metodi con una determinata firma che puo` 
usare.
La prima riga puo` essere sostituita con un DI-manager (che onestamente 
devo ancora capire completamente).
A livello implementativo sara` qualcosa del genere
interface Watchdog_Logger {
 public function log($msg);
}
class Watchdog_Logger_File implements Watchdog_Logger
{
 private $filename;
 public function __construct($filename) {$this->filename=$filename;}
 public function log($msg)
 {
   $f = fopen($this->filename, 'a');
   fwrite($f, $msg);
   fclose($f);
 }
}
class Watchdog
{
 private $loggers = array();
 ...
 public function addLogger(Watchdog_Logger $logger)
 {
  $this->loggers[] = $logger;
 }
 public function log($msg)
 {
  foreach ($this->loggers as $logger) {
    $logger->log($msg);
  }
 }
}
Questa e` la base, lascio a te approfondire (e mettere i controlli di 
errore :) )
Bye.

 usare.
fico, sto facendo tutto al contrario ;)
Onestamente più provo a implementare il DI e più ricado nel Singleton.
Il mio problema è che per le classi "accessorie", gli helper, vorrei fossero 'globali', cioè che io da qualsiasi parte nell'applicazione posso invocare il watchdog o il File, questo evitando loop infiniti (cosa che con il DI mi sembra molto facile sbagliarsi).
Cioè, io ho il main controller, che per prima cosa setta i vari parametri.
Poi invoca i moduli fondamentali, come il router.
In base al router invoca il controller indicato.
Io da dentro il controller, o da dentro il router, vorrei poter lanciare il watchdog (più a uso debugger che watchdog a questo punto), quindi dovrei fare una cosa del tipo che il main controller inizializza e configura un watchdog, e lo passa al sotto-controller e al router (DI) utilizzando un registro:
// main controller
$loggers = array(
    'file_logger' => new File('/var/www/app/private/logs/'),
    'mail_logger' => new Mailer('
smtp.example.com
', [mail configs]),
    'database_logger' => new DB_logger($this->db_connection), //model che 'vede' solo tabelle di log
);
self::$_watchdog = new Watchdog();
self::$_watchdog->set_loggers($loggers);
// da qualche parte, nel router voglio loggare qualcosa
MiaApp::$_watchdog->log('Ecco un log', WATCHDOG_LEVEL_DEBUG);
// da qualche parte, nel controller:
if(MiaApp::$_router->action === null)
{
    MiaApp::$_watchdog->log('Manca l\'azione, procedo con default', WATCHDOG_LEVEL_WARNING);
    if(method_exists($this, 'index'))
    {
        $this->index();
    }
    else
    {
        MiaApp::$_watchdog->log('metodo default non trovato: puppa!', WATCHDOG_LEVEL_ERROR);
    }
}
ma questo, non è i singleton?

 implementare il DI e più ricado nel Singleton.
Non ti rispondo finche` non cambi lo schifo di programma di newsgroup che 
usi con uno che rispetti la RFC (che mantenga i thread e che rispetti il 
Re nel subject) :P
Bye.

 Re nel subject) :P
Ho l'atroce sospetto che sia il "nuovo fiammante" Google Groups. Si può
tornare alla versione "vecchia" che non ha questo problema.



Ok sono tornato alla versione "vecchia" ;)

.. ma vedo che scazzo i quote lo stesso, chepalle.

 utilizzando un registro:
Potresti addirittura rendere modulari il router o il dispatcher, e 
metterli dentro al DI Container, e il Front Controller potrebbe 
richiamarli senza sapere cosa gli arrivera`. :)
 
Che credo sia quello che vogliono fare in Symfony2 e in Zend Framework 2
Bye.

 Ora anche io ho le idee un po' piu` chiare.
OK, sono fuso. Tre "un po'" e una doppia mancante in quattro righe di 
post. Per fortuna che sta arrivando il weekend.
Bye.

 Bye.
Grazie, esaustivo come sempre, quell'articolo lo avevo già letto
(forse un pò di fretta) e a 'modo mio' capito, solo che facendo
qualche prova ho avuto il dubbio che le DI siano effettivamente più
gestibili del singleton per implementazioni di media-grande scala... e
mi sono risposto che se il termine di paragone è la manutentibilità
del codice la risposta deve essere si.
Nel week-end mi rileggo bene quell'articolo ;)