Dalam perdebatan model domain Rich vs Anemic, internet penuh dengan saran filosofis tetapi pendek pada contoh-contoh otoritatif. Tujuan dari pertanyaan ini adalah untuk menemukan pedoman definitif dan contoh nyata dari model Desain Berbasis Domain yang tepat. (Idealnya dalam C #.)
Sebagai contoh dunia nyata, implementasi DDD ini tampaknya salah:
Model domain WorkItem di bawah tidak lain adalah tas properti, yang digunakan oleh Entity Framework untuk database kode-pertama. Per Fowler, itu adalah anemia .
Lapisan WorkItemService tampaknya merupakan persepsi yang salah tentang Layanan Domain; ini berisi semua logika perilaku / bisnis untuk WorkItem. Per Yemelyanov dan lainnya, ini bersifat prosedural . (hal 6)
Jadi jika di bawah ini salah, bagaimana saya bisa memperbaikinya?
Perilaku, yaitu AddStatusUpdate atau Checkout , harus termasuk dalam kelas WorkItem yang benar?
Ketergantungan apa yang harus dimiliki oleh model WorkItem?
public class WorkItemService : IWorkItemService {
private IUnitOfWorkFactory _unitOfWorkFactory;
//using Unity for dependency injection
public WorkItemService(IUnitOfWorkFactory unitOfWorkFactory) {
_unitOfWorkFactory = unitOfWorkFactory;
}
public void AddStatusUpdate(int workItemId, int statusId) {
using (var unitOfWork = _unitOfWorkFactory.GetUnitOfWork<IWorkItemUnitOfWork>()) {
var workItemRepo = unitOfWork.WorkItemRepository;
var workItemStatusRepo = unitOfWork.WorkItemStatusRepository;
var workItem = workItemRepo.Read(wi => wi.Id == workItemId).FirstOrDefault();
if (workItem == null)
throw new ArgumentException(string.Format(@"The provided WorkItem Id '{0}' is not recognized", workItemId), "workItemId");
var status = workItemStatusRepo.Read(s => s.Id == statusId).FirstOrDefault();
if (status == null)
throw new ArgumentException(string.Format(@"The provided Status Id '{0}' is not recognized", statusId), "statusId");
workItem.StatusHistory.Add(status);
workItemRepo.Update(workItem);
unitOfWork.Save();
}
}
}
(Contoh ini disederhanakan agar lebih mudah dibaca. Kode ini jelas masih kikuk, karena ini merupakan upaya yang membingungkan, tetapi perilaku domainnya adalah: perbarui status dengan menambahkan status baru ke riwayat arsip. Pada akhirnya saya setuju dengan jawaban lain, ini hanya bisa ditangani oleh CRUD.)
Memperbarui
@AlexeyZimarev memberikan jawaban terbaik, video yang sempurna tentang subjek dalam C # oleh Jimmy Bogard, tetapi tampaknya dipindahkan ke komentar di bawah karena tidak memberikan informasi yang cukup di luar tautan. Saya memiliki konsep kasar catatan saya yang merangkum video dalam jawaban saya di bawah ini. Silakan mengomentari jawaban dengan koreksi apa pun. Video ini berdurasi satu jam tetapi sangat layak ditonton.
Perbarui - 2 Tahun Kemudian
Saya pikir itu adalah tanda kedewasaan DDD yang baru lahir bahwa bahkan setelah mempelajarinya selama 2 tahun, saya masih tidak bisa berjanji bahwa saya tahu "cara yang benar" untuk melakukannya. Bahasa di mana-mana, akar agregat, dan pendekatannya terhadap desain yang didorong perilaku adalah kontribusi berharga DDD untuk industri. Ketidaktahuan yang gigih dan sumber acara menyebabkan kebingungan, dan saya pikir filsafat seperti itu menahannya dari adopsi yang lebih luas. Tetapi jika saya harus melakukan kode ini lagi, dengan apa yang telah saya pelajari, saya pikir akan terlihat seperti ini:
Saya masih menyambut jawaban apa pun untuk pos ini (sangat aktif) yang memberikan kode praktik terbaik untuk model domain yang valid.
"I don't want to duplicate all my entities into DTOs simply because I don't need it and it violates DRY, and I also don't want my client application to take a dependency on EntityFramework.dll"
. "Entitas" dalam jargon Entity Framework tidak sama dengan "Entities" seperti pada "Domain Model"