L'architettura del progetto ha una strong relazione con le librerie utilizzate?

6

I programmatori, quando si tratta di parlare di modelli popolari nelle applicazioni aziendali, predicare che si dovrebbe codificare contro le interfacce per rimuovere forti relazioni tra i componenti; fare ciò aiuterà a cambiare i tipi di cemento riducendo al minimo i cambiamenti in altre aree dell'applicazione. L'ipotesi di fondo è che le interfacce riguardano esclusivamente le astrazioni. Quando si tratta di vita reale è quasi impossibile. Usiamo un esempio:

Diciamo che attualmente utilizzi un framework ORM nella tua applicazione, che hai sottratto applicando il pattern del repository. Ora, puoi veramente cambiare il framework ORM senza problemi?

public interface IRepository<T>
{        
    T GetById(int id);      
    void Add(T entity);
    void Remove(T entity);
    void Update(T entity);
    IQueryable<T> Query(Expression<Func<T, bool>> filter);                                
} 

In teoria, questa implementazione può essere applicata al resto dell'applicazione, ma restano molte domande sull'applicazione effettiva di questo modello:

  1. In che modo questo schema mi protegge dal processo interno delle librerie?
  2. In che modo l'astrazione si occupa della variazione delle eccezioni generate da ciascuna libreria?
  3. Se ho selezionato un ORM che fornisce internamente un meccanismo di memorizzazione nella cache e in seguito decido di passare a un ORM alternativo privo di tale supporto, come lo gestisce questo modello?

Quindi, da questo, credo che l'architettura del progetto sia strongmente influenzata dalle librerie che vengono utilizzate. c'è qualcosa di sbagliato con questo? Sto assumendo troppo da questo modello?

    
posta AnyOne 04.09.2011 - 19:51
fonte

5 risposte

5

Chiunque,

L'interfaccia che hai mostrato è un esempio di un'astrazione tipica che si trova tra un client e un sistema CRUD. Come in tutti i modelli, c'è un punto in cui è necessario riconoscere che il prodotto è sovradimensionato. Compensare una mancanza di conoscenza del dominio costruendo una flessibilità sistematica è uno dei tanti mali dello sviluppo del software. Sei un programmatore, non un profeta.

Hai menzionato il caching. L'interfaccia mostrata non presuppone l'utilizzo della memorizzazione nella cache, pertanto l'interfaccia protegge il codice client da questa differenza se si sceglie di passare. Per quanto riguarda le prestazioni, potresti notare una differenza, ma al codice non interessa.

Riguardo alle eccezioni, puoi costruire la tua gerarchia che include eccezioni specifiche. Credo che il framework Spring adotti questo approccio con i template JDBC poiché l'API JDBC ha solo un'eccezione: SQLException, che non protegge il codice client dai problemi specifici del driver JDBC, quindi Spring offre una gerarchia di eccezioni che include la maggior parte degli errori specifici del driver ciò può accadere durante il runtime.

Quindi, la scelta delle librerie può influenzare le prestazioni e il comportamento in fase di esecuzione del sistema, ma le interfacce di uso generale non dovrebbero interessare le caratteristiche specifiche di un'implementazione sottostante, poiché ciò comporterebbe ciò che Spolsky chiama astrazione dolente .

    
risposta data 04.09.2011 - 21:11
fonte
3

Quello che descrivi è solo un altro caso della "Legge delle astrazioni che perdono" di Joel. Leggi il suo bel blog su questo argomento:

 http://www.joelonsoftware.com/articles/LeakyAbstractions.html

D'altra parte, quando si desidera che le diverse implementazioni del repository siano intercambiabili, il solo conferimento a qualche interfaccia non è sufficiente, è corretto. Almeno, devono seguire il principio di sostituzione di Liskov . Questo principio afferma che le diverse sottoclassi di IRepository devono comportarsi allo stesso modo, ad esempio, l'uso coerente delle eccezioni per la gestione degli errori,

Bene, l'esempio ORM è ovviamente un caso difficile, dal momento che gli ORM sono spesso componenti complessi in cui anche aspetti come i requisiti di prestazioni o il sovraccarico della memoria possono fare la differenza tra un componente fattibile per il tuo progetto o meno. Il principio di inversione delle dipendenze (che è lo schema che hai descritto) si applica molto più facilmente ai componenti più piccoli. E si applica molto meglio ai componenti che hai sotto il tuo controllo - non aspettarti che i componenti di terzi siano intercambiabili facilmente se non sono progettati appositamente per questo scopo.

IMHO il vero valore di un'interfaccia IRepository non è l'intercambiabilità di un ORM rispetto ad un altro. Il vero valore è che è possibile creare un'implementazione simulata per il repository consentendo test unitari leggeri.

    
risposta data 04.09.2011 - 20:51
fonte
1

Vorrei andare un po 'oltre gli altri commentatori. Gli ORM non sono sicuramente un'interfaccia astratta. Esistono dozzine di dipendenze e comportamenti specifici di implementazione. Piccole modifiche nel modello sottostante o le tecnologie sottostanti si propagano all'applicazione.

Gli ORM sono una scorciatoia per programmatori e forniscono ai codificatori OO un'interfaccia con la quale sono più a loro agio di raw * dbc. Le classi risultanti non dovrebbero essere pensate come interfacce.

In termini architettonici una "interfaccia" è un'interfaccia tra componenti logici. In molti casi un componente è costituito dal codice e dal suo modello di dati sottostante. Non è possibile separare un database e il codice che gestisce quel database in due componenti separati, sono intimamente collegati. Qualsiasi modifica al modello di dati comporterà (e dovrà) comportare una modifica al codice dell'applicazione che mantiene il modello.

    
risposta data 06.09.2011 - 08:30
fonte
1

Le biblioteche generalmente non influenzano l'architettura dell'applicazione. I quadri, d'altra parte, fanno. C'è una grande differenza tra librerie e framework. Le librerie offrono funzionalità che possono essere richiamate come base necessaria. I framework richiedono che il tuo codice aderisca al concetto di framework, altrimenti non farai realmente uso del framework.

    
risposta data 06.09.2011 - 08:34
fonte
0

" In teoria, non c'è differenza tra teoria e pratica. In pratica, c'è. "

L'isolamento tramite interfacce è una grande teoria. Raramente ha successo nella pratica, perché le implementazioni che si nascondono dietro le interfacce hanno spesso differenze comportamentali che vanno ben oltre la capacità di nascondere l'interfaccia. Anche le interfacce che si sforzano di avere un strong supporto e sono altamente isolabili ( e.g. , SQL) non riescono comunque a essere completamente isolate.

    
risposta data 27.10.2011 - 21:41
fonte