2009-04-28 5 views
16

Mi interessa percepire le "migliori pratiche", mitigato da una piccola dose di realtà qui.Consenti al livello Web di accedere direttamente al DAL?

In un'applicazione Web, consenti al tuo livello Web di accedere direttamente al DAL o prima di passare a un BLL?

Sto parlando in modo specifico di scenari in cui non esiste realmente una "logica aziendale", ad esempio una semplice query: "Recupera tutti i clienti con il cognome 'Atwood'". Scenari in cui esiste un qualsiasi tipo di logica passeranno assolutamente attraverso il BLL, quindi chiamiamolo allo moo.

Mentre si potrebbe incapsulare questo metodo all'interno di un oggetto BLL, sembra essere un po 'inutile, quando spesso la firma sarà esattamente la stessa di quella dell'oggetto DLL e il codice probabilmente semplice come un delegante uno di linea la query alla DLL.

Se si sceglie il primo - utilizzando un oggetto BLL - come si chiamano questi oggetti? (Supponendo che facciano poco più che fornire un livello di query nella DLL). Helpers? QueryProviders?

Pensieri per favore.

saluti

Marty

+0

Bellissima domanda! –

risposta

4

A mio parere, si dovrebbe SEMPRE utilizzare un BLL (Business Logic Layer) tra il livello Web e il tuo DAL (Data Access Layer).

Mi rendo conto che per alcune delle domande rivolte più "semplici", la BLL da vicino imitare il DAL (ad es Fetch tutti i paesi, Fetch tutti i tipi di prodotto, ecc), ma per onesta, anche nel tuo esempio:

(Fetch tutti i clienti con cognome 'Atwood')

c'è "business logic" espressi qui - Un desiderio per i record di dati da filtrare per cognome, se non altro!

Implementando un BLL dall'inizio di un progetto diventa incredibilmente facile inserire o la validazione o la "logica" aggiuntiva come e quando può sorgere l'esigenza (e se il progetto è un'applicazione commerciale, tale necessità sarà quasi pari a sorge alla fine se non è lì all'inizio del progetto). L'aggiunta di logica aggiuntiva come ad esempio:

recuperare tutti i clienti che hanno speso oltre 10000 $ di quest'anno

o

Non consentire ai clienti con il cognome di 'Atwood' di acquistare oggetti su $ 1000

diventa significativamente più semplice quando è coinvolto un vero BLL, piuttosto che tentare di introdurre questa logica nel livello Web.

Si tenga presente che con il tipo di query di cui sopra, stiamo quasi certamente parlando di entità multiple e tabelle di database che dovranno unirsi con i rapporti specificamente definiti al fine di implementare questa funzionalità. Cercare di ottenere questo risultato manipolando direttamente il DAL diventa complicato poiché ti occuperai di più entità e classi. Un BLL qui semplificherebbe notevolmente il tuo codice di livello Web, dal momento che la BLL corrisponderà a encapsulate di quelle relazioni di entità dietro un'interfaccia notevolmente semplificata.

Questo "separation of concerns" diventa sempre più importante quando e se si presenta la necessità di cambiare l'interfaccia utente.

In almeno due occasioni separate ora, ho lavorato su applicazioni web commerciali con un'interfaccia utente del sito web, e sono stati infine chiesto (a causa di esigenze di business derivanti da clienti che cercano una maggiore integrazione all'interno dei loro prodotti software) per la produzione di un'interfaccia web service che offre la stessa identica funzionalità del sito web.

Se avessi incorporato qualsiasi logica di business all'interno del mio livello Web, avrei dovuto duplicare e riscrivere quella logica quando implementavo il mio servizio web. In effetti, mi sono assicurato che tutta la logica aziendale fosse incapsulata all'interno delle classi BLL, il che significava che dovevo semplicemente progettare una serie di chiamate al metodo dell'interfaccia del servizio web e collegarle alle chiamate ai metodi sulle classi BLL (in realtà usavo il Facade Design Pattern in luoghi per semplificare l'API del servizio Web).

In totale, non riesco a pensare a NON includere un livello BLL tra il mio DAL e il mio livello Web.

Al modo più semplice, quando il BLL "imita" il DAL, sì, sembra che ci sia una duplicazione di codice e funzionalità, tuttavia, pur essendo un po 'più di digitazione, questo rende anche relativamente facile da implementare.

Quando è più coinvolto (ad esempio quando esiste una logica aziendale significativa fin dall'inizio), la separazione delle preoccupazioni aiuta a ridurre la ripetizione (il principio DRY) e allo stesso tempo semplifica notevolmente la manutenzione futura e continua.

Naturalmente, questo presuppone che stai facendo tutto questo "a mano". Se lo desideri, puoi semplificare notevolmente i livelli DAL/BLL/UI utilizzando uno ORM di cui ce ne sono molti! (ad esempio LINQ-to-SQL/Entities, SubSonic, NHibernate ecc.)

+1

Penso che l'esempio dell'aggiunta successiva di un servizio Web sulla BLL sia un esempio abbastanza convincente. Grazie! –

+0

Tuttavia, sono curioso del tuo commento su ORM. Sto usando Hibernate nel mio progetto, il che rende il mio DAL piuttosto magro, ma ha ancora dei chiari confini tra i livelli. Era questo il tuo punto, o consideri un'opportunità per combinare BLL e DAL quando usi ORM? –

+0

@Marty - Puoi utilizzare alcuni degli ORM più avanzati per automatizzare DAL e gran parte della BLL, tuttavia, personalmente, se utilizzo un ORM, lascerò che generi automaticamente il mio DAL e scriva personalmente la BLL. In questo modo, mi salva un lavoro a scrivere manualmente il DAL e mi concentro sulla BLL. – CraigTP

1

Anche quando è acceso; y una riga nel BLL si effettua una chiamata simile alla DLL, l'astrazione consente di aggiungere la logica di business in quello strato, senza dover influire su qualsiasi altro livello. Potrebbe non sembrare che questo sia probabile ora, ma chiunque debba supportare l'applicazione dopo ti ringrazierà per aver utilizzato modelli come questo quando i cambiamenti si verificano.

Per quanto riguarda la denominazione, ho il mio oggetto principale, dire una cambio di nome, allora avrò un oggetto BLL che è una persona che accetta un oggetto di modifica del nome, allora avrò un/Entità oggetto DAL chiamato una Persona. L'oggetto business Person si trova all'interno dello spazio dei nomi BLL e l'oggetto DAL/Entity Person si trova nello spazio dei nomi DB (avrei scelto DAL se l'avessi creato in origine).

2

È necessario distinguere gli oggetti BLL (cosa diavolo sono questi? Dominio oggetti nessuno?) E Servizi. I tuoi oggetti di dominio non dovrebbero avere nulla a che fare con il tuo livello di accesso ai dati. Per quanto riguarda il livello web, può trattare i tuoi repository (pensa allo IRepository) proprio come qualsiasi altro servizio che può liberamente utilizzare.

Quindi la linea di fondo è: sì, il livello Web può utilizzare DAL direttamente a condizione che sia incapsulato in proprietà ed è rappresentato come servizio di livello servizio standard.

+0

BLL - Business Logic Layer? –

+0

Sì - BLL == Livello di business logic. Li vedo come separati da (sebbene un'estensione naturale di) il modello di dominio. Se questa è una visione polemica, forse aprirò una nuova domanda per ottenere alcune opinioni. –

+1

So cosa significa BLL. Non posso proprio essere d'accordo con la combinazione "Business Logic" e "Objects" poiché credo fermamente che gli oggetti business dovrebbero essere privi di qualsiasi logica e che la logica dovrebbe essere spostata su un livello di servizio. –

1

Ci riferiamo a questo livello come a una Classe controller [livello] che incapsula il DAL dal livello Web. Il livello controller può o non può avere alcuna logica di business qualunque, aiuta a separare il DAL dal livello di presentazione e mantenerli indipendenti [in una certa misura].

+0

Non è la parte del controller del livello Web? – svirk

0

Abbiamo avuto la tendenza a utilizzare l'facade pattern per l'accesso, sebbene il nostro progetto su cui lo usiamo sia considerevole, penso che potrebbe rivelarsi eccessivo su un progetto più piccolo.

In sostanza:

UI -> BusFacade -> BusinessLogic -> DalFacade -> DataAccessLayer

facciata rende per un approccio bella/pulito dall'interfaccia utente, e le forze di standardizzare sulle convenzioni di denominazione come quel singolo punto di entrata ha un numero di metodi.

BusFacade.GetCmsSiteMap() 
BusFacade.GetProductGroup() 

ecc.ecc.

+0

E in alcuni scenari, vai direttamente a BusFacade -> DalFacade? –

+0

non ha mai fatto niente - anche (come suggerito dal poster precedente) se si tratta solo di un passaggio nel livello aziendale, io continuerei comunque a telefonare per assicurarmi che in futuro ci sia sempre bisogno di cambiamenti, è lì dentro. –

33

Non sono d'accordo con la maggior parte dei post qui.

Io chiamo il mio livello dati nel livello web. Se non c'è nulla tra il livello WEB/UI non è necessario creare un livello "nel caso in cui". È pre-ottimizzazione. È uno spreco. Non riesco a ricordare una volta che il livello aziendale "mi ha salvato". Tutto ciò che ha fatto è stato creato più lavoro, duplicazione e maggiore manutenzione. Ho passato anni ad abbonarmi al Business Layer -> Livello dati passando le entità tra i livelli. Mi sono sempre sentito sporco a passare attraverso metodi che non hanno fatto nulla.

Dopo essere stato introdotto per Domain Driven Design by Eric Evans, faccio ciò che ha senso. Se non c'è nulla tra l'interfaccia utente e il livello dati, chiamo il livello dati nell'interfaccia utente.

per consentire futuri cambiamenti ho involucro tutte le mie classi di livello di Data nelle interfacce. Nell'interfaccia utente, faccio riferimento alle interfacce e utilizzo l'injection dependency per gestire l'implementazione. Dopo aver apportato questi cambiamenti, è stato come una boccata d'aria fresca. Se ho bisogno di iniettare qualcosa tra il livello dati e l'interfaccia utente, creo un servizio.

Un'altra cosa che ho fatto, era ridurre il numero di progetti. Prima avrei un progetto per il livello dati, business logic, entità aziendali e qualche tipo di progetto dell'interfaccia utente - che dolore.

Ho due progetti: il progetto principale (entità, logica aziendale e livello dati) e progetti di interfaccia utente (Web, servizi Web, ecc.)

Per maggiori informazioni vi consiglio di guardare questi ragazzi:

+1

Interessante (e stranamente liberatorio) punto. L'ottimizzazione precoce è rigorosamente anti-agile. Avrei dovuto sapere che c'erano argomenti convincenti su entrambi i lati del recinto ... ora devo prendere una decisione! :) –

+1

Ho fatto anche la cosa del "troppo progetto" e di recente ho pensato "perché diavolo sto facendo questo?" aggiungere riferimenti può essere una quantità ragionevole di overhead a volte +1 –

+1

@Marty - Si noti che mentre Chuck e I stanno utilizzando approcci diversi, entrambi mirano allo stesso obiettivo finale, in particolare una "separazione netta di preoccupazioni" e la capacità di (relativamente) estendere facilmente l'applicazione quando necessario. L'uso di Chuck dell'iniezione delle dipendenze e della programmazione su un'interfaccia lo raggiunge proprio come fa il mio uso di uno strato BLL. – CraigTP

0

Mentre sarebbe possibile andare direttamente dal livello di presentazione a DAL, stai saltando il BLL che spesso richiede l'autenticazione ...