Una domanda per esperti di OOP e Presentation/Business/DB layer

sabato 13 giugno 2009 - 15.47

arguros Profilo | Newbie

Ciao,

In alcuni libri di programmazione orientata agli oggetti che si occupano di dividere il programma in tre layer
Presentation/Business/DB ho visto questo approccio.

Business Layer

Class Customer
ID
Nome
Cognome
GetCustormer
Save
Upload

end

DB LAYER

Class CustomerDB

GetCustomer
Save
Upload
end

in cui Customer risiede nel business Layer e CustomerDB nel DB Layer.
La classe Customer delega a CustomerDB i metodi GetCustomer, Save, Upload.

Io non sono un esperto di programmazione ad ogetti, ma mi potreste spiegare la logica di questa soluzione?
Io vedo i seguenti problemi
1) Incorporando un istanza di CustomerDB in Customer, non si riesce a separare il Business Layer dal DBLayer,infatti per compilare Business Layer si richiederebbe una referenza a CustomerDb.
2) L'ogetto Customer acquisa delle propriea che non sono tipiche di un Customer (Save, Upload, GetCustomer)
3) L'ogetto Customer divente thigtly coupled con CustomerDB.

Quello che farei io e' il seguente

Class Customer
ID
Nome
Cognome
end

Class CustomerDB
Customer GetCustomer(ID)
SaveCustomer(Customer)
UplodCustoer(Customer)

end

Chiaramente con tale soluzione il Presentation Layer dovrebbe utilizzare contemporaneamente sia Customer che CustomerDB, (la qual'cosa non mi piace), pero il Business Layer e' completamente separato sia dall' interfaccia sia dal DB.
Cosa ne pensate? Come faccio a farsi che il Business Layer si compili da solo, e il presentation Layer Non dipenda da DB Layer?

Grazie

Pierpaolo

freeteo Profilo | Guru

Ciao,
per fare questo, devi referenziare il business layer e le entità, non devi referenziare la classe del db, altrimenti hai bucato tutti i pattern
Ed anche il business layer non deve referenziare direttamente l'implementazione del provider per i dati, ma piuttosto dovresti lavorare con Interfacce per dare conoscenza di "cosa" può/deve fare una classe, ma non specificatamente come viene implementato:
http://msdn.microsoft.com/en-us/library/87d83y5b(VS.80).aspx

a quel punto ovviamnete ti serve una libreria per le interfacce in modo che venga referenziata sia dallo strato data (che deve implementarla e quindi fare il codice specifico) e sia dallo strato Business (che deve sapere cosa sta utilizzando per accedere ai dati).
Quest'ultimo si preoccupa di caricare la classe che implementa quell'Interfaccia tramite "Factory":
http://msdn.microsoft.com/en-us/library/ms954600.aspx
Questo argomento è stato già discusso in questo post: http://www.dotnethell.it/forum/messages.aspx?ThreadID=26377

Poi se vuoi puoi separare anche il business layer, ma spesso non serve...io solitamente mi accontento della separazione del database e per la maggior parte delle volte mi basta...

Ciao.

Matteo Raumer
[MVP Visual C#]
http://blogs.dotnethell.it/freeteo

arguros Profilo | Newbie

Ciao Matteo,

Grazie per la risposta.
Avrei un'altra piccola domanda per quanto riguarda le entita.
Anche queste ovviamente sono in comune ai due layer, al business servono per ricevere i dati, mentre ad Db per trasmetterli.
Tu dove li definiresti? Ad occhio a me il posto piu' appropriato sembrerebbe a questo punto la libreria che definisce le interfacce di accesso al Database.
Inoltre gli ogetti del business layer hanno bisogno di istanze concrete delle interfaccie a cui si riferiscono.
Tu per questo suggerisci il factory pattern.Ma non ci riduciamo al punto di prima, in cui abbiamo
1) of una factory che appartiene al business layer che istanzia un concreto DB Object
2) o una factory che appartiene a DB Layer che viene referenziata nello user layer?
Segue un breve esempio che spiega il punto.



Esempio

----------------------------------------------------
Interface Libray
---------------------------------------------------
//Entita'
Class ClientDetails {
string ID
string Name
string Surname
}
//Interfacce
interface IClientDB {

ClientDetails GetClientDetails(ID)
void SaveClientDetais(ClientDetails)
}
----------------------------------------------------------------
DB Layer, use interface Libary
----------------------------------------------------------------


Class ClientDB : IClientDB {
ClientDetails GetClientDetails(ID) {
some code goes here...
}
void SaveClientDetais(ClientDetails){
some code goed here...
}

}

------------------------------------------
Business Layer, use interface Library. La classe concreta la passo nel constructor
----------------------------------------

Class Client(IClientDB clientDB) {
string ID
string Name
string Surname

Save() {
cd = new ClientDetails();
cd.ID = this.ID
cd.Name = this.Name
cd.Surname = this.Surname
clientDB.Save(ClientDetails)
}

Load(ID) {
ClientDetails cd = new ClientDetails();
cd = clientDB.Load(ID)
.....
}
------------------------------------------------------------
Factory Method. Non so dove metterlo, DB of Business Layer?
----------------------------------------------------
Class ClientFactory
Client Create(){
return new Client(new ClientDB)
}
end


-------------------------------------------------------------
user code
-------------------------------------------------------
Qui viene problema. Se la factory e' nel DB, lo user Layer usa il DB Layer (cosa che non vogliamo)
Se la factory e' nel Businees abbiamo un referenca ad una classe concreta (new ClientDB) e rompiamo la separazione
Client c = ClientFactory.Create()
c.Load(ID);
c.Name = "mario";
c.Save();
Partecipa anche tu! Registrati!
Hai bisogno di aiuto ?
Perchè non ti registri subito?

Dopo esserti registrato potrai chiedere
aiuto sul nostro Forum oppure aiutare gli altri

Consulta le Stanze disponibili.

Registrati ora !
Copyright © dotNetHell.it 2002-2024
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5