2009-02-20 16 views
6

Sto implementando un Data Access Layer (DAL), che è fondamentalmente un insieme di classi con funzioni condivise (VB.NET) per eseguire effettivamente le chiamate del database (CRUD). Sto cercando di capire il posto migliore in cui collocare le chiamate al DAL all'interno della gerarchia di classi. Lasciatemi fare un esempio.OOP - Dove mettere le chiamate al Data Access Layer?

Supponiamo di avere un cliente di classe, con solo ID standard, nome, indirizzo1, proprietà ecc. E forse una funzione ToString sostituita. Ho anche una classe DAL con modalità condivise, come ad esempio:

(pseudocode) 

Namespace Dal 

Public Class Customer 

Public Shared Function Read(id As Integer) As Customer 

Public Shared Function ReadList() As List(Of Customer) 

Public Shared Sub Create(c As Customer) 

'etc. 

Ora, ho potuto chiamare il Dal dallo strato di presentazione in questo modo:

Me.DataGridView1.Datasource = Dal.Customer.ReadList 

Tuttavia, non è una buona pratica di il livello di presentazione è a conoscenza del Dal? Dovrei invece mettere i metodi nell'oggetto Cliente e chiamare il Dal, come questo?

Public Function ReadList() As List(Of Customer) 
    Return Dal.Customer.ReadList() 
End Sub 

Public Sub Create() 
    Dal.Customer.Create(Me) 
End Sub 

Questo dovrebbe essere "più pulito" OOP? O è pratica accettabile lasciare che la presentazione chiamare il Dal, passando gli oggetti di business come il mio precedente esempio:

Me.DataGridView1.Datasource = Dal.Customer.ReadList 

Dim c As New Customer 
c.Name = "Alpha Corporation" 
c.Address1 = "123 Main Street" 
Dal.Customer.Create(c) 

Grazie per il tuo feedback.

risposta

2

Accetto che le chiamate dati non appartengano a un livello dell'interfaccia utente. Quelli sono solo per presentazione.

Penso che appartengano correttamente a un livello di servizio. L'implementazione del servizio utilizza gli oggetti del modello e il livello di persistenza per raggiungere i propri obiettivi. Che si tratti di un servizio Web basato su XML o di un'interfaccia locale, il servizio è l'oggetto che mappa per utilizzare i casi e conosce le unità di lavoro.

O inserire le chiamate al database in un livello di persistenza separato o incorporarle negli oggetti del modello per purezza extra orientata agli oggetti.

+0

Tutti e tre gli intervistati hanno dato grandi risposte, ma devo sceglierne una corretta. Grazie a tutti! – HardCode

4

Quanto meno l'applicazione conosce il DAL, tanto meglio. Ci sono diversi modi per farlo e penso che tu sia sulla strada giusta. Penso che potresti voler esaminare lo factory pattern per questa implementazione dato che sarai in grado di nascondere l'implementazione DAL dietro la fabbrica e restituire entità e raccolte di entità dalla fabbrica.

+0

Quindi, la fabbrica si posizionerebbe tra il DAL e il livello di presentazione, con i metodi di chiamata del livello di presentazione in fabbrica? È lo stesso del livello di servizio a cui fa riferimento duffymo? – HardCode

+0

Sort of - il modello factory è solo un pattern - può essere implementato sotto forma di livello di servizio, se lo si desidera. –

1

Il motivo per cui si desidera eseguire le operazioni CRUD in un livello separato è nel caso in cui si desideri modificare i sistemi di database. Bene, è per questo che l'ho fatto. Non consiglierei di farlo solo per essere un buon OOD. Ma qui ya go ...

Diversi gruppi di classi/interfacce

BusinessObject - Rappresenta tipo entità aziendali come ad esempio un cliente, ha DataManager come una proprietà.

DataManager - Forse si può trovare con un nome migliore, ma questa cosa fornisce funzioni di Save() Load() e per le BusinessObjects

SearchList - Consegna liste di cose, le query SQL andare qui. Anche questo dovrebbe probabilmente comportarsi come un RecordSet con membri di tipo Next(), Eof() e CurrentRecord

Costruttore/Fabbrica - Vedere FactoryPattern. Hai disaccoppiato le operazioni del tuo database dai tuoi oggetti di business questa cosa li ri-accoppia in un modo necessario.Assegna un'implementazione Datamanager appropriata a BusinessObject

Trova qualsiasi nome effettivo desideri, ma parliamo di nuovo del Cliente. Supponiamo di avere un database Oracle. Si potrebbe finire con queste classi:

boCustomer che eredita da BusinessObject

oracleDMCustomer che eredita o implementa DataManager

searchlistCustomer che eredita dalla searchlist che ha esposto sia attraverso metodi astratti o come qualcosa di un'interfaccia simile:

  • searchall() - che dovrebbe restituire tutti i clienti
  • SearchByZip (String zip), che deve restituire tutti i clienti con un dato codice postale

oracleSearchlistCustomer - implementa searchlistCustomer, sarebbe in realtà l'attuazione del searchall() e SearchByZip()

boFactory - classe statica che ha un metodo che sembra qualcosa di simile CreateObject (tipo Type)

searchlistFactory - classe statica che presenta un metodo simile a CreateSearchList (Type type);

Ti lascio compilare alcuni degli spazi vuoti, ma penso che le cose importanti siano lì. Altri possono avere idee diverse che richiedono meno astrazione. Prendevo in giro diverse strategie prima di andare con una.

+0

Roba buona. Grazie! – HardCode