ما هي الطريقة العملية لنمذجة جداول البحث في التصميم المستند إلى المجال (DDD)؟

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

  •  03-07-2019
  •  | 
  •  

سؤال

أنا فقط أتعلم DDD (كتاب إريك إيفانز مفتوح أمامي) وقد صادفت مشكلة لا يمكنني العثور عليها.ماذا تفعل في DDD عندما تحاول فقط الحصول على قائمة بسيطة من سجلات البحث؟

السابق.

هوية الموظف:123
اسم الموظف:فلان الفلاني
ولاية:ألاسكا (القائمة المنسدلة)
مقاطعة:Wasilla (القائمة المنسدلة - سيتم تصفيتها بناءً على الحالة).

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

لسوء الحظ ، تبدو جداول قاعدة البيانات وواجهة المستخدم مختلفة تمامًا.في tblEmployees، يحتوي على رمز الولاية=AK ورمز المقاطعة=02130، وليس أسماء الولاية والمقاطعة.

الطريقة القديمة (قبل أن أبدأ مهمة DDD هذه) ستكون واضحة جدا ، ما عليك سوى إنشاء استعلامات 2 واستخدام DataReader لملء القوائم المنسدلة.أسفل الشاشة الموجودة في المنسدلات هي القيمة ، والتي يتم استخدامها تلقائيًا في منشورات النماذج.

مع DDD، لست متأكدًا من كيفية القيام بذلك.لقد بدأت أولا بإنشاء كائنات الولاية والمقاطعة بالإضافة إلى مستودعات وواجهات للمستودعات.ومع ذلك، فإن كتابة 4 فئات + واجهتين والسباكة في ملفات hbm.xml + كائنات أعمال الموظف تبدو مبالغة في استعلامين فقط لقائمتين منسدلتين.يجب أن تكون هناك طريقة أفضل ، أليس كذلك؟أنا لا أقوم بتغيير السجلات في جداول الولاية أو المقاطعة في أي وقت قريب ، وحتى لو فعلت ذلك ، فلن يكون ذلك من خلال هذا التطبيق.لذلك لا أرغب حقًا في إنشاء كائنات تجارية للولاية والمقاطعة إذا لم أضطر إلى ذلك.

الحل الأبسط الذي أراه هو مجرد إنشاء فئة مساعدة باستخدام الأساليب التي ترجع القواميس، مثل GetStatesAll() وGetState() وGetCounties() وGetCounty()، ولكن هذا يبدو خاطئًا من منظور DDD.

الرجاء المساعدة.كيف يمكنني استخدام DDD دون المبالغة في إجراء بضع عمليات بحث بسيطة؟

حل نهائيأعتقد أنني وجدت أخيرًا إجابتي من خلال التجربة، والتي كانت تتمثل في وضع طريقة GetStates() في فئة الوصول إلى البيانات الخاصة بها، على الرغم من أنها ليست فئة مستودع.وبما أنني كنت أقوم بالوصول للقراءة فقط، فقد ألقيته في بنية DTO.نظرا لأن قاعدة البيانات كانت صغيرة ، فقد ألقيتها تماما في فئة واحدة ، مثل تود الموصوف أدناه.

استنتاجاتي:

  1. جداول البحث ليست أبدًا كائنات قيمة ، لأن جداول البحث لها دائمًا هوية.إذا لم يكن لديهم هوية، فسيكون لديك نسخ مكررة، وهو ما لن يكون له أي معنى.
  2. يمكن أن يحتوي جدول البحث للقراءة فقط على مستودع، ولكن ربما لا يحتاج إلى مستودع.الهدف من المستودع هو تقليل التعقيد عن طريق فرض الوصول فقط من خلال التجميع.يوفر لك الاطلاع على الإجمالي طريقة لضمان إمكانية تطبيق قواعد العمل، مثل عدم إضافة الإطارات إذا لم يكن لديك سيارة.
  3. إذا سمحت بصيانة CRUD على جدول البحث ، فمن المنطقي أن يكون لجدول البحث مستودع خاص به.
  4. حقيقة أنه انتهى بي الأمر إلى تخزين الرموز لأن الهياكل لا تجعلها "أنواع القيمة".يقول فاولر في POEAA أن البنية هي نوع قيمة.هذا صحيح، البنيات غير قابلة للتغيير، ولهذا السبب يقول فاولر إنها "أنواع قيمة"، لكنني كنت أستخدمها بشكل مختلف.كنت أستخدم البنيات كوسيلة خفيفة الوزن لتمرير DTOs التي لم أخطط أبدًا لتغييرها بعد إنشائها الأولي.
  5. يتم تعيينها بواسطة المنشئ ، لكنها للقراءة فقط (وليس الوصول الخاص) ولا يمكن تغييرها بمجرد إنشاء الكائن.
هل كانت مفيدة؟

المحلول

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

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

نصائح أخرى

باستخدام DDD لدي شيء مشابه لما يلي:

interface IAddressService
{
  IList<Country> GetCountries ();
  IList<State> GetStatesByCountry (string country);
  IList<City> GetCitiesByState (string state);
  // snip
}

البلد والولاية والمدينة كائنات قيمة تأتي من جدول بحث في قاعدة البيانات.

حسنًا، قرأت مقالًا بقلم ماتياس فيريس منذ بعض الوقت الحديث عن هذا هنا.يتحدث عن فصل كائنات القيمة في النموذج عن المفاهيم التي تخدم واجهة المستخدم.

اقتباس من المقال عندما سئل عما إذا كان يجب نموذج البلدان ككيانات أو كائنات قيمة:

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

واقترح نهجا مختلفا لتقديم مفهوم جديد يسمى AvailableCountry:

يمكن أن تكون هذه البلدان المتاحة كيانات في قاعدة بيانات ، وسجلات في JSON ، أو حتى مجرد قائمة مشفرة في التعليمات البرمجية الخاصة بك.(هذا يعتمد على ما إذا كانت الشركة تريد سهولة الوصول إليها من خلال واجهة المستخدم.)

<?php

final class Country
{
    private $countryCode;

    public function __construct($countryCode)
    {
        $this->countryCode = $countryCode;
    }

    public function __toString()
    {
        return $this->countryCode;
    }
}

final class AvailableCountry
{
    private $country;
    private $name;

    public function __construct(Country $country, $name)
    {
        $this->country = $country;
        $this->name = $name;
    }

    /** @return Country */
    public function getCountry()
    {
        return $this->country;
    }

    public function getName()
    {
        return $this->name;
    }

}

final class AvailableCountryRepository
{
    /** @return AvailableCountry[] */
    public function findAll()
    {
        return [
            'BE' => new AvailableCountry(new Country('BE'), 'Belgium'),
            'FR' => new AvailableCountry(new Country('FR'), 'France'),
            //...
        ];
    }

    /** @return AvailableCountry */
    public function findByCountry(Country $country)
    {
        return $this->findAll()[(string) $country];
    }
}

لذلك يبدو أن هناك حل 3rd وهو نمذجة البحث عن الجداول ككائنات وكيانات قيمة.

راجع للشغل تأكد من مراجعة قسم التعليقات ل بعض المناقشات الجادة حول المقال.

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

أنت تقرأ الكتاب الخطأ إذا كنت تريد أن تتعلم كيفية القيام بـ DDD دون المبالغة في تعقيده.:-)

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

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

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top