Esiste un nome ufficiale per l'anti-pattern della "malattia di un oggetto" (operazioni iterative a singolo oggetto su database, servizi, ecc.)?

0

È causato dal paradigma di programmazione ingenuo: concentrati su un singolo oggetto, fai qualcosa con esso, e se devi lavorare con molti oggetti, fai un loop, iterate e attraversi, ripetendo l'operazione su ogni oggetto che incontrerai . Questo di solito è o.k. per raccolte piuttosto piccole in memoria.

È sbagliato in un ambiente in cui un approccio basato su set può essere gestito molto meglio, o ogni singola operazione ha costi di gestione costosi, quindi è meglio raggrupparli. Tipicamente, database e servizi che richiedono connessioni e round trip per ogni operazione e possono gestire le operazioni di set molto meglio.

Ad esempio, un livello di accesso ai dati codificato in modo nativo caricherà una raccolta di oggetti radice / padre aggregati, quindi eseguirà un ciclo sulla raccolta per recuperare oggetti figlio per ciascuno e quindi su ogni oggetto figlio per recuperare oggetti "nipotino" per singole query , invece di creare una query per le righe / gli oggetti di dati successivi di tutti i genitori e poi tutti. Poiché un numero di genitori N richiede 1 query per i genitori e poi N per i loro figli, questo problema è noto come SELECT N + 1, che spesso mette in ginocchio database e prestazioni delle applicazioni.

Bad:

var parents = dbaccess.SelectParentsFromDb(fromDateTime, toDateTime);
foreach(var parent in parents)
{
    parent.Children = dbaccess.GetChildrenForParent(parent.Id);
}

Buono:

var parents = dbaccess.SelectParentsFromDb(fromDateTime, toDateTime);
var parentIds = parents.Select(p => p.Id).ToArray();
var allChildren = dbaccess.GetChildrenForParents(parentIds);
foreach(var parent in parents)
{
    parent.Children = allChildren
        .Where(c => c.ParentId == parent.Id)
        .toList();
}

Nella codifica diretta del database, come con PL / SQL o T-SQL, questo anti-pattern sarebbe visibile come un cursore DB per scorrere su righe, piuttosto che usare comandi SQL o DML basati su set. Questo è il motivo principale per cui i cursori sono di solito considerati pessimi nella programmazione di database.

Utilizzando servizi web o altre fonti remote, si possono verificare svantaggi analoghi; enorme overhead e perdita di tempo attraverso un gran numero di query / operazioni su singoli oggetti.

A volte, gli sviluppatori insistono su questo approccio "gestisci un oggetto, ripeti per più", almeno finché non ne riconoscono le conseguenze; per questo motivo, ho iniziato a chiamare questa "malattia ad un oggetto" anti-pattern.

C'è un nome più "ufficiale" per questo?

    
posta Erik Hart 25.03.2016 - 01:27
fonte

1 risposta

2

Come commento di Robert Harvey, mi aspetterei di vedere questo come un problema "N + 1" come termine generico per scenari simili in cui viene utilizzata un'implementazione O (n) o anche O (n ^ 2) quando un La soluzione O (1) è disponibile.

Un "l'algoritmo di Schlemiel the Painter" è simile ma non esattamente quello che stai descrivendo qui.

    
risposta data 25.03.2016 - 02:51
fonte