سؤال

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

أنا على وشك البدء في التطوير على تطبيق جديد (.NET & C#) وأحب حقًا مفهوم نمط المواصفات وأنا حريص على الاستفادة الكاملة منه. ولكن قبل أن أذهب في جميع الأسلحة المشتعلة ، سأكون مهتمًا حقًا بمعرفة ما إذا كان يمكن لأي شخص مشاركة نقاط الألم التي عاشت عند استخدامها نمط المواصفات في تطوير تطبيق.

من الناحية المثالية ، أتطلع لمعرفة ما إذا كان لدى الآخرين مشاكل في

  • اختبارات وحدة الكتابة مقابل نمط المواصفات
  • تحديد الطبقة التي يجب أن تعيش فيها المواصفات (المستودع ، الخدمة ، المجال ، إلخ)
  • استخدامه في كل مكان عندما يكون بسيطًا if البيان كان من شأنه أن يقوم بالمهمة
  • إلخ؟

شكرا مقدما

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

المحلول

كما أشار ديفيد في تعليقه ، يمكن الآن تحقيق الكثير من ما هو مفيد في المواصفات بشكل أكثر إيجازًا مع أمثال LINQ.

بدلاً من نوع المواصفات الجديد ، يمكنك إنشاء مواصفات تعسفية على أساس الحذر:GetCustomers().Where(customer => customer.IsActive && customer.City == "Oakland");

هذا ليس بديلاً كاملاً للمواصفات ، لعدة أسباب:

  1. يحدث الفرز/التصفية في الفصل المستهلك بعد إرجاع جميع العملاء. إذا كنت تتعامل مع أي شيء آخر غير الكائنات في الذاكرة ، فهذا أمر دون المستوى الأمثل (LINQ-to-SQL وما شابه ذلك هو استثناءات لأنها تقوم بتجميع الاستعلامات وتحسينها وتنفيذها على الجانب/الجانب البعيد ، وإعادة النتائج المطلوبة فقط ).
  2. واجهة برمجة التطبيقات الخاصة بك مفتوحة على مصراعيها أي استعلام إذا قمت بفضح المجموعات وترك المواصفات لاستفسارات LINQ. إذا كنت ترغب في تقييد ما الذي يمكن استرجاعه أو ما الذي يمكن استرداده ، فستحتاج إلى مجموعة من المواصفات التي يمكن الاستعلام عنها.

بالتأكيد ليست هناك حاجة لاستخدامها في كل مكان ، ومن المحتمل جدًا أنك لن تحتاجها على الإطلاق ؛ لا أعرف مجالك أو ما تعمل عليه.

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

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

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

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

أتمنى أن يكون هذا مفيدًا بعض الشيء.

نصائح أخرى

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

var valuedCustomers = Customers.Where(c => c.Orders.Count > 15 && c.Active).ToList();

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

var valuedCustomers = Customers.Where(new ValuedCustomerRule.IsSatisfied()).ToList();

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

الإجابة المحدثة: أتفق مع WIX ، LINQ غير بديل لنمط المواصفات. ليس لدي سمعة كافية لإضافة تعليق إلى إجابة wix ، فأنا أرد فقط كإجابة.

حسب هذه الورقة تستخدم المواصفات في المقام الأول لمطابقة كائن المجال مقابل بيان. على الرغم من أن المواصفات تُرجع صحيحة/خاطئة عند المطابقة مع كائن المجال ولكن هذا يعني أن المواصفات مقترحة لتغليف أي حالة منطقية في الكود الخاص بك.

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

   var valuedCustomer = new ValuedCustomerSpecification();
   //1. You can use this statement to check if a customer is valued or not in your domain
   Customer customer = ....
   if(valuedCustomer.IsSatisfiedBy(customer))

   //2. You can use it to get just valued customers from repository, 
   var valuedCustomers = repository.Get(valuedCustomer);

   //3. You can combine it with other specifications to create composite specifications. Following syntax can vary with implementation
   var seniorValuedCustomer = valuedCustomer.And(seniorCustomer)

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

ذكر الورقة المذكورة أعلاه أيضًا عند عدم استخدام أنماط المواصفات.

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