Devo utilizzare l'inversione di dipendenza in questo caso?

1

Ho una classe Document e una classe DocumentItem. Un documento crea più DocumentItems.

Mentre il mio progetto si è evoluto, mi sono reso conto che DocumentItem aveva bisogno di una logica "profonda" per visualizzare correttamente, prima controllando un database, poi il web. Il mio codice ha finito per sembrare così:

class DocumentItem 
 ...
    function getValue() {
        $du= new DocumentUtils();
        $possibleValue = $du->LookupValueInDatabaseRecursively();
        if (!$possibleValue)
            $possibleValue = $du->LookupValueOnWeb();
        return $possibleValue;
    }

Ciò che non mi piace di questo è che la mia classe DocumentItem deve "sapere" tutto su DocumentUtils e la logica più profonda associata a ottenere questo valore.

C'è un modo per isolare DocumentItem da DocumentUtils e la sua logica?

L'inversione di dipendenza dovrebbe essere utilizzata qui, quindi non abbiamo un "albero" di dipendenze?

Esiste un modello di progettazione migliore per questo?

    
posta Charlie Dalsass 10.12.2016 - 16:04
fonte

1 risposta

1

Quello che stai cercando è l'incapsulamento. L'inversione delle dipendenze può aiutarti a realizzarlo, ma è solo uno dei tanti modi.

Ciò che mi colpisce di getValue() è che non sembra utilizzare nulla da DocumentItem . Se è vero, vive nel posto sbagliato. I metodi dovrebbero vivere vicino a ciò di cui hanno bisogno. La logica qui si riduce all'utilizzo di una delle due fusioni su DocumentUtils e tale decisione si basa esclusivamente su ciò che uno di loro restituisce. Perché DocumentItem è coinvolto anche qui?

class DocumentUtils {
...
    function getValue() {
        $possibleValue = $du->LookupValueInDatabaseRecursively();
        if (!$possibleValue) {
            $possibleValue = $du->LookupValueOnWeb();
        }
        return $possibleValue;        
    }
}

class DocumentItem {
    private $du;

    public function __construct($documentUtils) {
        $this->du = $documentUtils;
    }

    function getValue() {
        return $du.getValue();
    }
}

//and here's your dependency injection.
$value = new DocumentItem(new DocumentUtils())).getValue();

Ora DocumentItem non deve sapere come ottenere questo valore. Fa DocumentUtils farlo che sa di più su cosa sta succedendo qui comunque.

Devo dire che questi nomi non sono ottimali. Document , DocumentItem , DocumentUtil ? Non c'è da meravigliarsi se non sei sicuro di dove mettere qualcosa.

Se Document crea più DocumentItems forse è un DocumentFactory . Forse un DocumentItem è in realtà solo un Document . Qualunque cosa forse che cerchi i valori nel database o nel web è il tuo DocumentGateway .

Nota: di solito non vuoi mescolare la costruzione e usarla come ho fatto quando ho fatto l'iniezione di dipendenza in un solo liner. Il punto è che ora le cose prima e dopo il punto possono essere separate.

    
risposta data 10.12.2016 - 17:22
fonte

Leggi altre domande sui tag