In particolare per il collaudo delle unità, sto cercando di implementare un'applicazione con un'architettura a strati . Sto codificando in C # e utilizzo l'API Web ASP.NET per il livello di servizio. Sto puntando su un'architettura a 3 livelli:
- Livello di servizio
- Livello di logica aziendale
- Livello di accesso ai dati
Il problema
Mi sento a disagio nel dover scegliere tra un DAL di architettura rilassato o classi di BLL anemiche e mi chiedo se sia perché mi sto avvicinando a questo nel modo sbagliato. Quando mi riferisco a "DAL rilassato per architettura", intendo un DAL che può essere chiamato da strati diversi da il BLL direttamente sopra di esso, cioè il livello di servizio.
La mia ragione per non volere un'architettura rilassata DAL: semplifica l'esclusione errata della logica aziendale.
La mia ragione per non volere classi anemiche di BLL: non voglio una pletora di classi che non fanno altro che passare le chiamate tra il livello di servizio e il DAL.
Esempio
Ecco alcuni esempi di codice. Innanzitutto, un metodo del livello di servizio che supporta la registrazione di uno studente in una classe:
public class ClassRegistrationController : ApiController
{
private readonly BusinessLogic.ClassRegistration _classRegistrationLogic;
public ClassRegistrationController(
BusinessLogic.ClassRegistration classRegistrationLogic)
{
_classRegistrationLogic = classRegistrationLogic;
}
[Route("/api/class/{classId}/register")]
[HttpPost]
public IHttpActionResult RegisterForClass(
int classId,
[FromBody]ClassRegistrationRequest registrationRequest)
{
try
{
_classRegistrationLogic.RegisterStudentForClass(
classId,
registrationRequest.StudentId);
}
catch (ClassFullException)
{
return BadRequest("Cannot register for class, it is full");
}
return Ok();
}
}
E la classe della business logic a supporto:
public class ClassRegistration
{
private DataLayer.IClassDataLayer _classDataLayer;
private DataLayer.IClassRegistrationDataLayer _classRegistrationDataLayer;
public ClassRegistration(
DataLayer.IClassDataLayer classDataLayer,
DataLayer.IClassRegistrationDataLayer classRegistrationDataLayer)
{
_classDataLayer = classDataLayer;
_classRegistrationDataLayer = classRegistrationDataLayer;
}
public void RegisterStudentForClass(int classId, int studentId)
{
var classDetails = _classDataLayer.GetClassDetails(classId);
if (classDetails.ClassIsFull)
{
throw new ClassFullException();
}
_classRegistrationDataLayer.AddStudentToClass(classId, studentId);
}
}
Le interfacce del livello dati (l'implementazione non è pertinente alla domanda):
public interface IClassDataLayer
{
Models.ClassDetails GetClassDetails(int classId);
}
public interface IClassRegistrationDataLayer
{
int AddStudentToClass(int classId, int studentId);
}
Ora, io penso tutto ciò sembra ragionevole, e ogni classe ha una sola (e non insignificante) responsabilità. Ma ora diciamo che voglio aggiungere un metodo del livello di servizio che espone i dettagli di una classe, come:
[Route("/api/class/{classId}")]
[HttpGet]
public IHttpActionResult GetClassDetails(int classId)
{
var classDetails = _classDetailsGetter.GetClassDetails(classId);
if (classDetails == null)
{
return NotFound();
}
return Ok(classDetails);
}
La domanda è, sarà _classDetailsGetter
un'istanza di una classe dal DAL o dalla BLL?
Se proviene dal DAL, allora sto dicendo che è "OK" perché il livello di servizio passi direttamente al DAL, il che apre il rischio, ad esempio, di qualcuno che fa manutenzione sul metodo del livello di servizio RegisterForClass
decidendo di andare direttamente a IClassDataLayer
anziché BusinessLogic.ClassRegistration
.
Ma se proviene dalla BLL, allora quella classe BLL sarebbe responsabile solo della mappatura delle chiamate 1-a-1, il che mi fa anche sbagliare. Come:
public class ClassDetailsLogic
{
private readonly DataLayer.IClassDataLayer _classDataLayer;
public ClassDetailsLogic(DataLayer.IClassDataLayer classDataLayer)
{
_classDataLayer = classDataLayer;
}
public Models.ClassDetails GetClassDetails(int classId)
{
return _classDataLayer.GetClassDetails(classId);
}
}
Sommario
C'è motivo di favorire l'architettura rilassata DAL o la BLL anemica? Le mie preoccupazioni riguardo l'una (o l'altra) sono infondate? O c'è qualcos'altro che mi manca?