سؤال

أقوم بتطوير وأحافظ على تطبيق WinForms كبير (500k+ loc) مكتوب في C# 2.0. إنه متعدد المستخدمين ويتم نشره حاليًا على حوالي 15 آلة. إن تطوير النظام مستمر (يمكن اعتباره بيتا دائمة) ، وهناك القليل جدًا من تم القيام به لحماية المستخدمين من الأخطاء الجديدة المحتملة التي قد يتم تقديمها في بناء أسبوعي.

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

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

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

الآن ، أدرك تمامًا أن ميزات اللغة الجديدة في C# 3 و 4 غير متوافقة إلى حد كبير مع التحرير والتحرير (تعبيرات Lambda ، LINQ ، إلخ). هذا أحد الأسباب التي تجعلني قاومت نقل المشروع إلى إصدار أحدث من الإطار.

سؤالي هو ما إذا كان من الممارسات الجيدة تجنب استخدام هذه التركيبات الأكثر تقدماً لصالح الكود الذي يسهل تصحيحه؟ هل هناك شرعية في هذا النوع من التطور ، أم أنها تهدر؟ أيضًا ، من المهم أيضًا ، أي من هذه البنيات (تعبيرات Lambda ، والطرق المجهولة ، وما إلى ذلك) تتحمل النفقات العامة للأداء/الذاكرة التي يمكن أن تتجنبها رمز مكتوبة جيدًا ومتوافق مع التحرير والموت؟ ... أم أن الأعمال الداخلية لمجمول C# تجعل مثل هذه التركيبات المتقدمة تعمل بشكل أسرع من رمز "الموسع" المكتوب يدويًا؟

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

المحلول

دون الرغبة في الصوت - من الممارسات الجيدة كتابة اختبارات الوحدة/التكامل بدلاً من الاعتماد على تحرير الاستئصال.

وبهذه الطريقة ، تنفق الجهد مرة واحدة ، وكل مرة أخرى "مجانية" ...

الآن أنا لا أقترح عليك كتابة وحدات بأثر رجعي لجميع الكود الخاص بك ؛ بدلاً من ذلك ، في كل مرة يتعين عليك فيها إصلاح خطأ ، ابدأ بكتابة اختبار (أو اختبارات متعددة أكثر شيوعًا) تثبت الإصلاح.

كما يذكر dave Swersky في التعليقات ، كتاب Mchael Feathers ، العمل بفعالية مع الرمز القديم هو مورد جيد (إنه قديم بعد 5 دقائق من كتابتك ، أليس كذلك؟)

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

نصائح أخرى

أنا أحب "التعديل والاستمرار". أجد أنه عامل تمكين ضخم للتطوير/التصحيح التفاعلي وأجده أيضًا مزعجًا جدًا عندما لا يعمل.

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

أحد أليف Peeves هو أن تحرير أي شيء في وظيفة مع تعبيرات Lambda يكسر "تحرير واستمرار". إذا قمت برحلة فوقها بما يكفي ، فقد أكتب تعبير Lambda. أنا على السياج مع تعبيرات لامدا. يمكنني القيام ببعض الأشياء بشكل أسرع معهم ، لكنهم لا يوفرون لي الوقت إذا انتهى بي الأمر إلى كتابتها لاحقًا.

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

نهجك لا يحتاج إلى أن يكون أبيض وأسود.

أراد توضيح هذه الأشياء قليلاً

من الممارسات الجيدة تجنب استخدام هذه التركيبات الأكثر تقدماً لصالح الكود الذي يسهل تصحيحه؟

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

يمكن تجربة كل شيء واختباره في الوقت الفعلي دون إيقاف العملية.

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

بشكل عام ، على الرغم من نعم ، أعتقد أنه من الخطأ تجنب C# جديد ينتهك لصالح السماح بالتحرير والمتابعة. يعد التحرير والمتابعة ميزة رائعة (أحببتها حقًا عندما واجهتها لأول مرة في أيام C ++). لكن القيمة كمساعد لخادم الإنتاج لا يعوض عن مكاسب Producitivy من ميزات C# الجديدة IMHO.

سؤالي هو ما إذا كان من الممارسات الجيدة تجنب استخدام هذه التركيبات الأكثر تقدماً لصالح الكود الذي يسهل تصحيحه للغاية.

أود أن أزعم أنه في أي وقت تجبر نفسك على كتابة رمز هو:

  1. أقل تعبيرا
  2. طويل
  3. يتكرر (من تجنب الطرق العامة)
  4. غير محمول (لا تصحح واختبار 64bit ؟؟!؟!؟)

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

أود أن أكتب أفضل رمز ممكن ، وليس الرمز الذي يجعل ميزة عمل IDE الخاص بك.

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

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

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

http://www.codinghorror.com/blog/2006/02/revisiting-edit-and-continue.html

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

لقد عملت أيضًا على مشاريع كبيرة جدًا للبيتا.

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

لقد استخدمت الطرق والفصول العامة لإعادة الاستخدام والموثوقية.

لقد قمت بتشجيع الفصول في المُنشئين إلى حد كبير قدر الإمكان ، للحفاظ على ثبات الطبقة والقضاء على إمكانية الحشرات الناجمة عن كائنات في حالات غير صالحة.

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

كل هذه مفيدة في الحفاظ على مشروع كبير متغير بسرعة في حالة موثوقة.

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

هناك الكثير سأفعله لتسهيل العثور على الأخطاء ، ولكن ليس إذا كان من السهل الحصول على الأخطاء أيضًا.

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

أعلم أن TDD هي كلمة الطنانة الحالية ، لكنها تعمل حقًا بالنسبة لي. إذا احتجت إلى استخدام مصحح الأخطاء ، فأنا أعتبره فشلًا شخصيًا :)

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

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

أتمنى أن يساعدك هذا!

القضية التي يبدو أنك تواجهها هي:

يستغرق الأمر وقتًا طويلاً لإعادة بناء التطبيق ، وابدأه مرة أخرى والوصول إلى جزء من واجهة المستخدم التي تعمل عليها.

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

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

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

عندما بدأت في كتابة الكثير من اختبارات الوحدة ، انخفض استخدامي لـ "التحرير والاستئصال" ، كيف بالكاد أستخدمه بصرف النظر عن رمز واجهة المستخدم.

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