
عندما ذهبت أنا وصديقي إلى المدرسة وحلمنا بأن نصبح مطورين فقط ، فكرنا في كيفية صنع شيء معًا - لعبة أو برنامج مفيد للغاية.
لقد بدأت في تعلم الإيجابيات و C # ، إنه جافا سكريبت. تخرجنا من المدرسة الثانوية ، ودرسنا في الجامعة ، وخدمنا في الجيش ، وحصلنا على وظيفة. لقد انشغلنا بالتنمية الصناعية هنا وهناك ، وعندما سئمنا منها ، تذكرنا أين بدأنا.
بعد أن جمعنا مطورين محنكين بالفعل ، قررنا أخيرًا إنشاء مشروعنا الخاص - لعبة فيديو ثنائية الأبعاد. نظرًا لأن الصديق كان واجهة نظيفة ، وكنت مكدسة بالكامل ، أصبح المتصفح منصة واضحة بالنسبة لنا. اعتدت على تطوير الواجهة فقط على TypeScript ، واعتقدنا أنه لا توجد مشكلة ، TS هي مجرد مجموعة شاملة من JavaScript. خذها وكل شيء يسير بسلاسة. لا يهم كيف. عندما بدأنا في مناقشة العمل ، واجهنا هاوية لا تصدق من سوء التفاهم.
لذا رأيت مهمة صنع لعبة. أنا كذلك - نعم ، لدينا نوع من "لعبة" ، نوع "جرد" ، نوع "شيء" ، نوع "خريطة" ، نوع "موقع". يمكنني أن أتخيل كيف يعملان معًا ، ويصفانهما ، ويجمعان مشروعًا ويعمل كل شيء. المترجم فحصني ، فعلت كل شيء بشكل صحيح. بعد ذلك ، أبدأ في كتابة التعليمات البرمجية التي تستخدم هذه الأنواع. بسبب حقيقة أنها أسهل بكثير بالنسبة لي. يخبرني IDE ويتحقق من الأخطاء. إذا كان المشروع سوف - على الأرجح أنه يعمل. قضيت الكثير من الوقت في وصف الأوصاف ، وكانت جيدة. هذا هو نهجي.
أراد صديقي أن يفعل العكس - كتابة التعليمات البرمجية على الفور وعدم وصف أي أنواع. لم يكن مستعدًا لتعريف المشكلة على أنها عائلة من النوع. لم أكن أرغب في البناء عليها ، ولم أر المهمة كمجموعة من الفئات أو الأنواع أو السجلات أو أي شيء آخر من هذا القبيل. بدا لي ببساطة لا يمكن تصوره. كلانا كان على حق في نواح كثيرة ، فقط حق كل منا استبعد الآخر.
بجدية ، تحدثنا لساعات ، لكن كل واحد تحدث عن نفسه ، كما لو كان بلغات مختلفة. ولا يمكنك الكتابة أن أدمغتنا ليست مرنة. منذ عام واحد فقط ، انتقلت بدون ألم إلى العالم الوظيفي من وجهة الكائنات ، والعكس صحيح. علاوة على ذلك ، قضيت الكثير من الوقت في تعلم JS ، وكان يتعلم العديد من اللغات المكتوبة بشكل ثابت.
لكن التكنولوجيا ، التي أصبحت أول تقنية "قتالية" للمطورين ، تحددهم بقوة لدرجة أن شخصين بالغين من ذوي الخبرة ليسوا ببساطة على استعداد للاستماع إلى بعضهم البعض. على مر السنين من دراسة التنمية ، تطورت رؤيتنا بشكل مختلف للغاية ولم تنجح طرق حل المشكلات معًا على الإطلاق.
ونتيجة لذلك ، تخلينا عن فكرة العمل مع بعضنا البعض. يتبادر إلى الذهن على الفور أن المشكلة هي فقط بيننا. ربما ، لكني رأيت هذا مع أشخاص آخرين في الصناعة.
للكتابة الساكنة والديناميكية فرق جوهري لا يمكن التوفيق بينهما
يجيب الرمز الخاص بي على السؤال "كيفية العمل مع هذا" ، وككود للمطورين الذين اعتادوا على الكتابة الديناميكية - "كيف يعمل". كلا النهجين لهما الحق في الحياة ، وهناك أدوات لكليهما ، ولكن واحد فقط يمكن أن يكون في المقدمة.
يُعد Static جيدًا للمشاريع الكبيرة التي قامت بمئات السنين من التطوير ، وديناميكيًا للفرق الصغيرة ، للمهام التي غالبًا ما تكون فيها التعليمات البرمجية للكتابة فقط مطلوبة. باستخدام الديناميكي ، يمكنك توفير الوقت والجهد في بداية التطوير ، وثابتًا في النهاية.
أثرت فكرة وضع الأنواع في المقدمة بشكل خطير على تفكيري بالمطور.
باختيار C # في بداية الرحلة ، قمت بتسمية التصنيف الثابت لنظري العالمي ، الذي أعاني منه الآن. بعد أن رأيت أي مشكلة ، أحاول تقديم حلها كمجموعة من أنواع ومبادئ تفاعلهم. عندما أقوم بتطوير وحدة نمطية ، أحدد أولاً الأنواع التي تعمل عليها والتي تتفاعل مع بيئتها. لا أتذكر حتى كيف تعاملت مع حل المشكلات من قبل.
كل تدريب برمجة Java هو التدريب على تصميم واستخدام الأنواع. .NET CLR - C # وقت التشغيل - مبني على الأنواع والأنواع. الكتابة الثابتة هي في صميم تصميم البرمجة الكائنية (مرحبا ، فصول من JS ، قررت أنك لست بحاجة إلى ذلك). التطبيقات الأساسية لمعظم أنماط OOP مليئة بالواجهة ، والتي لا معنى لها تمامًا في لغة مطبوعة ديناميكيًا.
الأنماط نفسها هي شيء متعدد اللغات ، ولكن هل يمكن لأحد أن يخبرني عن سبب الحاجة إلى نمط "الحالة" بلغة مكتوبة ديناميكيًا؟ ماذا عن البناء؟ هذه الأنماط لا تتعلق بالتنمية ، ولكنها تتعلق بالأنواع. ترتبط الأنواع و OOP ارتباطًا وثيقًا.
لا يمكنك بناء منطق عملك بناءً على الأنواع ، لكنك لا تعرف أي شيء عنها في عملية التطوير. هذا هو السبب في وجود بائعين أماميين يغطون شفرتهم بعدد لا يمكن تخيله من اختبارات الوحدة ، والتي تتحقق فقط من أساس الرمز لعدم وجود أخطاء في النوع.
نعلم جميعًا جيدًا أن الأمن من خلال التغطية هو وهم. الاختبارات مكتوبة بخط اليد ؛ فهي ، بحكم تعريفها ، أقل موثوقية من نظام فحص النوع المدمج في اللغة.
هذا لا يعني أن اللغات المكتوبة ديناميكيًا ليست ضرورية (في الواقع ، أعتقد حقًا أنها ليست ضرورية). هذا يعني أنه عند استخدامها ، تحتاج إلى التخلي عن OOP كنموذج سائد. كل هذه الوحدة من البيانات والعمليات عليها مخصصة للرجال الذين لديهم فحص ثابت.
لا يعتقد المطورون الذين تعاملت معهم أن وجود كتابة ثابتة يغير نهج التطوير ، ويكتبون نفس التعليمات البرمجية كما هو الحال في اللغات الديناميكية ، مضيفين التحقق من النوع. أعتقد أن هذا خطأ جوهري. وهذا يمكن ملاحظته على وجه التحديد في حالة وجود واجهة أمامية حديثة.
أعرف أن انتقاد الجبهات هو موضوع من المحرمات. في أحد الأيام ، بدأت أنا وصديقي ذكاءً اصطناعيًا يخدع الجميع على Twitter ، وقد التقط بريندان آيك ذلك. على محمل الجد ، حارب منشئ جافا سكريبت مع شبكتنا العصبية في التعليقات.
لسبب غير معروف ، هؤلاء الرجال ببساطة غير مستعدين للعيش في عالم حيث تحتوي رؤيتهم على فجوات خطيرة. لذلك ، أنتقد فقط أولئك الذين يندفعون إلى مشروعي المكتوب بالتأكيد ، ويضعون أوامرهم الخاصة هناك.
كنا سنعيش في عوالمنا الصغيرة ، لكن TypeScript دفعتنا
لذلك أنا أكتب رمزًا نظرًا لأن الأنواع لا يمكن استخدامها بشكل غير صحيح. في المشروع ، أتوقع أن يستخدم الآخرون الأنواع أيضًا. ثم ستعمل الكود الخاص بي كما قصدت. وأنا لا أغطي عن علم جميع حالات إساءة استخدام هذا الرمز (لأن الكتابة تستبعد ذلك). لكن لقب JS يأتي في المشروع ، ويأخذ هذا النوع من الألغام ، ويلفها في أي منها ، ويبدأ في استخدامه بشكل غير صحيح ، مما يؤدي إلى أخطاء دقيقة.
مطورو جافا سكريبت مقتنعون بأن Typescript لا يزال هو نفس JS ، ولكن مع القدرة على إضافة التحقق من النوع الثابت في بعض الأحيان إذا كانوا بحاجة إليه. هذا ليس كذلك. البرنامج النصي أقوى بمائة مرة ، وهم مهتمون بثلاثة بالمائة فقط من إمكانياته.
الحجة الأكثر ضررا هي TypeScript هي مجرد مجموعة شاملة من JS. ولكن من الناحية العملية ، لا يسعك إلا أن تعتبر Typescript كلغة مستقلة ، حتى إذا كنت الملك الملعون للواجهات الأمامية. لأننا هنا نحتاج إلى نهج مختلف - ثابت وليس ديناميكي.
الميزة الرئيسية للكتابة الثابتة هي الضمان. إذا كنت تستخدمه في وحدة واحدة ، ولكن ليس في وحدة أخرى ، فقد قضيت وقتًا وجهدًا في وصف الأنواع وتطويرها ، ولكنك لم تحصل على أي ضمانات.
يبدو للكثيرين أن TypeScript هو حل وسط بين أنظمة الكتابة بين JS و Java. إنه ليس حلاً وسطًا ، ونظام نوعه خاص فقط.
كل شيء يضاعف من حقيقة أن كل وظيفة ثانية على الجبهة تتطلب معرفة TS. هذا يؤدي إلى حقيقة أن مطوري JS يدرسون سطحيًا قدرات Typescript ، ويبدأون في كتابة التعليمات البرمجية عليه ، مما يخلق عددًا كبيرًا من الممارسات الضارة. ينشأ موقف عندما لا يحتاجون حقًا إلى كتابة ثابتة للكتابة ، لكنهم فرضوها عليهم ودمروها. يجب أخيرًا إدراك أن مناهج التطوير مع الكتابة الديناميكية والساكنة تتعارض مع بعضها البعض ، فهذه ليست أشياء يمكن خلطها.
JavaScript ، كما أراها ، هي أداة جيدة جدًا لكتابة التعليمات البرمجية التي تحل المشكلة دون إبراز التجريد غير الضروري. الحالة الأكثر فظاعة في ذلك هي نمط مصنع الثلج. يمكنك إطعام هذا المثيل مثيلاتك ، ويغطيها بحصانة وقت التشغيل. إذا قمت بمعالجتي مع هذا المصنع ، فسوف يعطيني نفس الشيء ، ولكن عندما أحاول تغيير قيمة إحدى الخصائص ، سأحصل على استثناء. فقط وات؟!؟
نشأ النمط لأن الجبهات تقرأ في مكان ما عن الثبات البارد ، وقررت سحبه إلى لغتهم الخاصة ، والتي لم تكن بأي حال من الأحوال مخصصة للحصانة. في Typescript ، يمكنني إنشاء نفس المصنع ، ولكن مع حظر وقت مجمع للطفرات ، ودون أي استثناءات.
من ناحية أخرى ، هذا ليس ضروريًا ، لأن هناك برمجة وظيفية خالصة. خذ F # ، Haskell ، OCaml ، سأضعها ، ReasonML - هناك طفرات ممنوعة خارج الصندوق. لكن أخشى أنه إذا أعطيت الواجهة الأمامية للغة وظيفية ، فستبدأ على الفور في تحديثها وجعل السلوك يبدو مثل JS.
لأن اختيار الكتابة هو مسار بدون عودة. جميع الحلول الوسطية تعطي فقط وهم الحل الوسط. إما أن تضع الأنواع في المقدمة أم لا. لا أدري كيف سيحدث كل شيء ، ابدأ في تعلم C # وجافا سكريبت في وقت واحد وبشكل موازٍ لبعضهما البعض. ولكن الآن أنا مسمر للغاية في تفكيري لدرجة أنني لا أرى ولا أرغب في رؤية مزايا الكتابة الديناميكية. إنهم كذلك ، ولكن بعيدًا عن نظري ، وكل ما تبقى لي هو أن أغض الطرف عنهم ، كما هو الحال بالنسبة لأي مظاهر من العالم غريبة علي يجب أن أعيش معها. أفهم أنني مخطئ ، لكني أحتاج إلى العمل هنا والآن ، ولا توجد ميزانية تتسارع بين القطبين.
لذلك ، لا أريد البحث عن حلول وسط ، لكنني أتحدث بشكل مباشر. إذا كنت قد بدأت للتو في تعلم التطوير ، فابدأ بالكتابة الثابتة.