ฉันอ่านClean Codeและบทความออนไลน์มากมายเกี่ยวกับ SOLID เมื่อเร็ว ๆ นี้และยิ่งฉันอ่านมากเท่าไหร่ฉันก็ยิ่งรู้สึกว่าไม่รู้อะไรเลย
สมมติว่าผมสร้างโปรแกรมประยุกต์บนเว็บโดยใช้ ASP.NET MVC 3. สมมติว่าผมมีUsersController
กับCreate
การกระทำเช่นนี้
public class UsersController : Controller
{
public ActionResult Create(CreateUserViewModel viewModel)
{
}
}
ในวิธีการกระทำนั้นฉันต้องการบันทึกผู้ใช้ไปยังฐานข้อมูลหากข้อมูลที่ป้อนนั้นถูกต้อง
ตอนนี้ตามหลักการความรับผิดชอบเดี่ยววัตถุควรมีความรับผิดชอบเดียวและความรับผิดชอบนั้นควรถูกห่อหุ้มทั้งหมดโดยชั้นเรียน บริการทั้งหมดของ บริษัท ควรสอดคล้องกับความรับผิดชอบนั้น เนื่องจากการตรวจสอบความถูกต้องและการบันทึกลงในฐานข้อมูลเป็นความรับผิดชอบที่แยกกันสองอย่างฉันจึงควรสร้างคลาสแยกต่างหากเพื่อจัดการกับสิ่งเหล่านี้:
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);
}
}
}
ที่ทำให้บางคนรู้สึกถึงฉัน แต่ฉันไม่ได้เลยแน่ใจว่านี้เป็นวิธีที่เหมาะสมในการจัดการกับสิ่งเช่นนี้ มันเป็นตัวอย่างที่เป็นไปได้ทั้งหมดจะผ่านอินสแตนซ์ที่ไม่ถูกต้องCreateUserViewModel
ไปที่IUserService
ระดับ ฉันรู้ว่าฉันสามารถใช้การสร้าง DataAnnotations ได้ แต่จะทำอย่างไรเมื่อมีไม่เพียงพอ ภาพที่ฉันICreateUserValidator
ตรวจสอบฐานข้อมูลเพื่อดูว่ามีผู้ใช้รายอื่นที่มีชื่อเดียวกันอยู่แล้ว ...
อีกทางเลือกหนึ่งคือให้IUserService
การตรวจสอบเป็นดังนี้:
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;
}
}
แต่ฉันรู้สึกว่าฉันละเมิดหลักการความรับผิดชอบเดี่ยวที่นี่
ฉันจะจัดการกับสิ่งนี้ได้อย่างไร
user
คลาสไม่ควรจัดการกับการตรวจสอบหรือไม่ SRP หรือไม่ฉันไม่เห็นสาเหตุที่user
อินสแตนซ์ไม่ควรทราบเมื่อมันถูกต้องหรือไม่และพึ่งพาอย่างอื่นเพื่อตรวจสอบว่ามัน ชั้นเรียนมีความรับผิดชอบอื่นใดอีกบ้าง? และเมื่อuser
การเปลี่ยนแปลงการตรวจสอบอาจมีการเปลี่ยนแปลงดังนั้นการเอาต์ซอร์ซไปยังคลาสอื่นจะสร้างคลาสที่คู่กันอย่างแน่นหนาเท่านั้น