دورة حياة المشروع البرمجي: مقدمة


مستوى المقال: مبتدئ

بسم الله الرحمن الرحيم

السلام عليكم ورحمة الله وبركاته

 

مقدمة

سأتحدث في هذا الموضوع عن دورة حياة المشروع البرمجي ولن يكون موضوع واحد فقط وانما عبارة عن سلسلة مواضيع سأتحدث بها عن SPLC -وتعني Software Project Life Cycle- للمستقلين، وأعني بالمستقلين المبرمجين الذين يعملون بشكل مُستقل وليس مع فريق، والسبب الرئيسي لتحدثي عن هذا الموضوع هو انعدام جودة أغلب المشاريع البرمجية التي تتم بشكل فردي أو يتوقف تطويرها في مرحلةٍ ما بسبب عدم فهم الكثير من الأمور التي تتعلق بالمشروع البرمجي وقد تسبق كتابة الكود ايضاً.

 

ملاحظة: SPLC هو مصطلح غير علمي والمصطلح المعروف SDLC -وتعني System Development Life Cycle- ولكن في هذه الدروس لن أتحدث عن دورة حياة تطوير المشروع بشكل خاص وانما عن دورة حياة المشروع البرمجي بشكل عام.

 

جدول المصطلحات الهامة المستخدمة

تمت الإشارة للمصطلحات الهامة باللون الأخضر

المصطلح الوصف
Ad Hoc Approach الطريقة الخاطئة التي يتبعها المستقلين حالياً.
SDLC System Development Life Cycle دورة حياة تطوير البرمجيات.
SPLC Software Project Life cycle دورة حياة المشروع البرمجي. وهو مصطلح غير علمي كما ذكرنا.
Standard هي عبارة عن معايير ونماذج تحددها شركات كبيرة، وهذه النماذج مختبرة، ومجربة، وتم اثبات جدارتها، وتمنح الشركات المطبقة لهذه النماذج او المعايير بالشكل الصحيح شهادات اعتماد.
Phases مراحل.
Models نماذج.
Build اصدار من البرنامج يكون مكتمل ويكون محدد باصدار؛ مثال: Buld 1، Build2...الخ.
GUI Graphical User Interface واجهة المستخدم.
AI Artificial intelligence الذكاء الاصطناعي.

 

اولاً ماهو المشروع البرمجي؟ وما الهدف منه اصلاً؟

يوجد الكثير من الأشخاص الراغبين في تعلم البرمجة او لنكون دقيقين يرغبون في تعلم لغة برمجة، وذلك بهدف برمجة تطبيق او موقع على الانترنت، او حتى برنامج سطح مكتب، او لعبة...الخ ولكن للرغبة نوعان: نوع قد يكون بهدف، والأخر قد لا يكون بهدف؛ ومن هذا المنطلق نستطيع القول ان المشروع البرمجي هو هدف مبني على رغبة، وليس رغبة بحد ذاتها، وهذا الهدف لا يكون الا لحل مشكلة انسانية او تسريع اعمال او للقيام بالامور الحسابية بشكل فاعل وأسرع، أو حتى بالمجال الطبي أو بالمجال الاقتصادي، وبالغالب كل مجالات الحياة الانسانية، وبسبب هذه الأهداف أصبحت الرغبة بتسريع الأمور  وتسهيلها هاجس انساني بحت، حتى وصلنا اليوم الى الـ AI وتقدمنا فيه بشكل كبير. 

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

 

ثانياً ماهي المشكلة بالطريقة المتبعة حالياً من قبل المستقلين؟

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

تعريف Ad Hoc Approach: هي الحلول المتبعة او الطرائق التي يتخذها المبرمج لإنجاز مشروعه، وهذه الحلول او الطرائق تكون غالباً مبنية على رؤية المبرمج -وليس بطرق مُنظمة بُنيت على الكثير من التجارب التي تم اثباتها-، وغالباً هذه الطرق التي يتخذها المبرمج غير قابلة للاستخدام في مشاريع او اهداف اخرى وذلك لعدم كفائتها فهي غالباً وإن لم تكن دائماً تُنتج مُخرجات ذات جودة رديئة تكون غير قابلة للإختبار، أو التطوير، او قد تكون غير قابلة للتعديل لاحقاً.

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

ثالثاً ماهي دورة حياة تطوير البرمجيات (SDLC):

SDLC او System Development Life Cycle هي دورة حياة تطوير البرمجيات، وتعتبر هذه الدورة بكل مراحلها من ضمن مجالات هندسة البرمجيات، والتي تهدف لتفصيل الإجراءات والأساليب المتبعة لحوكمة وضبط عمل فريق تطوير البرمجيات، والتي أصبحت أساس من أساسيات بناء اي مشروع برمجي، وقد تختلف المراحل من مشروع الى أخر حسب حجم واحتياجات المشروع، وتطبيق جميع المراحل يجعل من المشروع ذا جودة عالية جداً، وموافق للمعايير القياسية (Standard).

 

مراحل دورة حياة تطوير البرمجيات (SDLC):

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

1 - Feasibility Study دراسة الجدوى.

2 - Analysis التحليل.

3 - Design التصميم.

4 - Implementation التنفيذ.

5 - Testing الاختبار.

6 - Maintenance الصيانة.

7 - Evaluation التقدير.

 

598e0ba246581_Group3.png.35a58fd564f129738ae6a4a1265e7471.png

 

المراحل الأساسية والمتعارف عليها:

1 - Planning التخطيط.

2 - Analysis التحليل.

  • Requirement المتطلبات
  • Definition المفاهيم

4 - Design التصميم.

5 - Implementation التنفيذ.

6 - Testing الاختبار.

7 - Deployment التنصيب.

8 - Maintenance الصيانة.

9 - Evaluation التقدير.

Background.png.7180b24a3a7c4355f1cb04c00313382c.png

 

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

 

ملاحظة: أساس من أساسيات بدأ او تنفيذ اي مشروع برمجي هو اختيار طريقة تنفيذ SDLC وفي الشطر التالي من هذا الموضوع سنتحدث عن هذه الطرائق او النماذج.

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

ملاحظة: قد تختلف مسميات بعض المراحل فمثلاً Implementation يطلق عليها احيانا Development.

 

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

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

Requirement المتطلبات: هي رغبات العميل، وتطلعاته وهي مهمة جداً في فهم المشروع وتحديد مشكلة العميل وماذا يريد بالضبط.

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

د. مرحلة الاختبار: في هذه المرحلة يتم اختبار المشروع، والتحقق من أنه يعمل بشكل جيد ويوجد نوعين من الاختبارات الأساسية Black Box Testing و White Box Testing وسنتعرف على هذه الانواع لاحقاً.

ك. التنصيب: وهي عملية نقل المشروع من بيئة التطوير الى بيئة التشغيل في مكان العميل.

ص. الصيانة: أهم مراحل SDLC وقد تكون الأكثر ثمناً والأطول في المدة.

 

رابعاً كيف ابدأ المشروع البرمجي؟

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

ملاحظة: سأطلق على Models لاحقاً بالطرائق أو النماذج.

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

ومن هذه النماذج (الطرق) نذكر:

1 - Code and Fix: وهذه الطريقة مستخدمة كثيراً من قبل أغلب المستقلين وهي سيئة جداً في حال تم تطبيقها لمشروع كبير او متوسط الحجم، وهي بكل بساطة نبدأ بكتابة الشفرة البرمجية حتى ننتهي، في حال ظهور مشاكل نصلحها او حتى نحصل على رضا المستخدم، ثم نبدأ بكتابة بقية الشفرة حتى ننتهي، وفي حال ظهور مشاكل نصلحها او حتى نحصل على رضا المستخدم، ونستمر بهذه الدورة حتى يكتمل المشروع.

لاحظ في هذا النموذج استخدمنا مرحلة ال التخطيط، والتنفيذ فقط.

Background1.png.55cc7c39ca389d18d9d61cd3c18d2cca.png

 

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

 

2 - Incremental: هذه الطريقة تستخدم كثيراً في التطبيقات العامة التي يتم تطويرها وبيعها للمستخدمين، وهذه الطريقة جيدة ولكن لها سلبياتها للأسف، وهي بكل بساطة أن نعمل اصدارات للمشروع البرمجي وكل اصدار يسمى Build وكل Build أثناء تنفيذه يتم تطبيق جميع مراحل SDLC تقريباً  بشكل تكراري Itrative، وسنتحدث عن هذه المراحل في موضوع أخر ان شاء الله.

 

3 - Agail: هذه الطريقة هي دمج مابين Incremental و Itrative وتركز على تنفيذ المشروع بالشكل الذي يحقق رضا العملاء، عن طريق التسليم السريع للمنتج، وهذه الطريقة تعتبر سلسة جداً من ناحية الاستخدام وهي من الطرق التي يستطيع استخدامها المستقلين.

Background2.png.05589c7bc67815af871e28ea1ffc6391.png

 

ملاحظة: هذه بعض النماذج التي احببت ذكرها، وهي نماذج جيدة جداً، ويستطيع المستقل استخدامها بسلاسة نوعاً ما.

خلاصة: اذاً اجابتاً على السؤال: كيف ابدأ المشروع البرمجي؟ الاجابة تكمن في اختيار الطريقة او النموذج الصحيح؛ واختيار نموذج او طريقة العمل ليس سهل وانما يتطلب خبرة عالية وفهم عميق للمشروع، ولكن لا تقلق حتى لو كنت مبتدأ فمعرفتك البسيطة بهذه النماذج سوف يساعدك كثيراً على اختيار الصحيح -تقريباً- منها.  على كُل حال فهذه النماذج قد لا تكون واضحة للبعض ولكن لاحقاً في موضوع أخر سنشرح هذا النماذج بشكل أفضل ونشرح طرق الاختيار.

 

خامساً تحليل وتلخيص المعلومات:

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

  • ماهي المشكلة مع الطريقة التي يتبعها المستقلين في مشاريعهم البرمجية.
  • ماهي المخاطر الممكنة او المتوقعة التي تسببها الطرق الخاطئة في تنفيذ المشاريع البرمجية.
  • كيف ابدأ ببناء مشروع برمجي ذو جودة عالية.
  • SDLC و SDLC Models.

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

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

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

د. SDLC و SDLC Models: دورة حياة تطوير المشروع البرمجي SDLC هي مجموعة مراحل يجب تنفيذها لبناء المشروع البرمجي بشكل صحيح، وطريقة تنفيذ هذه المراحل يكمن من خلال نماذج دورة حياة تطوير المشروع البرمجي SDLC Models.

 

خاتمة

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

 

الموضوع التالي دورة حياة تطوير البرمجيات: المرحلة الأولى التخطيط

 

هذا وصلى الله وسلم على نبينا محمد وعلى آله وصحبه اجمعين

Nawaf Alshareef

2


اراء المستخدمين


لاتوجد تعليقات لعرضها .



انشئ حساب جديد او قم بتسجيل دخولك لتتمكن من اضافه تعليق جديد

يجب ان تكون عضوا لدينا لتتمكن من التعليق

انشئ حساب جديد

سجل حسابك الجديد لدينا في الموقع بمنتهي السهولة .


سجل حساب جديد

تسجيل الدخول

هل تمتلك حساب بالفعل ؟ سجل دخولك من هنا.


سجل دخولك الان

Ads Belongs To Nawaf Alshareef

  • ماهي قاعدة بيانات الـMongoDB؟
    في السابق كان الحديث حول قواعدة البيانات المعروفه و المتوارد بين اقطاب المبرمجين من مختلف الأصعدة ابتدا من web developers إلى الـsoftware developers على مختلف المنصات windows, OSX, Linux و جل الحديث كان يدور حول نوع واحد فقط وهو RDBMS Relational database management system مثل  MS SQL Server, IBM DB2, Oracle, MySQL, and Microsoft Access  التي تعتمد في حفظ البيانات داخل جداول ولكن في الآونة الأخيرة و بعد صدور عدد من JS Frameworks  و ارتفاع عدد مستخدمي لغة الجافاسكربت بدأت شركة 10GEN في العمل على قاعدة بيانات من نوع مختلف تماما عما سبق ذكرة وهي NoSQL تحت اسم MongoDB اي قاعدة بيانات لا توجد بها علاقة بين الجداول وتعتمد في حفظ البيانات كمستندات BOSN ويعد هذا النوع الأشهر بين عائلة الـNoSQL وهنا ننوه بأن جميع ما تعرفه عن الـSQL Databases قد يتغير فبالتاكيد لن يكون هناك كوريز بالطريقة التي اعتدت العمل عليها.
     
    1- أمثله
    وبما ان الكثير من المبرمجين لديه خلفية في الـMySQL سأقوم بمقارنة سريعة حول الأختلافات السطحية بين المونجو والـMySQL:
    اسم الـTable في الـMongoDB هو Collection اسم الـRow في الـMongoDB هو Document تعتمد قواعد بيانات الـRDBMS على الجداول كالنحو التالي:
     

     
    بينما قاعدة بيانات الـMongoDB تعتمد على BSON وهذا يعني Binary Encoding Of JSON Objects وتكون كالنحو التالي:
    { "_id" : ObjectId("57fe832b13e6a51130a23d2a"), "ID" : 1, "username" : "abdulla", "email" : "[email protected]" } { "_id" : ObjectId("57fe832b13e6a51130a23d2b"), "ID" : 2, "username" : "omar", "email" : "[email protected]" } { "_id" : ObjectId("57fe832b13e6a51130a23d2c"), "ID" : 3, "username" : "mohammed", "email" : "[email protected]" }  
    امثلة حول الفروقات في عمليات الـQueries مابين الـMongoDB و الـMySQL OR RDBMS ولنفترض بأن لدينا جدول و كولكشن يحتويان على عدد من الصفوف والدوكيومنتس فيهم معلومات حول مستخدمين
    عرض جميع المستخدمين من هم دون السن الـ24 SELECT * FROM users WHERE age < 24 db.users.find({"age": { $lt: 24 }}) // $lt = less than  
    عرض جميع المستخدمين الذين  اعمارهم مابين الـ20 والـ30 SELECT * FROM `users` WHERE `age` BETWEEN 20 AND 30 db.users.find({ age: { $gt: 20, $lt: 30 }}) // $gt = greater than  
    عرض المستخدمين الذين اسمائهم تحتوي على حرف A في الاول او الاخير او المنتصف لايهم SELECT * FROM `users` WHERE username LIKE %A% db.users.find({username: /A/})  
    و في حالة الإضافة INSERT INTO `users` (username,age,status) VALUES ('abdulla',25,'active') db.users.insertOne({username: "abdulla", age: 25, status: "active"})  
    ولكن هناك فارق كبير في هذه الكويري و بما ان قاعدة بيانات الـMongoDB ليست Relational بالتالي ليس هناك Schema محدده عند الإضافه فتستطيع مثلا إضافة document بمتغير col,field ليس موجود في الـdocument السابق او التالي في نفس الـCollection وبهذا يقال للـMongoDB بأن اهم مميزات هذا النوع من قواعد البيانات بأنه Flexible او Dynamic Schema  ومثال على ذلك:
    db.users.insert([ { username: { fname: "abdulla", lname: "bahraini" }, age: 25, status: "active" }, { username: "mohammed", age: 19, status: "not active" } ])  
    2- لماذا التحول الى MongoDB ( وجهة نظر )

     
    كما اسلفنا سابقا ومع صدور عدد من js frameworks وبالاخص Meanjs المعني ب expressjs , angularjs & nodejs بالاضافه الmongodb و توسع هذه الفريموركس بشكل ضخم و رهيب جدا ومنها النود التي اصبحت خطر داهم على لغة الphp مقارنة بالسرعة, الاداء الرهيب وتناغم المونجو مع هذه الفريموركس بشكل افضل سبب في توجه الكثير من المطورين الى المونجو.
     
    ليس عند هذا الحد وحسب بل نظرا الى سرعة المونجو حسب الاحصائيات تبين اهمه الانتقال من قواعد البيانات الاعتيادية الى المونجو.
    تجربة اضافه 10000 صف و دوكيومنت في MySQL و MongoDB .. نلاحظ الفرق في سرعة الاداء احتاج المونجو الى ثانتين لتنفيذ المهمه بينما الMySQL احتاج الى 3 دقائق تقريبا.
     


     
    3-التثبيت
    لتثبيت الـMongoDB قم بالدخول على الرابط واختر ما يناسب نظام جهازك
     
    بعد التثبيت إن كنت  من متسخدمي الوندوز انشأ مجلد في داخل الـC (في حال تم تثبيت المونجو في السي)
     
    أضف المتغير التالي في PATH Environment وتجده في المسار التالي
    this pc >> proprieties >> Advanced System Settings >>  Advanced tab >> Environment Variables >> in System Variables find PATH then Click Edit
     
    افتح الـCMD واكتب الكوماند التالي لتفعيل خدمه الـMongoDB في جهازك وستعمل على بورت 27017 بشكل افتراضي
     
    ثم افتح CMD أخر واكتب الكوماند التالي للدخول على MongoDB SHELL
     

     
    بالتالي ستكون داخل الـMongoDB SHELL وتستطيع التعامل معه من خلال الاوامر المباشرة وللإطلاع اكثر اكتب help
     
    مستوى المقال: مبتدئ

    بواسطه AbdullaScript , في

  • المستوى: مُبتدأ/متوسّط
     
    يُمكن الاستفادة من مكتبة Multer في nodejs لرفع الصور والملفّات إلى السيرفر، فبأسطر برمجية بسيطة يُمكن رفع الملفات التي قام المُستخدم بتحديدها
    let app = require("express")() let multer = require("multer") let upload = multer({ dest: 'uploads/' }).any() app.get("/", (req,res)=>{ res.send("Teting...") }) app.post("/upload", (req, res)=>{ upload(req,res, (err)=>{ if (err) throw err }) res.send(req.files) }) app.listen(3000, ()=>{ console.log("Let's Upload....") }) الكود السابق يقوم باستلام الملفّات التي يُرسلها المستخدم إلى المسار /upload ليقوم برفعها ثم طباعة اسم الملف المُستلم. لكن وبعد تنفيذه قد تتفاجئ بأن عملية الرفع تجري بنجاح، إلا أن الاسم لا يظهر ويتم إرسال مصفوفة فارغة على الرغم من أن عملية الرفع تمّت دون مشاكل.
    السبب في ذلك هو طبيعة Nodejs، والتي سبق وأن تحدّثت عنها في مقال سابق بعنوان "تنفيذ الطلبات بتسلسل وترتيب في Nodejs باستخدام Async/Await". انصحك بقرائته لفهم آلية عمل إطار العمل بشكل كامل.
    ما يحدث على أرض الواقع هو أن النظام يبدأ بالرفع، ولأن تنفيذ المهام في nodejs يتم بشكل متوازي لتجنّب تأخير الرد على طلب المستخدم، سيقوم النظام فورًا بطباعة محتويات مصفوفة الملفّات req.files، التي ستكون فارغة بالفعل لأن النظام لم ينتهي بالأصل من عملية الرفع. والحل في هذه الحالة هو استخدام async/await ليُصبح الكود من الشكل:
    let app = require("express")() let multer = require("multer") let upload = multer({ dest: 'uploads/' }).any() app.get("/", (req,res)=>{ res.send("Testing Routes.....") }) let uploadPromise = (req, res)=>{ return new Promise((Resolve, Reject)=>{ upload(req,res, (err)=>{ if (err) Reject(err) Resolve() }) }) } app.post("/upload", async(req, res)=>{ try{ await uploadPromise(req, res) res.send(req.files) }catch(uploadErr){ throw uploadErr } upload(req,res, (err)=>{ if (err) throw err }) }) app.listen(3000, ()=>{ console.log("Let's Upload....") }) حاول تنفيذ الكود السابق وسترى أن اسم الملف سيظهر دون مشاكل لأن النظام قام أولًا برفع الملف ثم قام بطباعة الاسم، وهذا يعني أن المصفوفة لم تعد فارغة بشكل كامل. الفيديو التالي يشرح الفرق بشكل عملي:
    أما الراغبين بتحديد لاحقة الملف أو قبول نوع مُحدّد من الملفات فهم بحاجة لتعديل بعض جزئيات الكود، ولتجنّب تعقيد الأفكار ما بين Async/Await، سأقوم باستخدا مثال بسيط عن Multer.
    let app = require("express")() let multer = require("multer") let upload = multer({dest: "uploads"}) app.post("/", upload.single("photos"), (req,res)=>{ res.send("OK...") }) app.listen(3000, ()=>{ console.log("Ready to upload...") }) الكود السابق يشرح طريقة رفع ملف إلى مُجلّد uploads باستخدام multer، فعند طلب الرابط domain.com/ باستخدام POST فإن النظام سيأخذ الملف الموجود في الحقل photos وسيقوم برفعه. لكن ماذا لو أردنا تغيير الاسم أو اختيار اللاحقة؟ الأمر يتم من خلال ميثود موجودة داخل multer تُعرف بـ diskStorage ليُصبح الكود من الشكل
    let app = require("express")() let multer = require("multer") let storage = multer.diskStorage({ destination: function(req, file, cb){ cb(null, "uploads") }, filename: function(req, file, cb){ let ext = file.mimetype.split("/") ext = ext[ext.length-1] cb(null, file.originalname + "-"+Date.now()+"."+ext) } }) let upload = multer({storage:storage}) app.get("/", (req, res)=>{ console.log(Date.now()) }) app.post("/", upload.single("photos"), (req,res)=>{ res.send("OK...") }) app.listen(3000, ()=>{ console.log("Ready to upload...") }) قُمنا في الميثود بتعريف خاصيّتين الأولى هي destination الخاصّة بتحديد مكان الرفع، والثانية هي اسم الملف. الشرط الوحيد في الخصائص داخل multer هو استخدام دالة cb، وهي اختصار لـ Call Back لتمرير النتيجة التي نرغب بها.
    في مثالي في الأعلى قُمت بفحص نوع الملف باستخدام الـ mimeType الخاص به، فلو كان صورة سيظهر بالشكل image/jpeg أو image/png وهكذا. بعدها قمت بإضافة تلك اللاحقة للاسم الذي يُمكنك تسميته كيفما تشاء. أما بخصوص رفع نوع واحد من الملفات دونًا عن الغير فهذا مُمكن عبر تعديل السطر الخاص بتعريف upload ليُصبح من الشكل 
    let upload = multer({storage:storage, fileFilter: function(req, file, cb){ if (file.mimetype != "image/jpeg"){ return cb(null, false) } cb(null, true) }}) قُمنا بإضافة ما يُعرف بالـ fileFilter، وهي خاصيّة موجودة في multer قُمنا فيها بفحص نوع الملف مرّة أُخرى عبر mimeType وفي حالة عدم مُطابقة الشروط نقوم برفض الملف من خلال استخدام إعادة الـ callback فارغ مع false. بهذه الحالة سيقفز النظام عن الملف وسيتجاوزه.
    الفيديو التالي يشرح كل شيء
     
    في حالة وجود أي استفسار يُمكن تركه في التعليقات أو مُراسلتي عبر حسابي في تويتر @FerasAllaou
    مستوى المقال: مبتدئ

    بواسطه feras , في

  • السلام عليكم ورحمة الله وبركاته 
    طرحنا مسابقة عالم البرمجة للنقاش الهادف ، و هدفنا إثراء المحتوى العربي في مجال البرمجة ، فاز معنا الطرح المتميز و المفيد حيث قام بتقييم المقالات وترقيتها فريق عالم البرمجة سنذكر بهذه المقالة الفائزين معنا ، و مقالاتهم ، و نشكرهم على ماقدموا من فائدة للجميع ، و إثراء المحتوى العربي في البرمجة.
     
    الفائزون في شهر January 2018
    المقال الفائز:
    المقال الفائز:
    المقال الفائز:
    المقال الفائز:
    المقال الفائز:
    المقال الفائز:
    المقال الفائز:
    المقال الفائز:
    المقال الفائز:
    المقال الفائز:
     
     
    في الختام:
    هدفنا في موقع عالم البرمجة إثراء المحتوى العربي في مجال البرمجة ، و تعزيز حب المساعدة بين المبرمجين تستطيع كتابة ماتحب في ساحات النقاش ، و يمكن تكون احد الفائزين معنا  بمسابقة عالم البرمجة للنقاش الهادف فهي مازالت مستمره ايضا تستطيع مساعدة المبرمجين بالإجابة عن أسئلتهم ، و حل المشاكل التي تواجههم بقسم سؤال وجواب ؛ لتكون مرجع لبقية المبرمجين شعارنا في عالم البرمجة "إن في قضاء حوائج الناس لذة لا يَعرفها إلا من جربها، فافعل الخير مهما استصغرته فإنك لا تدري أي حسنة تدخلك الجنة." -ابن القيم-  وممكن تستفيد من
    حبيبي القارئ اعلم ان فريق عالم البرمجة يصب كل جهودة لمساعدة المبرمجين الذين يخصصون من وقتهم لنشر العلم المفيد ويساعدون الغير ويارب يقدرنا نوقف معكم ونساعدكم قد مانقدر.
    مستوى المقال: مبتدئ

    بواسطه Ali Majrashi , في

  • بسم الله الرحمن الرحيم
    السلام عليكم ورحمة الله، كيف حال الجميع؟ عساكم بألف خير و عافية.
    سأحاول باذن الله البدأ في سلسلة جديدة حول تعلم أساسيات رياكت (React) و (RN = React Native) كما تعلمون هي مكتبة عرض (View) أطلقتها شركة الفيسبوك لبناء واجهاتك البرمجية (User Interfaces)  بطريقة سلسة و سهلة مبنية على نظام (Virtual DOM). و أول نسخة رسمية منها بتاريخ مارس 2013. و لما نقول أنها مكتبة عرض ليست اطار عمل (MVC) ركّز هنا جيّداً أخي القارئ؛ حيث تمثل هي حرف (V) فقط لا تقدم خدمة المتحكم (Controller) و لا (Model).
    بداية تعلمك React يصادفك شئ جديد عند كتابة أول مكوّن (Component's) حيث أنها تعود (returning) بصيغة تشبه صيغة HTML! ربما لم تلاحظها في مكتبات أو أطر عمل أخرى. تسمى بالـ JSX
    فما هي يا ترى JSX ؟ 
    JSX عبارة عن صيغة (syntax) أقول أُخترعت لمكتبة React التي تبدو مشابهة جداً لـ xHTML التي تمكنك من انشاء عناصر واجهتك البرمجية (Create Elements) بسهولة و يسر عن طريقها بدلاً من استعمال وضائف (functions) تستدعيها يدوياً لتنفذ مهمة معيّنة. ربما هذه نقطة مبهمة للبعض لكن ستفهمها بعد قليل باذن الله.
    من المهم أن تعلم أن جميع مكونات React المبنية بصيغة JSX تترجم من شفرة لشفرة (transpiler) الى تعليمات جافاسكربت حقيقية (Real JavaScript) باستخدام مكتبة تدعى بابل (Babel) تقوم بتحويل الرياكت الى شفرة ES5 القديمة لتشتغل على جميع المتصفحات (حتى القديمة منها).
    لنكتب مثالا بسيطاً بالـ JSX : 
    return <span> أهلا بعالم البرمجة! </span>; هل لاحظت سهولة كتابة جملة، و ارجاعها للظهور في المصتفح بكل سهولة مرفقة بكلمة (Return). تخيّل لو كتبناها بصيغة ES5 القديمة؟! 
    return React.createElement( 'span', {}, 'أهلا بعالم البرمجة!'); كم سطراً كتبناه لنعيد الجملة للظهور باستخدام جافاسكربت طبيعية! في هذا المثال استعملنا وظيفة (function) تسمى بـ React.createElement صيغتها كالتالي: 
    React.createElement( string|element, [propsObject], [children...]) ماذا لو أردنا كتابة عدة جمل متفرقة بداخل الشفرة البرمجية! ستكون هكذا بلا شك!
    React.createElement('div', {}, React.createElement('div', {}, 'text1'), React.createElement('div', {}, 'text2', ) ); لكن لسهولة JSX و هذا ما تميّزت به شركة الفيسبوك صراحة في مكتباتها البرمجية، الشفرة السابقة مثلاً باستخدام JSX : 
    function text1() { return <span>text1</span>; } function text2() { return <span>text2</span>; } هنا نستنتج مرة أخرى، أن JSX رائعة جدا و اختزال (shorthand) لكثرة الشفرات البرمجية التي تؤدي نفس الوظيفة. مما يكلفك وقتا اضافيا و كثرة المشاكل (bug's) عند تنقيح برمجياتك و تطبيقاتك؛ هذا كود شامل و أوسع، تلاحظ أنه يمكنك من تقسيم واجهاتك البرمجية عبر مكونات مختلفة و التحكم بها كلٌ على حِدة.
    من الثلاث خصائص المتوفرة في JSX هي : 
    العناصر المتداخلة (Nested elements): حيث يمكنك الجمع بين عدة عناصر (Multiple elements)  في حاوية واحدة (container element) كـ <div> مثل المثال الذي بالأسفل.
    السمات (Attributes): داخل كل عصنر div لك أن تضيف وظائف متعددة كـ (className، selected، style) ..الخ. 
    تعبيرات الجافاسكربت (JavaScript expressions): يمكنك اضافة تعابير (ليست شرطية statements)  داخل JSX كعمليات الحساب و المهم أن تكون ضمن قوسين {} .
    import React from 'react'; class App extends React.Component { render() { return ( <div> <p>Header</p> <p>Content</p> <p>Footer</p> </div> <div> <h1>{10+1}</h1> </div> <div style={{ height: 10 }}> Hello World! </div> ); } } export default App; في التعبيرات ذكرنا أنه لا يمكن استخدام التعابير الشرطية كـ if و else باستثناء التعبير الشرطي الثلاثي: { i === 1 ? 'true' : 'false' }  مثال : 
    import React from 'react'; class App extends React.Component { render() { const i = 1; return ( <div> <h1>{ i === 1 ? 'true' : 'false' }</h1> </div> ); } } export default App; من النصائح التي أقدمها و لا يجب عليك نسيانها: جميع أسماء المكونات (components) تكتب بحروف صغيرة (lowercase) التي تكون مدمجة بـعناصر HTML أو SVG كـ (div, ul, rect, etc.) و لا تنسى اغلاق العناصر بأوسمتها (Close Every Element) مثال مبسط: 
    // DO THIS: return <br/>; return <input type='password' .../>; return <li>text</li>; // NOT THIS: return <br>; return <input type='password' ...>; return <li>text; هذه أهم أساسيات JSX التي يجب على كل شخص معرفتها لمحبي تعلم ReactJS و RN عموماً. أتمنى تكون مفهومة للجميع. 
    و السلام عليكم.
    مستوى المقال: مبتدئ

    بواسطه عبدالهادي , في

  • بسم الله الرحمن الرحيم
    السلام عليكم ورحمة الله وبركاته
    تعرفنا في بداية سلسلة مواضيعنا على طريقة من طرق تخزين البيانات وهي القوائم سواء الأحادية أو الثنائية، كما ونعلم بأن هناك
    طريقة أخرى احفظ مجموعة البيانات وهي أبسط طريقة والتي تتمثل في المصفوفات سواء المصفوفات العادية أو مصفوفات القوائم.
    في هذا الدرس سنتعرف على أحد أفضل الطرق في حفظ البيانات والتي تعتبر من الأفضل من ناحية العرض أو البحث وغيرها
    من الأمور المتعلقة بهذه المجموعة من البيانات. كما هو الحال في القوائم فإن الأشجار لديها أكثر من نوع وكل واحد منهم له خواصة واستخداماته.
    في هذا الدرس سنتعرف على أحد أنواع الأشجار وهو الأشجار الثنائية.
     
    ماذا نقصد بالأشجار الثنائية (Binary Trees):
    هو نوع من أنواع تمثيل البيانات ويتكون من مكونين أساسيين هما العقد (Nodes) و الأقصان (Arcs). 
    عندما نقوم بتمثيل هذه الشجرة فإننا نقلب مفهومها فيكون الجذر (Root) في الأعلى والأقصان في الأسفل.
    سميت بالأشجار الثنائية لأنه كل عقد لديه عقيدين يرتبط فيهم وهما أبنائه ولديه والد واحد.
    هناك بعض المصطلحات التي يجب أن نتعرف عليها قبل الشروع الى صلب الموضوع:
    - العقد (Node): وهو كل عنصر موجود في الشجرة، وهو المكان الذي يتم حفظ البيانات داخله.
    أنواع خاصة من العقد (Nodes):
                   - الجذر (Root): وهو العنصر الذي ليس لديه والد أي أنه أعلى عنصر في الشجرة. وكل شجرة تحتوي على جذر واحد فقط.
                   - الأوراق (Leaves): وهذه هي مجموعة العقد التي ليس لديها أي أولاد. أي أنها في طرف الشجرة.
    - القصن (Arc): هو الرابط الذي يربط العقد بين بعضها وهو ذي اتجاه واحد من الأعلى الى الأسفل.

     
    يختلف مفهوم الشجرة الثنائية Binary Tree  حيث أن بعضها لا تحقق بعض الشروط مما يؤدي بها الى أن تكون عبارة عن قائمة عادية
    لكن الأنواع الأخرى تحتوي على شروط التي تجعلها شجرة فعالة بأكبر قدر ممكن و تسمى بـ Binary Search Tree وهذا اساس جميع ما يلي.
     
    تمثيل الشجرة الثنائية (Binayr Tree):
    ١. عن طريق المصفوفات (ArrayLists): وهذه الطريقة لديها مشاكلها كما ذكراناها سابقاً.
    ٢. عن طريق القوائم الثنائية (Linked lists): وهذه هي الطريق الأمثل لتمثيل الشجر.
     
    أكواد الشجرة الثنائية (Binary Tree):
    أ- إنشاء كلاس خاص بالعقد (Nodes) :
    هذا الكلاس يسمى بـ BSTNode وهو كالتالي:
    public class BSTNode { protected int key; protected BSTNode right, left; public BSTNode(){ this(0); } public BSTNode(int k){ this(k, null, null); } public BSTNode(int k, BSTNode r, BSTNode l){ this.key = k; this.right = r; this.left = l; } public void addRight(BSTNode r){ this.right = r; } public void addLeft(BSTNode l){ this.left = l; } } هذا الكلاس يحتوي على المتغيرات التالية:
    - Key: وهو من نوع و int وهو المكان الذي يتم حفظ البيانات داخله.
     - right & left: وهما القصنان (Arcs) والذان يربطان العقد بأبنيه اليمين والشمال.
    كما نرى فإننا نستطيع إنشاء عنصر من هذا الكلاس سواء كان في بيانات أو لا. لديه أولاد أولا.
    كما وأنه لدينا ميثودين نستخدمها لإضافة ابن لليمين أو لليسار.
     
    ب- انشاء كلاس الشجرة الثنائية (Binary Search Tree):
    public class BST { private BSTNode root = null; public BST(){ } public void clear(){ this.root =null; } public boolean isEmpty(){ return root == null; } public void visit(BSTNode n){ System.out.println(n.key + " "); } } هنا نقوم بانشاء الهيكلة الأساسية للشجرة ويحتوي على التالي:
    - root: الجذر وهو رأس الشجرة والوحيد الذي يربطنا بكامل عناصر الشكرة. وفي بداية انشاء الشجرة يكون الجذر فاضي.
    لدينا الكثير من الميثود لكن سنذكر هنا الأشياء الأساسية ونترك الباقي للدرس القادم بحيث أنها تحتوي على الكثير من التفاصيل:
    * clear(): تستخدم لتفريغ الشجرة من البيانات؛ وبما أن الجذر هو الرابط الوحيد لعناصر الشجرة فإن حذف الجذر سيؤدي الى حذف الشجرة كلها.
    *isEmpty(): وستخدم للاستعمال اذا ما كانت الشجرة خالية أو لا. ترسل true في حال كانت الشجرة خالية.
    *visit(): تستخدم لطباعة قيمة القيمة داخل العقد المرسل.
     
    خلال الشرح القادم إن شاء الله سنتطرق لاضافة وحذف عناصر من الشجرة، كذلك كيف نقوم بطباعة جميع عناصر الشجرة.
     
    اسأل الله العلي العظيم بأني وفقت لاصال المعلومة بابسط طريقة
     
    في حفظ الله
    مستوى المقال: متوسط

    بواسطه Abather , في

  • Ads Belongs To Nawaf Alshareef

    عالم البرمجة

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