Rich'e karşı Anemik etki alanı modelleri tartışmasında, internet felsefi tavsiyelerle doludur, ancak otoriter örnekler konusunda kısa bilgi. Bu sorunun amacı, kesin Etki Alanına Dayalı Tasarım modellerinin kesin kurallarını ve somut örneklerini bulmaktır. (İdeal olarak C # 'da.)
Gerçek dünyadaki bir örnek için, DDD'nin bu uygulaması yanlış görünmektedir:
Aşağıdaki WorkItem etki alanı modelleri, Entity Framework tarafından kod ilk veritabanı için kullanılan özellik çantalarından başka bir şey değildir. Fowler başına, bu bir anemik .
WorkItemService katmanı, görünüşte Etki Alanı Hizmetlerinin ortak bir yanılgısıdır; WorkItem için tüm davranış / iş mantığını içerir. Yemelyanov ve diğerleri, usule göredir . (sf. 6)
Peki, aşağıdaki yanlışsa, nasıl düzeltebilirim?
Davranış, yani AddStatusUpdate veya Checkout , WorkItem sınıfına girmeli mi?
WorkItem modelinin hangi bağımlılıkları olmalı?
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();
}
}
}
(Bu örnek daha okunaklı olacak şekilde basitleştirildi. Kod kesinlikle hala karışık, çünkü bu karışık bir girişim, ancak etki alanı davranışı şuydu: yeni durumu arşiv geçmişine ekleyerek durumu güncelle. Sonuçta diğer cevaplara katılıyorum. sadece CRUD tarafından ele alınabilirdi.)
Güncelleme
@AlexeyZimarev en iyi cevabı verdi, C # 'daki konuyla ilgili olarak Jimmy Bogard'ın mükemmel bir videosu, ancak bağlantının ötesinde yeterli bilgi vermediği için görünüşe göre aşağıdaki bir yoruma taşındı. Aşağıdaki cevabımdaki videoyu özetleyen notlarım hakkında kaba bir taslak var. Lütfen cevabınızı düzeltmelerle ilgili yorum yapmaktan çekinmeyin. Video bir saat sürüyor ama izlemeye değer.
Güncelleme - 2 Yıl Sonra
Bence DDD'nin yeni ortaya çıkan olgunluğunun bir işareti, 2 yıl çalıştıktan sonra bile, hala bunu yapmanın "doğru yolunu" bildiğime söz veremem. Eşsiz dil, toplu kökler ve davranış odaklı tasarıma yaklaşımı DDD'nin sektöre değerli katkılarıdır. Kalıcılık cehaleti ve olayların kaynaklanması karışıklık yaratıyor ve bunun gibi bir felsefenin onu daha geniş bir kabullenmeden uzak tuttuğunu düşünüyorum. Fakat bu kodu tekrar tekrar yapmak zorunda olsaydım, öğrendiklerimle, bunun gibi bir şey olacağını düşünüyorum:
Geçerli bir etki alanı modeli için en iyi uygulama kodunu sağlayan bu (çok etkin) yayına yanıtları hala memnuniyetle karşılıyorum.
"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"
. Varlık Çerçevesi jargonundaki "Varlıklar", "Etki Alanı Modeli"