Non so esattamente se stò parlando della tecnica degli N-Tiers (che conosco poco) ma da quanto ho potuto leggere credo di si.
Vorrei porvi un problema che più che tecnico è logico e vorrei discutere con voi di come risolverlo.
Ho una procedura dove i dati vengono gestiti su un Database. --> Primo strato
Ho creato una serie di classi in diversi assembly che mi permettono di gestire in modo mirato le mie tabelle. --> Secondo strato (che idealmente è la DAL)
Ho creato delle classi che gestiscono le entità logiche del mio programma (ad esempio Clienti, Fornitori, Articoli, Ordini, ecc...) con proprietà, divisi in collection e classi "base" e altre classi che gestiscono la logica di Business. --> Terzo strato
Ho implementato nel programma l'interfaccia utente con Forms, Controlli, ecc... che prendono i dati dalle varie classi di entità. --> Interfaccia utente
Il problema ce l'ho nel Terzo strato.
Mettiamo che ho una classe Cliente con relative proprietà (Nome, Cognome, Codice Fiscale, Partita IVA, ecc...) ed una classe collection (Clienti) dove istanzio un oggetto cliente per ogni occorrenza. Questi dati vengono presi dal secondo strato (metodi che leggono dal DB e mi restituiscono degli oggetti ed io faccio il parsing agli oggetti entità).
Quello che vorrei fare è tenere completamente separati questi strati (a livello logico), cioè non vorrei referenziare assembly del secondo strato nel terzo. In parte ci sono riuscito utilizzando un assembly dove creo delle interfacce implementate nel secondo strato e utilizzate nel terzo.
Quello che non riesco a fare è passare i dati in modo trasparente (senza referenziare assembly del secondo strato nel terzo). Esempio pratico:
Ho 2 interfacce:
Public Interface ICliente
ReadOnly Property Codice() As String
ReadOnly Property RagioneSociale() As String
ReadOnly Property Indirizzo() As String
ReadOnly Property CAP() As String
ReadOnly Property Localita() As String
ReadOnly Property Provincia() As String
'... ecc...
End Interface
Public Interface IClienti
Function GetClienti() As ICliente()
End Interface
Queste intefacce le implementto nelle classi del secondo strato
Public Class ClientiDB
Implements GPDCommon.IClienti
Public Function GetClienti() As ICliente() Implements IClienti.GetClienti
'Recupero i dati dal DB
End Function
End Class
Nel terzo strato le uso in questo modo:
Public Class Cliente
Private _cliente As ICliente
Public Sub New(ByVal cli As ICliente)
_cliente = cli
End Sub
Public ReadOnly Property Codice() As String
Get
Return _cliente.Codice.ToString.Trim
End Get
End Property
Public ReadOnly Property RagioneSociale() As String
Get
Return _cliente.RagioneSociale.ToString.Trim
End Get
End Property
'... ecc...
End Class
Public Class Clienti
Inherits CollectionBase
Private _clientiDB As IClienti
Sub New()
_clientiDB = New ClientiDB '<---PROBLEMA
Popola()
End Sub
Private Sub Popola()
For Each cl As ICliente In _clientiDB.GetClienti
Me.List.Add(New Cliente(CType(cl, ICliente)))
Next
End Sub
'... ecc...
End Class
Come vedete (dove ho scritto '<--- PROBLEMA') ho dovuto referenziare un oggetto presente nel secondo strato della logica così lego strettamente i 2 strati e ho problemi a riutilizzare il codice.
Qual'è la tecnica corretta per non incappare in questo problema? Ho pensato di aggiungere uno strato ma poi mi ritrovo sempre nello stesso problema.
Ho sbagliato qualcosa nella logica impostata? Da quanto ho capito le classi collection andrebbero in uno strato intermedio fra entità e DAL però sono anche loro entità vere e proprie.
Cosa ne pensate?
--------------
Maurizio Brini
--------------
Nessuna impresa è mai stata compiuta da un uomo ragionevole