Per me, gli archivi, combinati con ORM o altri livelli di persistenza DB, hanno questi svantaggi:
- Coprire le unità di lavoro. UoW deve essere codificato dal programmatore e raramente può essere implementato come una sorta di magia in background, dove l'utente fa semplicemente query e modifiche, senza definire i limiti UoW e, eventualmente, il punto di commit. A volte, l'UoW viene abbandonato riducendoli in micro UoW (ad esempio sessioni di NHibernate) in ciascun metodo di accesso al repository.
- Coprire o, nel peggiore dei casi, distruggere Persistenza Ignoranza: metodi come "Load ()", "Get ()", "Save ()" o "Update ()" suggeriscono operazioni immediate, a singolo oggetto, come se si invia un singolo SQL / DML o se si lavora con i file. Infatti, ad esempio, i metodi di NHibernate, con questi nomi fuorvianti, di solito non rendono l'accesso individuale, ma accodano per il carico pigro o il batch di inserimento / aggiornamento (Persistenza Ignoranza). A volte, i programmatori si chiedono perché non ottengono operazioni DB immediate e violano forzatamente l'ignoranza della persistenza, uccidendo così le prestazioni e usando i maggiori sforzi per rendere il sistema (molto!) Peggio.
- Crescita incontrollata. Un repository semplice potrebbe accumulare sempre più metodi per soddisfare esigenze specifiche.
Ad esempio:
public interface ICarsRepository /* initial */
{
ICar CreateNewCar();
ICar LoadCar(int id); // bad, should be for multiple IDs.
void SaveCar(ICar carToSave); // bad, no individual saves, use UoW commit!
}
public interface ICarsRepository /* a few years later */
{
ICar CreateNewCar();
ICar LoadCar(int id);
IList<ICar> GetBlueCars();
IList<ICar> GetRedYellowGreenCars();
IList<ICar> GetCarsByColor(Color colorOfCars); // a bit better
IList<ICar> GetCarsByColor(IEnumerable<Color> colorsOfCars); // better!
IList<ICar> GetCarsWithPowerBetween(int hpFrom, int hpTo);
IList<ICar> GetCarsWithPowerKwBetween(int kwFrom, int kwTo);
IList<ICar> GetCarsBuiltBetween(int yearFrom, int yearTo);
IList<ICar> GetCarsBuiltBetween(DateTime from, DateTime to); // some also need month and day
IList<ICar> GetHybridCarsBuiltBetween(DateTime from, DateTime to);
IList<ICar> GetElectricCarsBuiltBetween(DateTime from, DateTime to);
IList<ICar> GetCarsFromManufacturer(IManufacturer carManufacturer);
bool HasCarMeanwhileBeenChangedBySomebodyElseInDb(ICar car); // persistence ignorance broken
void SaveCar(ICar carToSave);
}
4. Oggetto di pericolo di Dio: potresti essere tentato di creare una classe di Dio, che copra tutto il tuo modello o livello di accesso ai dati. La classe repository non solo contiene i metodi Car, ma i metodi per tutte le entità.
A mio parere, è meglio offrire almeno alcune opportunità di query, per evitare l'immensa confusione di molti metodi a scopo singolo. Non importa se si tratta di LINQ, un proprio linguaggio di query o anche qualcosa preso direttamente dall'ORM (OK, tipo di problema di accoppiamento ...).