Saya telah membaca Kode Bersih dan berbagai artikel online tentang SOLID belakangan ini, dan semakin saya membaca tentangnya, semakin saya merasa tidak tahu apa-apa.
Katakanlah saya sedang membangun sebuah aplikasi web menggunakan katakanlah ASP.NET MVC 3. Mari saya memiliki UsersController
dengan Create
tindakan seperti ini:
public class UsersController : Controller
{
public ActionResult Create(CreateUserViewModel viewModel)
{
}
}
Dalam metode tindakan itu saya ingin menyimpan pengguna ke database jika data yang dimasukkan valid.
Sekarang, menurut Prinsip Tanggung Jawab Tunggal, sebuah objek harus memiliki tanggung jawab tunggal, dan tanggung jawab itu harus sepenuhnya dienkapsulasi oleh kelas. Semua layanannya harus selaras dengan tanggung jawab itu. Karena validasi dan penyimpanan ke database adalah dua tanggung jawab terpisah, saya kira saya harus membuat kelas terpisah untuk menangani mereka seperti ini:
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);
}
}
}
Yang membuat beberapa akal bagi saya, tapi saya sama sekali tidak yakin bahwa ini adalah cara yang tepat untuk menangani hal-hal seperti ini. Hal ini misalnya sepenuhnya mungkin untuk melewati sebuah instance valid dari CreateUserViewModel
ke IUserService
kelas. Saya tahu saya bisa menggunakan DataAnnotations bawaan, tetapi bagaimana ketika itu tidak cukup? Gambar yang saya ICreateUserValidator
periksa database untuk melihat apakah sudah ada pengguna lain dengan nama yang sama ...
Pilihan lain adalah membiarkan IUserService
validasi seperti ini:
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;
}
}
Tetapi saya merasa saya melanggar Prinsip Tanggung Jawab Tunggal di sini.
Bagaimana saya harus berurusan dengan hal seperti ini?
user
kelas menangani validasi? SRP atau tidak, saya tidak melihat mengapauser
instance tidak harus tahu kapan valid atau tidak dan bergantung pada sesuatu yang lain untuk menentukan itu. Apa tanggung jawab lain yang dimiliki kelas? Ditambah ketikauser
perubahan validasi mungkin akan berubah, jadi outsourcing yang ke kelas yang berbeda hanya akan membuat kelas yang digabungkan secara ketat.