كائن افتراضي
كائن افتراضي

@CrouchSays

18 تغريدة 29 قراءة Jun 02, 2021
في ناس كتير اتكلمت عن مشاكل الجمل الشرطية في الكود وفي ناس بتوصل لان وجود الجمل الشرطية في حد ذاته شر لابد من تفاديه ودليل على ان عندك code smell
هاتكلم عن شوية مشاكل مرتبطة بالجمل الشرطية اظن انها مشهورة وازاي نقدر نتخلص منها 🧵
قبل ما نتكلم حابب انوه ان الحلول دي مش مبتكرة نهائي، انما هي حاجات اتعلمتها وانا شغال وهتلاقوها في كتب ومواقع كتير جدا وعلى رأسهم refactoring.guru و Clean Code وطبعا مارتن فاولر فلو حسيت بأي تشابه في المحتوى مع المواقع دي خليك دايما متخيل انهم الاصل
من اشهر المشاكل اللي بنشوفها في الكود هي ال nested if وهي السبب في اني اكتب الثريد ده اصلا. المشكلة دي ليها اسامي كتير زي
1. Conditional from hell
2. Arrow Code
3. Nested if conditions.
منظر الكود بيكون واخد شكل السهم ومليان بالجمل الشرطية وسهل جدا انك تعرف تشوف المشكلة
نتكلم عن اول وابسط حل Guard clauses والفكرة وراها هي انك بتحاول تسطح السهم اللي الكود راسمه ده وتقلل ال nesting عن طريق short circuits انت شايفها في الكود اللي قدامك
يعني مثلا في المثال اللي فوق احنا عارفين ان لو اول ٣ شروط متحققوش مفيش اي حاجة هتتنفذ فنخلي الكود بالشكل ده
المشكلة اللي فاتت بتأثر على عامل من العوامل اللي بنقيس بيها جودة الكود المكتوب اسمها ال Cyclomatic Complexity لو حابب تعرف اكتر en.wikipedia.org
شكل تاني من الجمل الشرطية هو ال input validation في الشكل ده انا مش بأثر على سلوك البرنامج ولا الخطوات اللي بينفذها، انا بس محتاج اتاكد ان المدخلات اللي جايه هي حاجات انا متوقعها ومطابقة للشروط اللي البرنامج بتاعي بيتطلبها زي المثال ده كده
المثال ده بنحاول نعمل حاجة مبسطة اوي من كاشير وفيه method بتمثل عملية الشرا، للتبسيط انا شيلت كل الحاجات اللي تخص البيزنس واحتفظت بس بال input validation. الكود ده مفهوش مشكلة ال nesting لانه واضح اننا استخدمنا الاسلوب اللي فات في اننا ن fail fast and return early
بس لازال الكود كبير جدا عشان يعمل حاجة بسيطة مقارنة بحجمه وهو انه يخصم فلوس من الكارت واغلب الكود ده متلخص في شوية الجمل الشرطية بتاعة ال input validation. طبعا المشكلة دي ليها حلول كتير جدا على حسب حجمها وعلى حسب مدى تكرار طبيعة المدخلات دي في البرنامج.
ممكن نقول لو عندك حاجات بتتكرر كتير تقدر تعملها Shared Class او مثلا لو عندك مدخلات كتير محتاج تتأكد من صحتها ممكن تلمهم في function لوحدهم زي المثال ده
الكود بقى شكله احسن شوية، قادر تفصل السلوك المطلوب من البيزنس عن ال input validation. طبعا ده تطور عن الكود القديم بس اللي حصل انك زقيت الحتة الكبيرة دي في حتة تانية انما هي لسه حجمها كبير وفيها تكرار لانك ترمي ال exception.
حل تاني هو اننا نستخدم شوية utility functions بتساعدنا اننا نعمل كود دفاعي اكتر وفي نفس الوقت شايل عننا هم اختيار ال exception واننا نرميه وبيركز اكتر على الشرط والرسالة زي مثلا في جافا Guava Preconditions
وده الحل الافضل بالنسبة لي
هنا احب اوضح ان فيه حاجة اسمها Design by Contract تقدر تقرا عنه وتاخد اللي يفيدك منها. ال Preconditions اللي استخدمتها هنا هي تشبه في الاسم وشوية في الوظيفة للي موجودة في الباترن الا ان الباترن اكبر منها ومختلفة عنها في شروطها
en.wikipedia.org
تالت اشهر مشكلة في رأيي بتواجه الجمل الشرطية، هو لما يتم استخدامها على الانواع. واظن ان دي الحالة الوحيدة اللي ممكن اتفق (الى حد ما) مع الناس اللي بتقول ان الجمل الشرطية شر لابد من تجنبه وتعالوا نشوف المثال ده
هنا المشكلة بتقول ان فعلا عندك كائنات المفروض يكون ليها سلوك مختلف عشان هي ليها طبيعة مختلفة ومع ذلك انت حاططهم كلهم تحت نفس تحت المسمى RegularShape وبقت مسئولية الكلاينت انه يحدد نوع الشكل الهندسي ده ويبتدي يحسب المساحة بنفسه وبقى عارف ازاي يحسب المساحة لكل واحد
ده معناه ان لو بقى فيه اكتر من كلاينت وعاوزين يحسبوا المساحة يا اما كلهم هيتعلموا يحسبوا المساحة لكل شكل يا اما هنعمل Shared utility class واللي هي في حد ذاتها مشكلة في رأيي لان كده بقى فيه logic يخص الشكل محطوط برا تعريف الشكل ده
اشهر حل للمشكلة دي هو ال Polymorphism لو بصيت على المثال ده هتلاقي اننا تخلينا عن الجمل الشرطية تماما لصالح ان عندنا classes بتعرف السلوك واللي بيستخدم الاشكال دي هو مش مهتم بنوع الشكل ولا ازاي يتحسب مساحته هو بس مهتم يعرف قيمة المساحة دي
بكده اكون اتكلمت عن المشاكل اللي باشوفها منتشره وايه الحلول اللي بالجألها في الحالات دي طبعا في مشاكل تانية اقل شهرة وفيه patterns تانية برضة ممكن نستخدمها ودي اساميها لو حد عاوز يزود
1. Strategy Pattern
2. Template method Pattern
واللي هم نقدر نعتبرهم شكل خاص من الحل الاخير اللي هو الاعتماد على ال polymorphism
3. Specifications pattern
4. Responsibility chain
5. Design by contract

جاري تحميل الاقتراحات...