Saturday, December 30, 2017

هندسة البرمجيات بالهجايص -- (2) أحط الحاجة فين؟

أصل المقالة دي كانت بوست كتبته على الفيسبوك، فحبيت أعيد نشره لتعم الفائدة...
وده رابط الحلقة الأولى في السلسلة لمن أراد..
"جيت ألم البنطلون الجاكتة ضربت...جيت ألم الجاكتة البنطلون ضرب!" -- سمير غانم 
- الحقيقة احنا بنشوف المرار في البرمجة، تيجي تعدل في حتة في البرنامج ولا تحل bug تلاقي جحيم اتفتح عليك و عمال تعدل في حتة تانية ورا حتة تالتة ورا حتة رابعة. وبيبقى فيه حتت كده في كل برنامج عبارة عن كهف مظلم محدش يجرؤ يقرب له بسبب موضوع تسلسل التعديلات ده. النوع ده من البرامج بيبقى مقاوم للتغيير، بيبقى عامل زي الزجاج كده فيه صلابة rigidity بس فيه هشاشة في نفس الوقت fragility. الوضع ده لما بيكون صفة ملازمة للبرنامج غالبا هاتفكر تهده وتبنيه من أول وجديد، إوعى، وراجع مقالة "إعادة اختراع العجلة في البرمجيات

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

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

البرامج اللي بيجتمع فيها البلاوي اللي فوق دي فيه مصطلح ظريف بيعبر عنها اسمه Big Ball Of Mud يعني كرة الطين الكبيرة!
لو تلاحظ المشاكل اللي فوق دي هاتلاقي إن الاعتمادية dependencies هي جزء أساسي في المشكلة، مش الاعتمادية في حد ذاتها، لكن كثرة الاعتمادية و عمقها - زي ما اتكلمنا فوق - و جزء أساسي في شغلك لما تيجي تظبط برنامج مطين أو تصمم برنامج جديد إنك تكسر الاعتمادية دي، و ده موضوع المقالة دي...أحط الحاجة فين؟

- أول مبدأ معانا هو مبدأ الفصل بين المسئوليات Separation of Concerns [الترجمة متصرفة أنا عارف].

تعالوا نضرب أمثلة توضح المقصود على طول:
= لما بيكون المشروع بتاعك مقسم لطبقات layers ما تخليش مسئوليات الطبقات تدخل في بعضها، يعني مثلا الطبقة بتاعت الواجهة front-end/presentation layer تكون مسئولة بس عن واجهة المستخدم user interface ومافيهاش قرارات ليها علاقة بقواعد النظام business rules و طبعا مش بتوصل لقاعدة البيانات! ده على مستوى بنية النظام application architecture.
= في كل طبقة layer ما تجيش تخلط برضو بين المسئوليات في أجزاء الطبقة دي، يعني مثلا يفضل إنك ما تكتبش html و css و javascript في نفس الملف لأن كل حاجة من دول مسئولة عن حاجة مختلفة. و نفس الكلام لما يكون عندك مثلا class مسئولة عن إدارة حسابات المستخدمين ما تحطش فيها كود له علاقة بإدارة الكتب (لو أنت عامل برنامج لمكتبة مثلا).
= نفس الكلام في قاعدة البيانات، ما تجيش تحط حقول columns مالهاش ارتباط الprimary key (و دي اسمها database normalization بس مش هانتكلم عنها عشان دي قصة لوحدها)
...وهكذا في كل مناحي البرنامج.

- المبدأ ده يقودنا لمبدأ تاني هو التخصص الدقيق Single Responsibility Principle [الترجمة متصرفة جدا المرة دي أنا عارف].

المبدأ بيقولك أي جزء برمجي لازم يكون بيعمل حاجة واحدة بس، و بيعملها كويس. و تقدر تقيس الموضوع ده بإن ما يكونش عندك أكتر من سبب لتغييرالجزء البرمجي ده. تعالوا نخش في الأمثلة:
= عندي method اسمها ParseAndCalculate لاحظ وجود الAnd في الاسم ده دليل على إن الmethod بتعمل حاجتين. طبعا الاسم مش دليل كافي، ممكن يكون مسميها بلحة وبتعمل 5 حاجات. الشاهد إن لما أحب أغير في الParse هاعدل في الmethod ولما أحب أغير في الcalculate هاغير فيها برضو، و ده يتنافى مع مبدأ التخصص الدقيق.
= شفت كود الmethod فيت تتجاوز ال3000 سطر بدون أي مبالغة، بس الحقيقة المبرمج حاطط comments كتير وعامل regions جوه الmethod مبين فيها كل حتة بتعمل إيه. ده مؤشر ظريف إن ممكن الregions دي تتقسم لmethods منفصلة.
= الكلام ده لا يسري على الmethods بس، طبقه بقى على كل حاجة من أول بنية النظام و طبقاته، مرورا بالclasses و الmethods و وصولا لقاعدة البيانات.

- فيه مبدأ تالت مرتبط بالمباديء اللي فاتت دي، ألا و هو مبدأ الاقتران Coupling و التماسك Cohesion [بتتنطق كده كوهيجن، بتعطيش الجيم]. يعني إيه الكلام ده؟

= الاقتران coupling معناه قد إيه الحاجات اللي أصلا مالهاش علاقة ببعض في اعتمادية بينها، و دي قصة الdependencies اللي عمالين نهري فيها فوق، فده بيتكلم عن علاقة الحاجات ببعضها من بره.
= أما التماسك cohesion فبيتكلم عن علاقة الحاجات ببعضها من جوة، يعني لما تشوف حاجة في الclass كده و تقول: "إيه اللي جاب القلعة جنب البحر؟" تعرف إن الclass مش متماسكة و بتعمل حاجات مش بتاعتها.
المبدأ ده تقدر تعتبره معيار لقياس هل تغيير الكود بتاعي سهل و لا صعب، إزاي؟
= الحاجات اللي مقترنة ببعضها tightly coupled بتبقى صعبة التعديل، يعني فيه اعتمادية بينها بحيث لو عدلت في جزء محتاج أعدل في جزء تاني. و أنا مش عاوز كده أنا عاوز الارتباط بينها يكون في حده الأدنى loosely coupled.
= الحاجات اللي مش بتطبق مبدأ التخصص الدقيق بتكون غير متماسكة loosely cohesive ودي برضو بتبقى صعبة في التعديل، يعني فيه أكتر من سبب لتعديل الجزء البرمجي ده. و أنا مش عاوز كده برضو، أنا عاوز التماسك يكون عالي جدا tightly cohesive.
= طيب تعالوا نعيد صياغة المبدأ تاني: حاول توصل لأعلى تماسك و أقل ارتبط strive for tight cohesion and loose coupling عشان الكود بتاعك مايبقاش big ball of mud.

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

No comments:

Post a Comment