È una cattiva idea mettere la logica dipendente esternamente nelle classi ORM?

3

Caso in questione in Entity Framework, ma questa è una domanda di progettazione che è applicabile a qualsiasi ORM.

Nell'attuale applicazione abbiamo un paio di classi di dati ORM che fanno cose non direttamente correlate alla funzione di quella classe.

Un esempio è la classe Document, che è una rappresentazione del database del documento memorizzato sull'unità di rete. Ha un costruttore che effettivamente fa una copia fisica del documento:

public Document(string filePath, int categoryId, User currentUser)
{
    FileInfo info = new FileInfo(filePath);
    this.Name = info.Name;
    this.Size = info.Length.ToString();

    this.CategoryId = categoryId;
    this.User = currentUser;
    this. CreatedOn = DateTime.Now;

    targetPath = ConfigurationManager.AppSettings["CampaignFolder"];
    FileHelper.CopyFile(filePath, targetPath + "\" + this.Name);
}

Puoi vedere come sarebbe conveniente, specialmente se stai caricando potenzialmente file da molti punti del codice e vuoi che vengano archiviati in una posizione centrale.

Un altro esempio è la classe Category, che è correlata a quanto sopra. La classe stessa ha una funzione che deve tornare al repository per fare qualche lavoro aggiuntivo - quindi ne passiamo una in:

public List<Document> SearchDocuments(string description, IRepository rep)
{
    if (this.Documents.Any(dc => dc.Description == description))
    {
        return this.Documents.(dc => dc.Description == description).ToList();
    }

    using (IRepository r = rep.Renew())
    {
        return r.GetDocuments(d => d.CategoryId == this.CategoryId 
                        && dc.Description == description).ToList();
    }
}

Ancora una volta, puoi vedere come questo è conveniente: usa le proprietà inerenti all'oggetto, ed è un posto utile dove mettere questa funzione se viene chiamata da molti posti diversi.

Vale anche la pena notare che quest'ultima funzione, almeno, non rompere la testabilità.

Tuttavia, non posso aiutare la sensazione che ciò sia sbagliato in qualche modo. Sembra una violazione di una singola responsabilità - queste cose sono solo per il trasporto di dati e forse alcune proprietà calcolate. D'altro canto, mettere al loro interno funzioni come queste rimuove il fastidioso proliferare delle classi helper.

Questa è una cattiva idea? O mi preoccupo per niente?

    
posta Matt Thrower 12.01.2016 - 15:38
fonte

2 risposte

3

Penso che tu abbia ragione nelle tue preoccupazioni.

In entrambi i casi, separerei le funzioni del repository dall'oggetto.

L'oggetto documento sembra particolarmente cattivo in quanto la logica si svolge nel costruttore

es

IDocumentRepository.Save(Document doc);
IDocumentRepository.Search(string description)

Questo ti aiuta a ottenere una serie di cose:

1: Nessuna dipendenza dell'oggetto sull'implementazione del repository

2: le responsabilità relative alla permanenza dell'oggetto sono incapsulate nel loro oggetto repository piuttosto che nell'oggetto Dominio

    
risposta data 12.01.2016 - 16:03
fonte
1

Sì, non è corretto mettere la logica dipendente esternamente nelle classi ORM.

Idealmente, l'unico scopo di un ORM è di fornire una mappa dal database agli oggetti usati dal codice (es. - Mappatura relazionale degli oggetti)

Quando confondi la responsabilità dello scopo di un oggetto, stai rompendo la possibilità di scambiare componenti dal sistema senza rompere le altre parti.

Se qualcosa cambia sul modo in cui i file sono archiviati ora devi andare all'interno dell'entità e ovunque si acceda ai file. Due posizioni per apportare modifiche anziché una posizione.

Per mantenere la funzionalità desiderata, ti consiglio di impostare un servizio che possa essere a conoscenza del Repository, Files & ORM.

    
risposta data 12.01.2016 - 16:38
fonte

Leggi altre domande sui tag