Metodo di progettazione per restituire Elenco di oggetti

4

Devo creare un metodo che restituisca un elenco di oggetti IRule.

Questo è quello che ho scritto, ho ragione nell'approccio? O dovrei seguire qualche schema / principio?

public IList<IRule> GetRules()
{
    return new List<IRule> {
         new Rule1(),
         new Rule2(),
         ...etc
     }
}
    
posta Bhaskar K 12.05.2015 - 11:45
fonte

4 risposte

2

Dipende da come è necessario utilizzare GetRules.
Se è costoso e vuoi davvero accedere allo stesso insieme di regole ovunque nella tua applicazione, creo una classe Cache che memorizza l'elenco di regole.

In questa istanza (e quasi tutti gli altri) un Singleton sarebbe un modello di formica. Invece avresti un'interfaccia ICache con un metodo GetRules e un riferimento ICache a ogni oggetto che ne ha bisogno.

Sebbene si tratti di un lavoro maggiore rispetto a quello di un Singleton (in realtà è sorprendentemente difficile implementare correttamente il pattern Singleton), ti offre una separazione corretta delle preoccupazioni e ti consente di sostituire il meccanismo dietro l'interfaccia ICache . per esempio. Nel tempo trovi che è necessario aggiornare la cache ogni 8 ore. L'oggetto Cache può farlo, ma il codice client non deve essere modificato.
O trovi che devi implementare due diversi tipi di memorizzazione nella cache per due diversi giochi / client? Basta iniettare una diversa implementazione della cache.
Tra un anno, una parte dell'app in esecuzione ha bisogno di vedere le regole in tempo reale in un database e non può funzionare dalla cache? Inietti una cache diversa che non è effettivamente una cache ma restituisce regole live ogni volta che viene chiamata. Saresti nei guai con un singleton su quello.

Questo è un modo in cui puoi farlo. Avere una cache che restituisce regole, o un IRulesProvider che sa come ottenere le regole.
Estrarre le regole, iniettare quell'astrazione nelle classi che necessitano di regole, quindi implementare quell'interfaccia.
Puoi ancora scegliere di creare solo un'istanza della classe che implementa IRulesProvider , ma dipende da te, non hai bisogno di tutta la merda che arriva con il pattern Singleton, metà del quale è lì per proteggerti dalla creazione di più che su istanza della classe.

A questo punto potresti aver indovinato che in passato mi sono imbattuto in teste con Singletons. . . ha lasciato alcune cicatrici:)

Anche se non è costoso creare gli oggetti Considera ancora il modello Provider. Ti dà una grande flessibilità e una corretta separazione delle preoccupazioni. Le cose che usano le regole possono ottenere regole, ma non sanno nemmeno quali regole possano ottenere. È uno schema davvero potente da seguire e lascia te e il tuo codice estremamente agili.

Un esempio di cosa intendo per modello di provider.

interface IRulesProvider
{
    IEnumerable<IRule> GetRules();
}

class RulesProvider: IRulesProvider
{
    IEnumerable<IRule> GetRules()
    {
        // return some rules;
    }
}

Le regole sono memorizzate nella cache sull'oggetto RulesProvider ? vengono recuperati da un file Xml e memorizzati nella cache, vengono letti in tempo reale da un database ogni volta che viene chiamato GetRules ? È a te che quel corso ti inietta un IRulesProvider in nessuno dei due sa né importa come il fornitore apprenda le regole (a meno che, naturalmente, non debba sapere , a quel punto abbiamo bisogno di un meccanismo diverso) .

    
risposta data 12.05.2015 - 12:43
fonte
3

Esci dal tuo commento, dove non hai bisogno di un nuovo elenco ogni volta. Sarebbe meglio creare l'elenco una volta e restituire lo stesso elenco "singleton" in quella funzione.

public class RuleProvider
{
    private readonly List<IRule> _theRules = 
        new List<IRule>{
         new Rule1(new Writer1()),
         new Rule2(new Writer2())
        };

    Public IList<IRule> GetRules()
    {
        return _theRules;
    }
}

A seconda di come si desidera utilizzare questo elenco, vale la pena esaminare:
1) Caricamento lento - posticipare il caricamento "intial" fino a qualcuno deve usare l'elenco delle regole.
2) Raccolta di sola lettura - in modo che gli utenti della tua "regole" non possono modificare la lista.

    
risposta data 12.05.2015 - 12:03
fonte
1

Considera il codice:

foreach (Object o in Items)
{
    foreach(Rule r in GetRules())
    {
        //apply rule
    }
}

Questo creerà più copie del tuo elenco di oggetti. questi saranno eventualmente raccolti dal garbage collector. ma nel frattempo loro mangiano la memoria.

Ora se lo hai chiamato "CreateRules ()" o hai aggiunto qualche commento xml, è meno probabile che lo faccia per sbaglio. Ma è ancora piuttosto rischioso e pone la domanda su cosa stai cercando di ottenere.

Fai attenzione a cadere nella direzione opposta e a fornire l'accesso a un elenco mutabile, in cui non desideri che le modifiche in un elenco di GetRules () influiscano su una seconda chiamata

    
risposta data 13.05.2015 - 11:16
fonte
0

Perché non utilizzare resa ?

 public System.Collections.Generic.IEnumerable<IRule> GetRules()
 {

      yield return new Rule1(new Writer1());
      yield return new Rule2(new Writer2());
      //...etc

 }

L'utente della funzione deciderà se desidera tutte le regole contemporaneamente o se vuole pigramente.

Aggiornamento

Le altre soluzioni hanno menzionato la memorizzazione nella cache: se hai bisogno di / vuoi la memorizzazione nella cache, questa soluzione non funzionerà.

    
risposta data 12.05.2015 - 11:59
fonte

Leggi altre domande sui tag