5.1الشيفرة النظيفة (clean code) وأنماط التصميم (design patterns) (PEP 8, SOLID)
الأساسي في 30 ثانية
- PEP 8 مؤتمتة : تسمية وتنسيق متوقعان — black/ruff يحسمان، ولا نتناقش بعد في الأسلوب أثناء المراجعة.
- SOLID عملي : مسؤولية واحدة لكل وحدة، والاعتماد على تجريدات (abstractions) — دون تعصب في السكريبتات الصغيرة.
- أنماط (patterns) مسماة : المصنع (Factory)، والاستراتيجية (Strategy)، والمحول (Adapter)، والسياق (Context) — اسم واحد يعادل عشر جمل شرح.
حالة مصغرة متسلسلة — نبيل يرتب سكريبتاته في الجزائر
نبيل، محلل بيانات مبتدئ في الجزائر، يصارع سكريبتات تحليل « تشتغل » لكن لا أحد يعيد قراءتها دون تقطيب : أسماء غامضة، ودالة عملاقة تحمل وتنظف وتحسب وتعرض، وأسلوب مختلف في كل ملف. مرر black/ruff، وأعاد التسمية بوضوح وقسم الدالة العملاقة إلى وحدات أحادية المسؤولية. يروي هذا القسم عبوره إلى الشيفرة الاحترافية — ويستمر الخيط في 5.2 و 5.3 و 5.4.
هذه الحالة نفسها تعود في الدرس والمخطط والنص الجاهز وتحدي 48 ساعة — وتستمر في 5.2 و 5.3 و 5.4.
1. PEP 8 : القواعد المشتركة
في المستوى الاحترافي، الشيفرة تُقرأ أكثر مما تُكتب. PEP 8 هو دليل الأسلوب الرسمي لبايثون (Python) : snake_case للدوال، وPascalCase للأصناف، وUPPER للثوابت، وأسطر محدودة، وسطران فارغان بين الدوال. اتباعه يجعل كل شيفرة متوقعة : يعرف القارئ أين ينظر. توقف نبيل عن إعادة اختراع أسلوبه في كل سكريبت — واعتمد القواعد المشتركة.
النقطة الحاسمة : الأسلوب يُؤتمت. black يعيد التنسيق، وruff (أو flake8/pylint) يبلغ عن الفروق — فلا يُتناقش الأسلوب بعد في المراجعة، والأداة تحسم. نثبت، ونشغل قبل كل commit، ونصحح ما يُبلغ عنه.
2. SOLID عمليا (دون تعصب)
يوجه SOLID التقطيع : مسؤولية واحدة لكل دالة أو صنف، ومفتوح للتوسيع (وسائط، إضافات) لكن مغلق أمام التعديل (نضيف دون أن نكسر)، والاعتماد على تجريدات (abstractions) لا على تفاصيل ملموسة — وفي بايثون يساعد الـ duck typing (« إذا صوت كالبطة فهو بطة »). قسم نبيل دالته العملاقة : دالة تحمل، وأخرى تنظف، وثالثة تحسب — وكل واحدة قابلة للاختبار.
لكن العملية أولا : سكريبت صغير للرمي لا يحتاج مصنعا مجردا. نهيكل ما يكبر ويدوم، ونترك بسيطا ما هو ظرفي. الشيء-الإله (god-object) الذي يفعل كل شيء ومصنع الغاز لخمسين سطرا هما الحافتان الواجب تجنبهما.
3. الأنماط التي تدفع
أنماط التصميم (design patterns) حلول مجربة لمشاكل تصميم متكررة. ما يدفع سريعا في بايثون : المصنع (Factory) (إنشاء الكائن حسب الإعداد)، والاستراتيجية (Strategy) (خوارزميات قابلة للتبديل — قاموس الدوال في المثال)، والمحول (Adapter) (توحيد واجهات API مختلفة خلف واجهة واحدة)، والسياق (Context) (عبارة with خاصة عبر contextlib لتدبير الموارد نظيفا). استبدل نبيل سلسلة elif باستراتيجية مسماة : إضافة وضع أصبحت إضافة مدخل.
مكسب الفريق : نمط (pattern) مسمى في المراجعة يعادل عشر جمل شرح — « إنها استراتيجية » يقول كل شيء. نكتشفها حسب الحاجات، أبدا حفظا دفعة واحدة.
🔎 مثال ملموس — نبيل يستبدل elif باستراتيجية
قبل/بعد black + استراتيجية مسماة.
# قبل : صلب
def calculer(mode, x):
if mode == "tva":
return x * 1.2
elif mode == "remise":
return x * 0.9
# بعد : استراتيجية مسماة
STRATEGIES = {"tva": lambda x: x * 1.2, "remise": lambda x: x * 0.9}
def calculer(mode, x):
return STRATEGIES[mode](x)
القراءة : إضافة وضع = مدخل في القاموس، لا elif إضافية.
الدرس : black . + ruff check . قبل كل commit.
مفردات القسم
- PEP 8
- دليل الأسلوب الرسمي لبايثون (Python)، الذي يجعل كل شيفرة متوقعة.
مثال بسيط: أعاد نبيل تسمية متغيراته إلى snake_case صريحة.
ما ليس كذلك: أداة تسرع التنفيذ.
رد فعل: هل سيقرأ مجهول شيفرتي دون جهد ؟
- الشيفرة النظيفة
- شيفرة مقروءة : أسماء صريحة ودوال قصيرة وصفر تكرار.
مثال بسيط: قسم نبيل دالته العملاقة إلى ثلاث وحدات قابلة للاختبار.
ما ليس كذلك: شيفرة تشتغل لكن لا نجرؤ على إعادة قراءتها.
رد فعل: هل لكل دالة مسؤولية واحدة ؟
- black / ruff
- أداتان تنسقان (black) وتراقبان الأسلوب (ruff) تلقائيا.
مثال بسيط: يشغل نبيل black ثم ruff قبل كل commit.
ما ليس كذلك: نقاش أسلوب يدوي في المراجعة.
رد فعل: هل حسمت الأداة قبل المراجعة ؟
- SOLID
- مبادئ تقطيع نحو شيفرة مفكوكة وقابلة للصيانة، تُطبق دون تعصب.
مثال بسيط: فتح نبيل التوسيع بالوسائط بدل التعديل.
ما ليس كذلك: قائمة تحقق تُؤشر عمياء.
رد فعل: هل تدفع هذه البنية كلفتها ؟
- الاستراتيجية (Strategy)
- نمط (pattern) : خوارزميات قابلة للتبديل خلف واجهة واحدة.
مثال بسيط: أصبحت أوضاع حساب نبيل مداخل في القاموس.
ما ليس كذلك: سلسلة elif تتمدد.
رد فعل: هل يمكنني إضافة حالة دون لمس الموجود ؟
في التطبيق — جعل شيفرتك نظيفة ومطابقة
- استعيدوا سكريبتا قديما وأعيدوا تسمية متغيراته/دواله بوضوح (snake_case، وأسماء معبرة).
- ثبتوا black (pip install black) وشغلوه على الملف : لاحظوا التنسيق التلقائي والموحد.
- ثبتوا flake8 وصححوا تحذيرات الأسلوب التي يبلغ عنها.
- قسموا دالة طويلة جدا إلى عدة دوال قصيرة أحادية المسؤولية : قيسوا مكسب المقروئية.
نص جاهز للقول — اقتراح الأسلوب المؤتمت
« في الجزائر، سكريبتات تحليلنا تشتغل لكن تُقرأ بصعوبة : أساليب مختلفة وأسماء غامضة ودوال عملاقة. أقترح تثبيت PEP 8 مع black و ruff قبل كل commit، وتقطيع الدالة الأكثر إيلاما إلى وحدات أحادية المسؤولية. نقيس مكسب إعادة القراءة، ثم نوسع. »
يُقال في المراجعة لاعتماد التنسيق المؤتمت دون وعد بإعادة كتابة كاملة.
نموذج نسخ-لصق — قائمة تحقق مراجعة نظيفة
مراجعة الشيفرة النظيفة (ملف واحد)
التسمية : snake_case للدوال / PascalCase للأصناف / UPPER للثوابت ؟ ___
التقطيع : هل لكل دالة مسؤولية واحدة ؟ -> للتقطيع : ___
التكرار : نفس المنطق في مكانين ؟ -> للتحليل : ___
الأدوات : هل مر black ؟ ___ · هل ruff check نظيف ؟ ___
النمط : elif يتمدد -> استراتيجية ممكنة ؟ ___
مستقل / ميزانية صغيرة
نبيل وحده : يكفي black + إعادة تسمية صريحة على السكريبت الأكثر قراءة — دون إعادة كتابة كاملة.
مقاولة صغيرة / فريق مصغر
pre-commit مشترك بـ black/ruff : ينتج الفريق كله الأسلوب نفسه دون نقاشه.
مقاولة متوسطة في الجزائر
يبرمج نبيل مراجعة شهرية في الجزائر : دالة عملاقة مقسمة في كل مرة، وأنماط مسماة في المراجعة.
فريق يبدأ
ثنائي : أحدهما يرمز والآخر يراجع بقائمة التحقق ؛ ولا نضيف نمطا إلا على ألم حقيقي.
✓ ممارسات جيدة
- black/ruff في pre-commit : الأسلوب تحسمه الأداة.
- مسؤولية واحدة لكل وحدة : قطع الدالة الأكثر إيلاما أولا.
- تسمية الأنماط في المراجعة : اسم مشترك يعادل عشر جمل.
✗ أخطاء شائعة
- مناقشة الأسلوب يدويا بدل أتمتته.
- بناء مصنع غاز لخمسين سطرا.
- ترك شيء-إله (god-object) يفعل كل شيء (يحمل وينظف ويحسب ويعرض).
النقاط الأساسية
- PEP 8 هو الأسلوب الرسمي لبايثون (Python) : اتباعه يجعل الشيفرة مألوفة للجميع.
- الشيفرة النظيفة = أسماء صريحة + دوال قصيرة + صفر تكرار.
- يعيد black التنسيق تلقائيا ؛ ويكشف flake8/pylint العيوب.
- أنماط التصميم (design patterns) حلول مجربة لمشاكل التصميم المتكررة.
تحدي 48 ساعة — طبق غدا
مرروا سكريبتا واحدا لنبيل تحت black + ruff، وأعيدوا تسمية 5 أسماء غامضة وقسموا دالة عملاقة واحدة : هل إعادة القراءة أسرع ؟
- أستطيع شرح PEP 8 ودور black/ruff في جملة واحدة.
- سكريبتاني أعيد تنسيقه ودون تحذير معطل.
- أعرف متى لا أضيف نمطا.
أسئلة شائعة
هل لأسلوب الشيفرة حقا أهمية إن كانت تشتغل ؟
نعم، كثيرا. الشيفرة تُقرأ أكثر بكثير مما تُكتب. الأسلوب المتسق يقلل الأخطاء ويسرع إعادة القراءة ويسهل العمل الجماعي. إنه معيار رئيسي في المقاولة : الشيفرة النظيفة شيفرة احترافية. ومع black/ruff، لا يكلف هذا الأسلوب شيئا تقريبا : تضمنه الأداة قبل كل commit.
هل يجب تعلم كل أنماط التصميم ؟
لا، أبدا حفظا. افهموا أولا مبادئ الشيفرة النظيفة. واكتشفوا الأنماط حسب الحاجات : حين يتكرر مشكل تصميم، يوجد غالبا نمط (pattern) يحله بأناقة. ومعرفتها بالاسم تساعد على تمييز هذه الحالات — المصنع والاستراتيجية والمحول والسياق تغطي أساس اليومي في بايثون.
ماذا تحدد اتفاقية PEP 8 ؟