سؤال

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

أعتقد أن "هذا يمكن أن يكون خاصية، لكنني لست متأكدًا مما إذا كان هذا هو المصطلح الاصطلاحي لـ C#."

هل علي أن كشف النتيجة النهائية كخاصية، أو كطريقة بدون وسائط؟هل سيجد مبرمج C# العادي الخصائص مربكة أو مسيئة؟ماذا عن جمهور Alt.Net؟

decimal consumption = calculator.GetConsumption(); // obviously derived
decimal consumption = calculator.Consumption; // not so obvious

إذا كان الأخير:هل علي أن إعلان النتائج المؤقتة كخصائص [خاصة]., ، أيضًا؟بفضل الثقيلة طريقة الاستخراج, ، لدي عدة نتائج مؤقتة.لا ينبغي أن يكون الكثير منها جزءًا من واجهة برمجة التطبيقات العامة.قد يكون بعضها مثيرًا للاهتمام، وستبدو تعبيراتي أكثر وضوحًا إذا تمكنت من الوصول إليها كخصائص:

decimal interim2 = this.ImportantInterimValue * otherval;

قسم التجارب السعيدة:

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

تبدو إعلانات القيمة المؤقتة أكثر فوضوية.ومع ذلك، فإن التعبيرات أسهل في القراءة بدون الأقواس.لم أعد أشعر بأنني مضطر لبدء اسم الطريقة بفعل.على النقيض:

// Clean method declaration; compulsive verby name; callers need
// parenthesis despite lack of any arguments.
decimal DetermineImportantInterimValue() {
    return this.DetermineOtherInterimValue() * this.SomeProperty;
}

// Messier property declaration; clean name; clean access syntax
decimal ImportantInterimValue {
    get {
        return this.OtherInterimValue * this.SomeProperty;
    }
}

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

def determineImportantInterimValue(self):
    "The usual way of doing it."
    return self.determineOtherInterimValue() * self.someAttribute

importantInterimValue = property(
    lambda self => self.otherInterimValue * self.someAttribute, 
    doc = "I'm not sure if this is Pythonic...")
هل كانت مفيدة؟

المحلول

ويبدو أن السؤال المهم هنا هو:

أيهما ينتج كودًا أكثر وضوحًا وقابلية للصيانة لك على المدى الطويل؟

في رأيي الشخصي، فإن عزل الحسابات الفردية كخصائص له ميزتان متميزتان مقارنة بطريقة أحادية واحدة:

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

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

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

  • إذا كانت كافة الخصائص منفصلة بما فيه الكفاية، فقد يؤدي تضمين المترجم إلى حل مشكلات الأداء لك.

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

أحد أفضل الأشياء التي يمكنك القيام بها هو التفكير بنفسك والتجرؤ على تحدي المفاهيم المسبقة "مقاس واحد يناسب الجميع" التي وضعها أقراننا وأسلافنا.هناك استثناءات لكل قاعدة.قد تكون هذه الحالة واحدة منها.

حاشية:لا أعتقد أننا يجب أن نتخلى عن التصميم القياسي للعقارات في الغالبية العظمى من الحالات.ولكن هناك حالات يكون فيها الانحراف عن المعيار (TM) مطلوبًا، لأنه من المنطقي القيام بذلك.

نصائح أخرى

أنا شخصياً أفضل أن تقوم بإنشاء واجهة برمجة التطبيقات العامة الخاصة بك كطريقة بدلاً من الملكية.من المفترض أن تكون الخصائص "أسرع" قدر الإمكان في لغة C#.مزيد من التفاصيل حول هذه المناقشة: الخصائص مقابل الأساليب

داخليًا، يمكن لـ GetConsumption استخدام أي عدد من الخصائص الخاصة للوصول إلى النتيجة، والخيار لك.

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

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

لنفترض أنك تشتق قيمة من سبعة مدخلات، وقمت بتنفيذ سبع خصائص، واحدة لكل مدخل، ولديك مُحصل الخاصية للنتيجة.بعض الأشياء التي قد ترغب في أخذها بعين الاعتبار هي:

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

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

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

  • عندما يكون لديك طريقة تحتوي على عدة معلمات، يمكنك بسهولة الحصول على تحقق أكثر ثراءً.على سبيل المثال، يمكنك طرح استثناء ArgumentException إذا كانت "المعلمة A والمعلمة B فارغة".

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

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