Come gestire le dipendenze opzionali in php?

1

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:

  1. Mettere tutto in un unico pacchetto : questo impaccherebbe due pacchetti piuttosto non correlati e in realtà ferirebbe il principio di responsabilità singola.
  2. Riferimento cerchio : non consentito dal compositore. Anche una cattiva idea per diversi motivi e non troppo diversa dal confezionarli insieme.
  3. Usa accesso al database nativo / proprietario : facile da fare, ma viola DRY ed è proprio la cosa esatta che cerco di evitare usando il compositore.
  4. 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.

    
posta Sebb 17.02.2016 - 22:06
fonte

1 risposta

0

In termini di implementazione delle dipendenze opzionali, utilizzare la seguente procedura:

  • Definisci i nomi dei metodi e i valori predefiniti
  • Documenta come sovrascrivere i valori predefiniti
  • Riassunto tutte le comunicazioni tra PHP e software esterno

Ad esempio:

Every Page Controller communicates with a Model using method names which are defined in the abstract table class, which means that any Controller can be used with any Model.

The construction and generation of all SQL statements is performed within a separate Data Access Object, with a separate class for each different DBMS (MySQL, PostgreSQL, Oracle, SQL Server). As each of these classes use identical method names I can switch from one DBMS to another without having to change any code in any of the Model classes.

Consentire metodi per consumare un tipo di dati diverso per lo stesso argomento aiuta anche:

Some controls, such as radio groups and dropdown lists, do not have single values but a group of options, and it is possible to have different scripting events on each option, as shown in the following:

  <select name="star_sign" onchange="alert('change');">
    <option value=""> </option>
    <option value="ARI" onkeypress="alert('1');">Aries</option>
    <option value="AQU" onkeypress="alert('2');">Aquarius</option>
    <option value="CAN" onkeypress="alert('3');">Cancer</option>
    <option value="CAP" onkeypress="alert('4');">Capricorn</option>
    <option value="GEM" onkeypress="alert('5');">Gemini</option>
    <option value="LEO" onkeypress="alert('6');">Leo</option>
    <option value="LIB" onkeypress="alert('7');">Libra</option>
    <option value="PIS" onkeypress="alert('8');">Pisces</option>
    <option value="SAG" onkeypress="alert('9');">Sagittarius</option>
    <option value="SCO" onkeypress="alert('10');">Scorpio</option>
    <option value="TAU" onkeypress="alert('11');">Taurus</option>
    <option value="VIR" onkeypress="alert('12');" selected="selected">Virgo</option>
  </select>

The options are normally supplied in an associative array consisting of a key and a value, as in:

$array['star_sign'] = array('ARI' => 'Aries',
                        ...
                        'VIR' => 'Virgo');

In order to supply an additional set of scripting events for each key it is necessary to replace the value part with an array, as in the following:

$array['star_sign'] = array('ARI' => array('value' => 'Aries',
                                           'onkeyup' => "alert('up');",
                                           'onkeydown' => "alert('down');"),
                            ...
                            'VIR' => array('value' => 'Virgo',
                                           'onkeypress' => "alert('12');"));

Riferimenti

risposta data 25.09.2018 - 18:07
fonte