ما تعلمته من تجربتي المريرة (أكثر من 30 عامًا في تطوير البرمجيات)

صورة

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

تطوير البرمجيات


المواصفات أولا ، ثم الرمز


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

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

في بعض الأحيان ، يكون "العرض التقديمي الموجز" كافيًا - حيث لا يوجد أكثر من فقرتين تصفان ما يفعله التطبيق.

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

وصف الخطوات كتعليقات


إذا كنت لا تعرف كيفية البدء ، فصف تدفق بيانات المستوى الأعلى في التطبيق الخاص بك ، ببساطة بلغتك الأم. ثم قم بملء الكود الفارغ بين التعليقات.

أو أفضل من ذلك: اقرأ كل تعليق كدالة ، ثم اكتب دالة تقوم بذلك تمامًا.

Gherkin يساعدك على تحقيق التوقعات


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

اختبارات الوحدة جيدة ، واختبارات التكامل أفضل


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

اختبارات تحسين واجهات برمجة التطبيقات


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

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

هل الاختبارات التي يمكنك تشغيلها من سطر الأوامر


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

كن على استعداد لإرسال الرمز الخاص بك إلى السلة


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

تم اختراع TDD لرمي الكود: كلما زادت معرفتك بمشكلة ، كلما أدركت أن ما تكتبه لن يحلها على المدى الطويل.

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

لغة جيدة لديها اختبارات متكاملة


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

التفكير في المستقبل يعني إضاعة طاقتك


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

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

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

الوثائق هي رسالة حب مستقبلية لنفسك


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

وثائق الوظيفة هي عقدها


عند البدء في كتابة الوثائق ، أنت بصدد إنشاء عقد (ربما مع نفسك): "أدعي أن هذه الوظيفة تقوم بذلك ، وهذا ما تفعله".

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

إذا كان وصف الوظيفة "و" ، فهذا سيئ


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

لا تستخدم القيم المنطقية كمعلمات


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

مرة أخرى ، لا تفعل هذا.

لأن من يقرأ الكود سيرى getUserMessage(userId, true) ويتساءل عما يدور حوله؟

أو يمكنك إعادة تسمية وظيفة getUserMessageSummaries وإدخال getUserMessagesFull ، أو أي شيء مشابه ، ولكن كل وظيفة سوف تتصل ببساطة بـ getUserMessage الأصلية مع true أو false - لكن الواجهة خارج الفصل / الوحدة النمطية ستكون واضحة.
لكن لا تضيف إشارات أو معلمات منطقية إلى الوظائف.

حذار من التغييرات واجهة


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

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

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

تحتوي اللغات الجيدة على وثائق مضمنة


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

وغالبا ما تكون اللغات التي لا تحتوي على وثائق مضمنة موثقة بشكل سيء.

اللغة أكثر من مجرد لغة


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

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

في بعض الأحيان يكون من الأفضل ترك التطبيق يتعطل من عدم القيام بأي شيء.


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

جافا لديها نمط شائع للأسف:

 try { something_that_can_raise_exception() } catch (Exception ex) { System.out.println(ex); } 

لم يتم إجراء أي شيء باستثناء استثناء هنا ، يتم عرض رسالة فقط.

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

إذا كنت تعرف كيفية معالجتها ، فقم بذلك


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

تتحدث الأنواع عن البيانات التي لديك


الذاكرة هي مجرد سلسلة من البايتات. البايتات هي ببساطة أرقام من 0 إلى 255. ما تعنيه هذه الأرقام موصوف في نظام نوع اللغة.

على سبيل المثال ، في C ، ربما يكون نوع الحرف (حرف char) بقيمة 65 هو الحرف "A" ، والرقم int بقيمة 65 سيكون الرقم 65.

ضع ذلك في الاعتبار عند العمل مع بياناتك.

عند إضافة منطقية ، ينسى الكثيرون التحقق من عدد القيم True . لقد صادفت هذا المثال مؤخرًا JavaScript:

 console.log(true+true === 2); > true console.log(true === 1); > false 

إذا كانت البيانات الخاصة بك تحتوي على مخطط ، فقم بتخزينها كهيكل


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

تعترف والبقاء بعيدا عن عبادة البضائع


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

"إذا قامت الشركة الكبيرة بتخزين البيانات بهذه الطريقة ، فيمكننا ذلك".

"إذا استخدمت الشركة الكبيرة ، فهذا أمر جيد".

"الأداة المناسبة للمهمة" هي طريقة لفرض رأيك


يجب أن تعني عبارة "الأداة الصحيحة للمهمة" وجود أداة صحيحة وخاطئة لشيء ما. على سبيل المثال ، استخدام لغة أو إطار عمل معين بدلاً من لغة أو إطار عمل حاليين.

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

"الأداة الصحيحة" أكثر وضوحًا مما تعتقد


ربما أنت الآن تشارك في مشروع تريد فيه معالجة بعض النصوص. قد ترغب في القول ، "دعونا نستخدم Perl لأن الجميع يعلم أن Perl جيد جدًا في معالجة النص."

ما تنساه: فريقك متخصص في C. الكل يعرف C ، وليس بيرل.

بالطبع ، إذا كان هذا مشروعًا صغيرًا "على الركبة" ، فمن الممكن في بيرل. وإذا كان المشروع مهمًا للشركة ، فمن الأفضل كتابته باللغة C.

ملاحظة: قد يفشل مشروعك البطولي (المزيد حول هذا أدناه) بسبب هذا.

لا تنسجم مع ما هو خارج مشروعك


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

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

تيارات البيانات تغلب على الأنماط


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

تُستخدم أنماط التصميم لوصف الحلول ، وليس للعثور عليها.


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

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

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

تعلم أساسيات البرمجة الوظيفية


لا تحتاج إلى الخوض في الأسئلة "ما هي monads" أو "هل هو functor". لكن تذكر: يجب ألا تغير البيانات باستمرار ؛ إنشاء عناصر جديدة بقيم جديدة (اعتبار البيانات غير قابلة للتغيير) ؛ قدر الإمكان ، قم بالوظائف والفئات التي لا تخزن الحالات الداخلية (الوظائف والفئات الخالصة).

الجهد المعرفي هو عدو قابلية القراءة.


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

على سبيل المثال ، تعد إضافة منطقية لحساب القيم True هي نسخة خفيفة من التنافر المعرفي. إذا قرأت الكود ورأيت الدالة sum() ، والتي ، كما تعلمون ، تضيف جميع الأرقام في القائمة ، فإنك تتوقع رؤية قائمة بالأرقام ؛ قابلت أشخاصًا يستخدمون sum() لحساب القيم True في قائمة Booleans ، وهو أمر مربك تمامًا.

السحر رقم سبعة زائد أو ناقص اثنين


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

إذا كان لديك وظيفة تستدعي وظيفة تستدعي وظيفة تستدعي وظيفة تستدعي وظيفة تستدعي وظيفة ، فهذا مجرد جهنم لقارئ الكود.

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

علاوة على ذلك ، يتحدث علماء النفس اليوم كثيرًا عن الرقم السحري FOUR ، بدلاً من سبعة.
فكر في فئة "تكوين الوظائف" (على سبيل المثال ، "سأدعو هذه الوظيفة ، ثم ذلك ، ثم هناك ...") ، وليس في فئة "استدعاء الوظائف" (على سبيل المثال ، "هذه الوظيفة ستدعو ذلك ، وسوف تسميها". .. ").

التخفيضات جيدة ، ولكن فقط في المدى القصير


تقدم العديد من اللغات والمكتبات والأطر طرقًا مختصرة لتقليل عدد الأحرف التي تكتبها.

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

مقاومة إغراء "سهولة"


بالطبع ، سوف تساعدك IDE في الإكمال التلقائي لمجموعة من كل شيء وتجعل من السهل بناء المشروع ، لكن هل تفهم ما يحدث هناك؟

هل تعرف كيف يعمل نظام البناء الخاص بك؟ إذا كان لديك لتشغيله دون IDE ، يمكنك القيام بذلك؟

هل تتذكر أسماء الوظائف دون الإكمال التلقائي؟ هل من الممكن كسر شيء ما أو إعادة تسميته بحيث يسهل فهمه؟

اهتم بما يحدث تحت الغطاء.

استخدم دائمًا المناطق الزمنية في التواريخ


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

استخدم دائمًا UTF-8


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

يمكنك التحويل إلى أي تشفير آخر ، لكن UTF-8 هزم حرب الترميز ، وبالتالي أسهل طريقة للتشبث بها.

بدء غبي


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

نعم ، هذا ليس بالأمر السهل. ولكن عندما تستخدم لاحقًا نوعًا من IDE ، فستفكر فقط في الأزرار "نعم ، إنها تطلق ذلك". هذا هو بالضبط ما تفعله IDEs.

السجلات مخصصة للأحداث ، وليس لواجهة المستخدم.


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

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

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

مصحح المبالغة


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

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

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

دائما استخدام نظام الإصدار


"هذا مجرد تطبيق غبي أريد أن أتعلم به شيئًا" - هذا لا يبرر عدم وجود نظام للنسخ.

إذا كنت تستخدم مثل هذا النظام من البداية ، فسيكون من السهل التراجع عند ارتكاب خطأ.

تغيير واحد لكل التزام


قابلت أشخاصًا يكتبون الرسائل التالية في حالات: "حل المشكلة 1 و 2 و 3". ما لم تكن كل هذه المشكلات مكررة - بعضها يجب أن يكون مغلقًا بالفعل - يجب أن يكون هناك ثلاث أوامر بدلاً من واحدة.

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

"Git add -p" ستساعدك في الكثير من التغييرات


هذا ينطبق فقط على جيت. يتيح لك دمج الملفات جزئيًا باستخدام المعلمة "-p" ، بحيث يمكنك فقط تحديد التغييرات المرتبطة ببعضها البعض ، وترك الآخرين للالتزام الجديد.

هيكل المشاريع حسب البيانات أو النوع ، وليس الوظيفة


تستخدم معظم المشروعات الهيكل التالي:

 . +-- IncomingModels | +-- DataTypeInterface | +-- DataType1 | +-- DataType2 | +-- DataType3 +-- Filters | +-- FilterInterface | +-- FilterValidDataType2 +-- Processors | +-- ProcessorInterface | +-- ConvertDataType1ToDto1 | +-- ConvertDataType2ToDto2 +-- OutgoingModels +-- DtoInterface +-- Dto1 +-- Dto2 

بمعنى ، يتم تنظيم البيانات حسب الوظيفة (جميع نماذج الإدخال موجودة في دليل أو حزمة ، وجميع المرشحات موجودة في دليل أو حزمة أخرى ، إلخ).

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

 . +-- Base | +-- IncomingModels | | +-- DataTypeInterface | +-- Filters | | +-- FilterInterface | +-- Processors | | +-- ProcessorInterface | +-- OutgoingModels | +-- DtoInterface +-- Data1 | +-- IncomingModels | | +-- DataType1 | +-- Processors | | +-- ConvertDataType1ToDto1 | +-- OutgoingModels | +-- Dto1 ... 

الآن يمكنك إنشاء وحدة نمطية تعمل فقط مع Data1 ، وحدة أخرى تعمل فقط مع Data2 ، إلخ. وبعد ذلك يمكنك فصلهم إلى وحدات معزولة.

وعندما تحتاج إلى إنشاء مشروع آخر ، يحتوي أيضًا على Data1 والعمل مع Data3 ، يمكنك إعادة استخدام معظم التعليمات البرمجية في الوحدة النمطية Data1.

اصنع مكتبات


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

لماذا لا تخصص الأجزاء المستخدمة بشكل متكرر للمكتبات التي يمكن توصيلها في مشاريع مختلفة؟

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

تعلم لرصد


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

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

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

استخدام ملفات التكوين


تخيل: أنك كتبت وظيفة تحتاج إلى تمرير قيمة من أجل أن تبدأ المعالجة (على سبيل المثال ، معرف الحساب على Twitter). ولكن بعد ذلك تحتاج إلى القيام بذلك بقيمتين ، ويمكنك فقط استدعاء الوظيفة مرة أخرى بقيمة مختلفة.

من الأفضل استخدام ملفات التكوين وتشغيل التطبيق مرتين فقط ، مع اثنين من التكوينات المختلفة.

خيارات سطر الأوامر تبدو غريبة ، لكنها مفيدة


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

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

ليس فقط التراكيب الوظيفية ، ولكن التراكيب التطبيقية


يستخدم Unix هذا المفهوم: "التطبيقات التي تفعل شيئًا واحدًا وتقوم به جيدًا".

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

حتى عند استخدام تكوين التطبيق ، ابدأ غبي


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


, . «, », , « , ».

, . , .

, , , . , . . . , .


, , . Lisp, . , Python yield , , , . , , , , .



, , . , « », « » ..

, .

,


, .

, , «»: , , , . , , . , , , .

, , . , .


, . (« ?»), .

… Google


, . , Google , . , , Google , .

C/C++ — K&R


. :)

Python — PEP8


PEP8. , .


, ? sleep() .

? ?

, . sleepForSecs sleepForMs , , sleep .

, .

«Zen of Python», .

,


, . , - . - , , , .

« , » — .

: , — . , .

, Java , Rust. , Spring , ++.


, — , «» .

, .


, , - .

— , — .

« , »


« » « ». , , , , .

, .

,


, , , , .

.

( «»), , , . , AWS SQS ( ), , , RabbitMQ.

- , , , .


,


, . , . , .

( , ). , , , .

,


- , , . , , , , .

, . , , , « » « , ».

, .


«». , . , . , , . , .

: «, , , , ». , .

.


. - . «» «».

, , , . , .

, ,


. , , - , .

لا تفعل هذا.

- , .


- , . , .

, . .

- ,


: - , . , .

«, , » — , .


, , . . , - . . .

, , . , , , - . , , .

,


« ».

- , , , . : « , , ».

.


, , , . .

, .

«»


«» — . , - « », - .

, , , . , , , .

.

, , «»


. - : «, , ?»

, . , , (, , ).

, —


, -, , , , ( ).

… , - , , « !».

:


«» , , , , . , , .

, /, .

, .

- .

« » « »


: - , , , .

« » — , .

.

,


, , - , .

- .

, .

, , .

, , , .

… .

IT


.

, , 15 , 3-4 .

.

.

, , , - , , , , , , .


. , , URL, .

Trello — ,


« , », .

,


, « , », « , ».

. . , - .

, .

.

, , .


, . , « ». - « », , .

. .


Github «, » . , - .

.

: Python, , Java Python, .

«, »


, , , «, ».

- , , - . , .

Source: https://habr.com/ru/post/ar456862/


All Articles