Riduci a icona il codice già funzionante quando è necessario un cambiamento radicale

1

Ho un codice che si basa molto su una struttura Array come la seguente:

$array['customer'][$customer_id]['details'][..];    // it goes to about 10 levels deep

Tuttavia, dopo quasi due anni dallo sviluppo iniziale, ora devo includere un altro elemento di alto livello per quell'array che lo renderà simile a questo:

$array['company'][$id]['customer'][..];

La sfida è che circa 12.000 linee di codice sorgente sono scritte da quattro programmatori: sono l'unico che sta ancora lavorando al progetto, E non ci sono test di unità, getter e setter, DI ecc. -casa struttura MVC. Quindi, cambiare la struttura di quell'array richiederà probabilmente il 30% percento dei metodi da modificare per adattarsi alla nuova modifica, altrimenti semplicemente non funzioneranno come previsto.

Esiste un approccio generale per questi tipi di mal di testa? Posso implementare un metodo che potrebbe in qualche modo colmare il divario?

So che la domanda è troppo vaga senza vedere il vero codice sorgente, tuttavia apprezzo molto qualsiasi raccomandazione.

Aggiorna

Attualmente sto pensando di avere un metodo / funzione che restituisce l' legacy array , tuttavia puoi effettivamente passare l' identificatore desiderato e metterlo in un ciclo per ottenere lo stesso effetto: non sono sicuro che funzionerà in tutti i casi, ma si spera che si adatti alla maggior parte dei casi:

$data = get_legacy_array( $company_id );    // Instead of: $data = $array['customer']...
    
posta Mahdi 24.02.2014 - 08:58
fonte

2 risposte

5

Sembra che quello che devi fare riduca a normalizzare la struttura dei dati, e metti semplicemente ['company'][$id] davanti a ogni% di% di utilizzo. Ovviamente potresti usare find & sostituisci (con uno strumento come AstroGrep), ma .. Tempo per qualche terminologia.

refactoring.

In primo luogo, il Refactor ti consente di deformare la tua mente più facilmente, sostanzialmente ristrutturando il problema in modo che sia molto semplice da risolvere, quindi basterà utilizzare la nuova funzionalità.

Il refactoring sta cambiando il design del codice di base interno per soddisfare meglio le (nuove) richieste. Che si tratti di prestazioni, stabilità o persino leggibilità. Aggiungere / cambiare funzionalità potrebbe essere messo sotto lo stesso ombrello ma non lo farei: di solito questa è la cosa che si attiva in pochi minuti dopo il refactoring.

Un esempio ..

Quindi quando refactro faccio not cambiare le funzionalità, faccio solo un punto in cui posso facilmente avviarlo, in un secondo momento. Tutte le funzionalità sono mantenute identiche.

Avrei tutte le ricerche in quell'array passare attraverso un posto centrale, una funzione come:

/**
 * Central customers lookup method, to aid implementing future functionality.
 * @param array $array       The original array.
 * @param Integer $companyid Optional. If given $array['company'][$companyid] must exist.
 * @return array             The $array parameter or a subset thereof.
 */
function GetCompanyCustomers($array, $companyid=null) {
  if ($companyid==null) {
    // Old approach
    return $array;
  } else {
    // Example doublechecks for debugging
    if (!isset($array['company'])) {
      echo 'Error! GetCompanyCustomers() $array["company"] does not exist.';
    }
    if (!isset($array['company'][$companyid])) {
      echo 'Error! GetCompanyCustomers() $array["company"][$companyid] does not exist.';
    }

    // New approach
    return $array['company'][$companyid];
  }
}

Questo facilita la transizione.

In primo luogo si inserisce questa funzione (e un setter, forse) dappertutto e si assicura che tutto funzioni esattamente come prima, quindi si passa effettivamente all'utilizzo di $ companyid. Anche annullare le modifiche dovrebbe essere semplice, basta modificare di nuovo la funzione. Prendi in considerazione l'impostazione di setter corrispondenti.

Ulteriori consigli:

Di solito non è una buona idea avere una matrice così grande che contenga tutti i dati, che viene riempita di nuovo per ogni richiesta del browser. Espone un cattivo design fondamentale. A meno che non sia necessario mostrare tutti i dati contemporaneamente su una pagina.

Tieni presente che i tuoi dati vengono normalizzati in modo che parti della ricerca siano auto-descrittive e autonome. Usa i modelli di dati per escludere l'accesso esterno, una matrice può essere efficiente a volte ma può morderti soprattutto in un linguaggio non tipizzato come PHP. Quello che ho fatto ora con il getter potrebbe (o dovrebbe ..) essere inserito in una classe (DataModel che rappresenta).

    
risposta data 24.02.2014 - 11:30
fonte
2

Sembra che ArrayObject in PHP5 ti consenta di creare una classe personalizzata in grado di operare come un array, che ti permetterebbe di fare cose orribili e orribili come [$ foo] restituendo cose completamente diverse a seconda del contesto. Potrebbe non essere una buona idea, ma non vedo perché non si possa dare a un oggetto di accesso ai dati più intelligente la stessa interfaccia di un array e quindi si tratti di una sostituzione drop-in. Almeno se accedete in base a stringhe costanti, dovreste essere in grado di modificare il comportamento con un minimo di stupore non necessario.

    
risposta data 24.02.2014 - 10:35
fonte

Leggi altre domande sui tag