واجهة مع طبقة الخدمة أو كائنات المجال نفسها؟ (DDD)

StackOverflow https://stackoverflow.com/questions/4300859

سؤال

ما زلت أتعلم عن DDD ولدي هذين السؤالين (ربما بسيط):

اذا كان مصنع يخلق كائن/رسم بياني جديد/مجموع حالات ، ولكن أيضا "إعادة التركيب" الكائنات/الرسوم البيانية من مخزن, ، ومن بعد:

(1) هل تعمل طبقة الخدمة/الوظائف/المهام/وحدة العمل في المصنع أو طريقة سلوكية على مثيل الكيان أو وظيفة خدمات المجال؟ لقد ضاعت فيما يتعلق بمكدس المكالمات بناءً على مسؤولية هذه المكونات.

(2) هل تحتوي مثيلات الكيان على "طرق سلوكية" كما هو مذكور أعلاه؟ على سبيل المثال لا يوجد منشور p.UpdatePost(string bodyText) أم أن هذا ليس مصدر قلق لنموذج المجال ، وبالتالي ينبغي تحقيق الشيء نفسه مع المستودع؟ أو وظيفة طبقة الخدمة ، هل يجب أن تدعو المستودع في هذه الحالة وأن مثيل الكيان لديه ببساطة طرق سلوكية خاصة بالمجال وليس الثبات؟ ولكن بعد ذلك ، لماذا يبدو مثل "تحديث منشور" وظيفة المجال عندما يكون هذا هو هدف المستخدم؟

يمكنك أن ترى أنني في كل مكان. الرجاء المساعدة.

هل كانت مفيدة؟

المحلول

(1) هل تعمل طبقة الخدمة/الوظائف/المهام/وحدة العمل في المصنع أو طريقة سلوكية على مثيل الكيان أو وظيفة خدمات المجال؟ لقد ضاعت فيما يتعلق بمكدس المكالمات بناءً على مسؤولية هذه المكونات.

عادة - يسترجع المستوى الأعلى الجذر الإجمالي الضروري ويستدعي وظيفة عليه. في بعض الأحيان ، يسترجع المستوى الأعلى جذور متعددة ويمررها إلى خدمة المجال ، ولكن ليس في كثير من الأحيان لأن خدمة المجال هي علامة قوية جدًا على وجود جذر إجمالي غير معترف به. في النهاية - يضمن المستوى العلوي استمرار الجذر الكلي.

(2) هل تحتوي مثيلات الكيان على "طرق سلوكية" كما هو مذكور أعلاه؟ على سبيل المثال ، هل لدى المنشور p.upDatePost (سلسلة bodytext) أم أنه ليس مصدر قلق لنموذج المجال ، وبالتالي ينبغي تحقيق الشيء نفسه مع المستودع؟ أو وظيفة طبقة الخدمة ، هل يجب أن تدعو المستودع في هذه الحالة وأن مثيل الكيان لديه ببساطة طرق سلوكية خاصة بالمجال وليس الثبات؟ ولكن بعد ذلك ، لماذا يبدو مثل "تحديث منشور" وظيفة المجال عندما يكون هذا هو هدف المستخدم؟

نعم ، يفعلون. يجب أن يكون نموذج المجال على دراية بتغييرات حالته. وهذا أكثر فائدة كما يبدو في البداية. شيء عظيم في هذا هو أنك تكتسب نقطة تمديد. إذا كان العميل سيمشي بعد أسبوعًا ويقول إنه يريد من النظام التحقق من أشياء إضافية عند نشر تحديثات المستخدم - بدلاً من البحث في كل سطر post.bodyText="new value", ، ستتمكن من الذهاب مباشرة إلى post.UpdatePost الطريقة وإرفاق الأشياء اللازمة هناك.

من ناحية أخرى - لا يكون Crud حصريًا بشكل متبادل مع تصميم المجال. على سبيل المثال - في طلبي ، فإن إدارة المستخدمين وأدوارهم غير مثيرة للاهتمام بما يكفي حتى لا أحاول تصميمه الحبيبي. تحتاج إلى التعرف على الأجزاء التي يهم تطبيقك الذي يصفه تطبيقك ويعمل معه.

ضع في اعتبارك أن التصميم الذي يحركه المجال أمر منطقي للتطبيقات المعقدة فقط. تطبيق المدونة البسيط لا يحتاج إليه.

(3) هل أنا مخطئ في افتراض أن طبقة الخدمة (وليس خدمات المجال) يجب أن تغلف كيف تتفاعل الواجهة مع طبقة المجال؟

كما أراها - خدمات التطبيقات هي أكثر من أجل تنسيق البنية التحتية. إذا لم تكن هناك بنية تحتية - خدمة التطبيق يفقد القيمة:

خدمات التطبيق هي في الأساس مجرد واجهات. وكل واجهة سيئة إذا كان التعقيد يضيف مشاكل زيادة الوزن التي يحلها.


داخل المجال:

//aggregate root is persistence ignorant. 
//it shouldn't reference repository directly
public class Customer{
  public string Name {get; private set;}
  public static Customer Register(string name){
    return new Customer(name);
  }
  protected Customer(string name){
    //here it's aware of state changes.
    //aggregate root changes it's own state
    //instead of having state changed from outside
    //through public properties
    this.Name=name;
  }
}

//domain model contains abstraction of persistence
public interface ICustomerRepository{
  void Save(Customer customer);
}

خارج المجال:

public class CustomerRepository:ICustomerRepository{
  //here we actually save state of customer into database/cloud/xml/whatever
  public void Save(Customer customer){
    //note that we do not change state of customer, we just persist it here
    _voodoo.StoreItSomehow(customer);
  }
}

//asp.net mvc controller
public class CustomerController{
  public CustomerController(ICustomerRepository repository){
    if (repository==null)throw new ArgumentNullException();
    _repository=repository;
  }
  public ActionResult Register(string name){
    var customer=Customer.Register(name);
    _repository.Save(customer);
  }
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top