Accesso al livello aziendale del livello dati

0

Ho un livello aziendale (BL) e un livello dati (DL). Ho un oggetto o con una collezione di oggetti figlio di Tipo C. Vorrei fornire una semantica come la seguente o.Children.Add ("informazioni"). Nel BL mi piacerebbe avere una CLASS statica che tutte le classi del livello aziendale usano per ottenere un riferimento all'istanza del datalay corrente. C'è qualche problema con questo o devo usare il modello factory per limitare la creazione alla classe A nel BL che conosce l'istanza DL.

  Fammi chiarire. In passato, quando definivo DL, creo un IDL di interfaccia implementato dal DL. Gli unici oggetti che permetto di creare dalla mia BL sono le fabbriche che nei loro costruttori prendono un riferimento all'IDL

IE

   IDL idlRef = new DataLayer();  
   IBlFactory iFac = new BLFactory(IDL);
   IBLa = IBlFactory.Geta(...);

Dal momento che ho provato a far funzionare statica e singleton dal mio sistema, la mia fabbrica crea tutti gli oggetti e passa sempre il riferimento dell'IDL ai nuovi oggetti. Alcuni membri del mio team si sono lamentati del mio uso copioso di interfacce e fabbriche e vorrebbero utilizzare lezioni concrete direttamente dal BL.

Quindi il problema è che se si dispone di un oggetto che può essere creato in IE un nuovo oggetto è meglio tagliato utilizzando la fabbrica. IE

IBLA oBLA = iFac.GetBLA();

o costringere il cliente a passare sempre il riferimento al DL al nuovo oggetto. IE    BLA oBLA = nuovo BLA (idlRef);

o la testabilità potrebbe essere realmente danneggiata dall'avere una proprietà statica nel BL.

Static IDL CurrentDL;

Permettere, anche se con qualche rotture di incapsulamento, uno stile più succinto Assumendo che ogni oggetto BL sappia quale sia l'attuale DL.

    
posta rerun 02.03.2011 - 00:29
fonte

4 risposte

5

Questo è uno scenario comune, quindi proverò a rispondere in modo riutilizzabile.

I problemi con le classi statiche sono:

  1. rendono difficile il test (a causa della loro capacità di mantenere lo stato tra i test)
  2. non possono essere scambiati con una versione specifica per test isolata
  3. rendono difficile il cambio dell'implementazione predefinita con una diversa (nota che è uguale a # 2).
  4. ogni chiamata richiede il nome della classe

Se potessi fornire un'istanza di - chiamiamola un EntityManager (la maggior parte degli ORM ha questa classe) nel costruttore, sarebbe meglio. Assicurati di dargli un'interfaccia e facci riferimento nel livello aziendale solo attraverso tale interfaccia.

L'unica differenza tra questa e la tua classe statica sarebbe quella:

  • viene passato al costruttore delle classi del livello aziendale
  • può essere testato
  • la classe del livello aziendale la conosce solo dal nome dell'interfaccia (non dal nome della classe), in modo che il livello dati possa essere sostituito con uno nuovo (anche in fase di esecuzione) che è molto potente quando non si desidera interrompere vecchio codice

Una cosa che ho imparato più di recente durante l'esecuzione di codice che "non sembra giusto": prova TDD o leggi alcune linee guida su come rendere il tuo codice più testabile - spesso ti indirizza nella giusta direzione.

    
risposta data 02.03.2011 - 01:13
fonte
0

Consiglierei di stare lontano dalle classi statiche, sono stato io stesso in questa direzione e rende tutto più difficile sia testare che implementare

    
risposta data 02.03.2011 - 00:50
fonte
0

Sembra (anche se è molto astratto) che tu stia cercando di implementare un qualche tipo di livello dati ORM. A seconda del tuo ambiente, utilizzerei solo un'implementazione esistente come NHibernate per java, django per python o active record per ruby, ecc. Progettare un ORM non è un semplice atto nel design del software: perché inventare la ruota?

    
risposta data 02.03.2011 - 00:58
fonte
0

Sembra che tu stia assumendo una dipendenza dal tuo livello dati nel tuo livello aziendale, ma non vuoi quella dipendenza diretta. In questo caso, crea un livello "Core" separato che contiene una definizione di interfaccia per il tuo livello dati (IDataLayer) e applicalo al tuo livello dati corrente. Si può finire con il codice che (in C # .Net) assomiglia a:

public class BusinessLayer {

  private IDataLayer _DataLayer;

  public BusinessLayer(IDataLayer dataLayer) { 
      _DataLayer = dataLayer;
  }

}

In questo modo, puoi inserire la definizione del livello dati appropriata nel tuo livello aziendale. In genere, ciò avviene tramite la funzione di costruzione che utilizza una tecnica chiamata "Constructor Injection"

Per ulteriori informazioni sull'iniezione di dipendenza: link

L'iniezione di dipendenza viene ora eseguita mediante l'uso di uno strumento Iniezione di dipendenza o di Inversion of Control (IoC). Un elenco di contenitori per .Net può essere trovato all'indirizzo: link

    
risposta data 02.03.2011 - 01:43
fonte

Leggi altre domande sui tag