Situasi
Sebelumnya malam ini saya memberikan jawaban atas pertanyaan di StackOverflow.
Pertanyaan:
Mengedit objek yang ada harus dilakukan di lapisan repositori atau dalam layanan?
Misalnya jika saya memiliki Pengguna yang memiliki hutang. Saya ingin mengubah utangnya. Haruskah saya melakukannya di UserRepository atau dalam layanan misalnya BuyingService dengan mendapatkan objek, mengedit dan menyimpannya?
Jawabanku:
Anda harus meninggalkan tanggung jawab untuk memutasikan suatu objek ke objek yang sama dan menggunakan repositori untuk mengambil objek ini.
Contoh situasi:
class User {
private int debt; // debt in cents
private string name;
// getters
public void makePayment(int cents){
debt -= cents;
}
}
class UserRepository {
public User GetUserByName(string name){
// Get appropriate user from database
}
}
Komentar yang saya terima:
Logika bisnis harus benar-benar dalam layanan. Tidak dalam model.
Apa kata internet?
Jadi, ini membuat saya mencari karena saya tidak pernah (secara sadar) menggunakan lapisan layanan. Saya mulai membaca tentang pola Lapisan Layanan dan pola Unit Kerja tetapi sejauh ini saya tidak bisa mengatakan saya yakin lapisan layanan harus digunakan.
Ambil contoh artikel ini oleh Martin Fowler tentang anti-pola Model Domain Anemik:
Ada objek, banyak yang dinamai dengan kata benda di ruang domain, dan objek ini terhubung dengan hubungan dan struktur kaya yang dimiliki oleh model domain yang sebenarnya. Tangkapan datang ketika Anda melihat perilaku, dan Anda menyadari bahwa hampir tidak ada perilaku pada benda-benda ini, membuat mereka sedikit lebih dari sekantong getter dan setter. Memang sering model-model ini datang dengan aturan desain yang mengatakan bahwa Anda tidak boleh menempatkan logika domain di objek domain. Sebaliknya ada satu set objek layanan yang menangkap semua logika domain. Layanan ini hidup di atas model domain dan menggunakan model domain untuk data.
(...) Logika yang harus ada dalam objek domain adalah logika domain - validasi, perhitungan, aturan bisnis - apa pun yang Anda suka menyebutnya.
Bagi saya, ini persis seperti apa situasinya: Saya menganjurkan manipulasi data objek dengan memperkenalkan metode di dalam kelas yang melakukan hal itu. Namun saya menyadari bahwa ini harus diberikan dengan cara apa pun, dan mungkin lebih berkaitan dengan bagaimana metode ini dipanggil (menggunakan repositori).
Saya juga merasa bahwa dalam artikel itu (lihat di bawah), Layer Layanan lebih dianggap sebagai façade yang mendelegasikan pekerjaan ke model yang mendasarinya, daripada lapisan padat karya yang sebenarnya.
Application Layer [namanya untuk Service Layer]: Menentukan pekerjaan yang seharusnya dilakukan oleh perangkat lunak dan mengarahkan objek domain ekspresif untuk menyelesaikan masalah. Tugas-tugas yang bertanggung jawab atas lapisan ini bermakna bagi bisnis atau diperlukan untuk interaksi dengan lapisan aplikasi sistem lain. Lapisan ini dijaga tetap tipis. Itu tidak mengandung aturan atau pengetahuan bisnis, tetapi hanya mengoordinasikan tugas dan delegasi yang bekerja untuk kolaborasi objek domain di lapisan berikutnya ke bawah. Itu tidak memiliki keadaan yang mencerminkan situasi bisnis, tetapi bisa memiliki keadaan yang mencerminkan kemajuan tugas bagi pengguna atau program.
Yang diperkuat di sini :
Antarmuka layanan. Layanan memperlihatkan antarmuka layanan tempat semua pesan masuk dikirim. Anda dapat menganggap antarmuka layanan sebagai fasad yang memaparkan logika bisnis yang diterapkan dalam aplikasi (biasanya, logika di lapisan bisnis) kepada konsumen potensial.
Dan di sini :
Lapisan layanan harus tanpa aplikasi atau logika bisnis apa pun dan harus berfokus terutama pada beberapa masalah. Seharusnya membungkus panggilan Layer Bisnis, menerjemahkan Domain Anda dalam bahasa umum yang dapat dipahami klien Anda, dan menangani media komunikasi antara server dan klien yang meminta.
Ini sangat berbeda dengan sumber daya lain yang berbicara tentang Lapisan Layanan:
Lapisan layanan harus terdiri dari kelas dengan metode yang merupakan unit kerja dengan tindakan yang termasuk dalam transaksi yang sama.
Atau jawaban kedua untuk pertanyaan yang sudah saya tautkan:
Pada titik tertentu, aplikasi Anda akan menginginkan beberapa logika bisnis. Selain itu, Anda mungkin ingin memvalidasi input untuk memastikan bahwa tidak ada sesuatu yang jahat atau tidak diminta yang diminta. Logika ini termasuk dalam lapisan layanan Anda.
"Larutan"?
Mengikuti pedoman dalam jawaban ini , saya datang dengan pendekatan berikut yang menggunakan Lapisan Layanan:
class UserController : Controller {
private UserService _userService;
public UserController(UserService userService){
_userService = userService;
}
public ActionResult MakeHimPay(string username, int amount) {
_userService.MakeHimPay(username, amount);
return RedirectToAction("ShowUserOverview");
}
public ActionResult ShowUserOverview() {
return View();
}
}
class UserService {
private IUserRepository _userRepository;
public UserService(IUserRepository userRepository) {
_userRepository = userRepository;
}
public void MakeHimPay(username, amount) {
_userRepository.GetUserByName(username).makePayment(amount);
}
}
class UserRepository {
public User GetUserByName(string name){
// Get appropriate user from database
}
}
class User {
private int debt; // debt in cents
private string name;
// getters
public void makePayment(int cents){
debt -= cents;
}
}
Kesimpulan
Semua bersama-sama tidak banyak yang berubah di sini: kode dari controller telah pindah ke lapisan layanan (yang merupakan hal yang baik, jadi ada sisi positif dari pendekatan ini). Namun ini sepertinya tidak ada hubungannya dengan jawaban asli saya.
Saya menyadari bahwa pola desain adalah pedoman, bukan aturan yang ditetapkan untuk diterapkan bila memungkinkan. Namun saya belum menemukan penjelasan yang pasti tentang lapisan layanan dan bagaimana seharusnya dianggap.
Apakah ini sarana untuk mengekstrak logika dari controller dan memasukkannya ke dalam layanan?
Apakah ini seharusnya membentuk kontrak antara pengontrol dan domain?
Haruskah ada lapisan antara domain dan lapisan layanan?
Dan, yang tak kalah pentingnya: mengikuti komentar asli
Logika bisnis harus benar-benar dalam layanan. Tidak dalam model.
Apakah ini benar?
- Bagaimana saya memperkenalkan logika bisnis saya dalam layanan, bukan model?