Approccio all'architettura di sviluppo software

0

Sto pianificando di standardizzare il nostro modo di creare progetti per i nostri nuovi progetti.

Attualmente stiamo usando l'architettura 3tier dove abbiamo il nostro Progetto ClassLibrary dove include il nostro livello di accesso ai dati e il livello aziendale

Qualcosa come:

   Solution ClassLibrary 
     >ClassLibrary Project :
          >DAL(folder)
               > DAL Classes
          >BAL(folder)
               > BAL Classes

E questa dll della libreria di classi era riferimento alla nostra presentazione Layer Project che è l'applicazione (web / desktop)

Qualcosa come:

     Solution WebUniversitySystem 
     >Libraries(folder)
          > ClassLibrary.dll
     >WebUniversitySystem(Project):
          >Reference ClassLibrary.dll 
          >Pages etc...

Ora ho intenzione di fare qualcosa di simile:

 Solution WebUniversitySystem 
     >DataAccess(Project)
     >BusinesLayer(Project)
          >Reference DAL
     >WebUniversitySystem(Project):
          >Reference BAL
          >Pages etc...

Va bene? O c'è un buon approccio che possiamo seguire?

    
posta john ryan 06.09.2012 - 04:15
fonte

2 risposte

1

È un approccio abbastanza buono. Hai separato le preoccupazioni in progetti e hai fatto riferimento ai progetti in cui sono utilizzati. Va bene.

Dato che hai taggato questo Visual Studio, ho intenzione di condividere come strutturo i miei progetti software .NET.

In genere avrò questi tre progetti, ciascuno contenuto in una singola soluzione di Visual Studio ( .sln ):

PointOfSale
|
|--PointOfSale.Domain (*A class library project. Typically Entity Framework models etc.*)
|
|--PointOfSale.WebUI  (*The UI project. Could be MVC3, or WPF, or whatever. Presentation.*)
|
|--PointOfSale.Tests  (*The unit testing project. I place all my tests in here.*)

Per quanto riguarda i riferimenti tra i progetti, il progetto .Domain viene fatto riferimento sia nel progetto dell'interfaccia utente che nel progetto di test.

    
risposta data 06.09.2012 - 05:01
fonte
0

La mia critica principale del tuo approccio sarebbe, non rendere il tuo BL direttamente dipendente dal tuo DAL, metti uno strato di riferimento indiretto nel loro dove il BL riceve il DAL tramite IOC o IPC (che è fondamentalmente una forma di IOC) Quindi i consumatori del tuo BL potranno scegliere cosa otterrà il DAL; Se il consumatore fa un test unitario dà un DAL finto, se il consumatore è un cliente fastidioso per qualche ragione usa un CSV DAL che odi mantenere, ma per la maggior parte dei consumatori al BL viene assegnato un DAL di grandi dimensioni per uso aziendale e circa il 20% dei consumatori implementati sono il livello di presentazione delle versioni mobili che dà al BL quel DAL in memoria.

Sono un fan personale di avere un blocco condiviso di modelli di dati, 2 BL, un DAL e un livello di presentazione nel pattern MVC.

Perché 2 BL? C'è sempre un corpo di logica che vive al livello DAL per tradurre in realtà i dati richiesti in un modello di dati, e ancora più complessità al contrario, soprattutto se si ha una qualche forma di memorizzazione nella cache. Di solito le persone incorporano tutto questo nel loro DAL ma finiscono per pagare una penalità di mantenimento che non avrebbero dovuto se facessero uno strato separato sopra il DAL che riceve i componenti DAL in CIO e completa la logica.

L'altro BL dovrebbe, a mio parere, essere idempotente in un paradigma funzionale con effetti collaterali minimi o eventuali, gli effetti collaterali sono ciò che il dal è per.

Quindi il grafico delle dipendenze sarebbe (layer: cose da cui dipende):

DataModels: nothing
DAL: nothing
DALInterfaces: nothing
DALBL: DALInterfaces, DataModels
DALBLInterfaces: DALInterfaces, DataModels
BL: DataModels
BLInterfaces: DataModels
Presentation: DataModels, *Interfaces, some IOC framework or service client framework that turns the interfaces into concrete implementations.

Quindi l'uso è tale che nella tua presentazione faresti cose come:

public MenuOption[] GetMenuOptions(string username, string password)
{
    DataModels.User currentUser = _securityBl.GetUserFromThread(Thread.CurrentThread);
    // remember no side effects in BL layer, just works from inputs, so needs be told the thread
    return _usersDalBl.GetMenuOptionsForUser(currentUser);
    // this dalBl was given a concrete Dal at construction, again
    // no *direct* side effects, only the dal it's accessing has the code with side effects
}

Nota, questo rende il più alto livello (che dovrebbe essere il più sottile e privo di sostanza) il più altamente dipendente, tuttavia penso che questo abbia senso, il suo scopo principale è quello di legare insieme qualsiasi elemento di funzionalità di cui ha bisogno, mentre tutte le funzionalità si trovano in realtà nelle librerie sottostanti.

I pezzi dell'interfaccia esistono solo per il test delle unità tanto quanto qualsiasi cosa, anche se la modularità può sempre essere necessaria in seguito. La mia preferenza è che IPC sia usato per accedere almeno a BL, così come a DAL, anche se dovrebbe essere un'interfaccia IPC più sicura. La forma di IPC è irrilevante, potrebbe essere solo un file mappato in memoria o altro. Penso solo che sia un limite importante mantenere l'indipendenza per quel tempo dopo, quando qualcuno scrive un DAL migliore del tuo e tutto ciò che devi fare è eseguire il loro processo DAL invece del tuo. Anche se forse sono solo un toccasana per IPC, è quasi necessario se sai che sarai in grado di mantenere i confini tra gli strati senza bisogno di protezioni per salvaguardare da incidenti / errori / altre persone.

    
risposta data 06.09.2012 - 05:26
fonte