Al mio lavoro sono attualmente in fase di refactoring di un CMS php molto vecchio. A questo punto, la "gestione del codice" è stata eseguita semplicemente copiando l'intera cosa e modificandola per adattarla a ciò che era necessario per fare questo lavoro (in realtà l'implementazione CMS è piuttosto un sito di esempio che una struttura per la costruzione di uno).
Fortunatamente, è piuttosto progressivo per quando è stato scritto e già utilizza le classi. Quindi la prima cosa che ho fatto è stata dividere il CMS in diversi pacchetti di compositori che sostituiscono le classi attuali. Poiché ci sono così tante versioni copiate, essere in grado di eseguire il drop-in sostituire alcune classi con la compatibilità all'indietro è molto importante per consentire una transizione più semplice al nuovo sistema.
Ormai ho un pacchetto per la registrazione e un wrapping della classe di database (ora mysqli) con una dipendenza dal pacchetto di registrazione. Attualmente il componente di logging non sta facendo molto di più che fornire un metodo factory per creare istanze logger con i soliti gestori 1 già impostati. Dovrebbe tuttavia essere in grado di accedere a un database esterno se il componente del database è installato, ma non dovrebbe dipendere da esso. A peggiorare le cose, il componente del database deve essere inizializzato dopo che il componente di registrazione ci ha avvisato in caso di un errore del database, ma devono essere memorizzati anche gli errori che si verificano prima che il componente del database sia attivo.
Ho pensato a diversi concetti, nessuno di loro è convincente:
- Mettere tutto in un unico pacchetto : questo impaccherebbe due pacchetti piuttosto non correlati e in realtà ferirebbe il principio di responsabilità singola.
- Riferimento cerchio : non consentito dal compositore. Anche una cattiva idea per diversi motivi e non troppo diversa dal confezionarli insieme.
- Usa accesso al database nativo / proprietario : facile da fare, ma viola DRY ed è proprio la cosa esatta che cerco di evitare usando il compositore.
- Factory : Sembra buono, ma in realtà creerebbe solo un super-pacchetto che ha sia come dipendenza. Anche questo richiederebbe molto tempo per essere installato e funzionante, cosa che non ho (refactor invece di riscrivere). Inoltre, è difficile da integrare nel codice esistente e dare una parte della base di codice ancora un altro sapore sembra controproducente.
La mia soluzione attuale è di avere una classe MySQLHandler nel pacchetto di registrazione, che sarà sempre registrata come gestore. La classe verifica l'esistenza di una classe di stager (che si trova nel pacchetto del database) e inoltra tutti gli errori se esiste e la registrazione al database è abilitata. Lo stager stesso è una classe singleton che memorizza tutti i messaggi fino a quando viene chiamato un metodo di attivazione. Questo metodo, infine, si connette al database e svuota il backlog (tutti gli altri messaggi sono autoflush).
Questo funziona per ora, ma sembra davvero sporco controllare l'esistenza della classe e dover chiamare una funzione di attivazione aggiuntiva dopo l'impostazione della registrazione. Qual è il modo corretto per gestire questa situazione di dipendenza?
1 Monolog funziona con diverse istanze di logger che forniscono il contesto e ognuno di essi ha gestori per scrivere file di log, inviare mail ecc.