Ich habe in letzter Zeit Clean Code und verschiedene Online-Artikel über SOLID gelesen. Je mehr ich darüber lese, desto mehr habe ich das Gefühl, nichts zu wissen.
Angenommen, ich erstelle eine Webanwendung mit ASP.NET MVC 3. Angenommen, ich habe eine UsersController
mit einer Create
Aktion wie dieser:
public class UsersController : Controller
{
public ActionResult Create(CreateUserViewModel viewModel)
{
}
}
Bei dieser Aktionsmethode möchte ich einen Benutzer in der Datenbank speichern, wenn die eingegebenen Daten gültig sind.
Nach dem Prinzip der Einzelverantwortung sollte ein Objekt nun eine Einzelverantwortung haben, und diese Verantwortung sollte vollständig von der Klasse eingekapselt werden. Alle seine Dienstleistungen sollten eng an dieser Verantwortung ausgerichtet sein. Da Validierung und Speichern in der Datenbank zwei separate Verantwortlichkeiten sind, sollte ich eine separate Klasse erstellen, um sie wie folgt zu behandeln:
public class UsersController : Controller
{
private ICreateUserValidator validator;
private IUserService service;
public UsersController(ICreateUserValidator validator, IUserService service)
{
this.validator = validator;
this.service= service;
}
public ActionResult Create(CreateUserViewModel viewModel)
{
ValidationResult result = validator.IsValid(viewModel);
if (result.IsValid)
{
service.CreateUser(viewModel);
return RedirectToAction("Index");
}
else
{
foreach (var errorMessage in result.ErrorMessages)
{
ModelState.AddModelError(String.Empty, errorMessage);
}
return View(viewModel);
}
}
}
Das macht etwas Sinn für mich, aber ich bin nicht sicher , dass dies der richtige Weg , um Griff Dinge wie diese. Es ist beispielsweise durchaus möglich, eine ungültige Instanz von CreateUserViewModel
an die IUserService
Klasse zu übergeben. Ich weiß, dass ich die integrierten DataAnnotations verwenden könnte, aber was ist, wenn sie nicht ausreichen? Bild, das ich in ICreateUserValidator
der Datenbank überprüfe, um festzustellen, ob es bereits einen anderen Benutzer mit demselben Namen gibt ...
Eine andere Möglichkeit besteht darin, IUserService
die Validierung wie folgt durchführen zu lassen :
public class UserService : IUserService
{
private ICreateUserValidator validator;
public UserService(ICreateUserValidator validator)
{
this.validator = validator;
}
public ValidationResult CreateUser(CreateUserViewModel viewModel)
{
var result = validator.IsValid(viewModel);
if (result.IsValid)
{
// Save the user
}
return result;
}
}
Aber ich habe das Gefühl, dass ich hier gegen das Prinzip der Einzelverantwortung verstoße.
Wie soll ich mit so etwas umgehen?
user
Klasse die Validierung nicht durchführen? SRP oder nicht, ich verstehe nicht, warum dieuser
Instanz nicht wissen sollte, wann sie gültig ist oder nicht, und verlasse mich auf etwas anderes, um dies zu bestimmen. Welche anderen Aufgaben hat die Klasse? Wenn sichuser
Änderungen ändern, ändert sich wahrscheinlich die Validierung. Wenn Sie diese also an eine andere Klasse auslagern, wird nur eine eng gekoppelte Klasse erstellt.