اذهب إلى المحتوى

لوحة المتصدرين

  1. محمود سعداوي2

    محمود سعداوي2

    الأعضاء


    • نقاط

      2

    • المساهمات

      510


  2. Ziyad Al Maghribi

    Ziyad Al Maghribi

    الأعضاء


    • نقاط

      2

    • المساهمات

      84


  3. Mustafa Suleiman

    Mustafa Suleiman

    الأعضاء


    • نقاط

      2

    • المساهمات

      8519


  4. بلال زيادة

    بلال زيادة

    الأعضاء


    • نقاط

      1

    • المساهمات

      4376


المحتوى الأكثر حصولًا على سمعة جيدة

المحتوى الأعلى تقييمًا في 09/02/23 في كل الموقع

  1. سنتعرف في هذا المقال على مفهوم واجهة برمجية التطبيقات Application Programming Interface، هذا المصطلح السهل المعقد حيث سنحاول فهمه وكيفية بناء مواقع الويب والتطبيقات الحديثة في يومنا هذا بالاعتماد على الواجهات البرمجية ونجيب على سؤال مهم وهو كيف ترتبط الواجهة الأمامية مع الواجهة الخلفية لتطبيق الويب أو الموقع الإلكتروني. هذا المقال هو جزء من سلسلة مقالات حول الواجهة البرمجية API وكيفية الاستفادة منها في بناء تطبيق ويب: مدخل إلى الواجهات البرمجية API الاتصال بواجهة زد البرمجية وفهم عملية الاستيثاق والتصريح أمثلة عملية لاستخدام واجهة برمجة متاجر زد zid API تطوير تطبيق عملي يزيد من احتفاظ العملاء عبر واجهة زد البرمجية مفهوم الواجهة البرمجية للتطبيقات API قبل أن ندخل في أية تفاصيل تقنية عن موضوعنا اليوم، سأحكي لك يومًا في حياة علي. علي هو مبرمج تطبيقات ويب يعمل في إحدى الشركات التقنية العربية، علي يحب تجربة المأكوﻻت المختلفة، بحيث يجرب في كل يوم أكلة جديدة في المطاعم المحيطة وإن سمع بافتتاح مطعم جديد بالقرب من مكان عمله، فإنه ﻻ يتوانى في زيارته وتذوق مختلف اﻷطباق التي يقدمها. ذهب علي ﻷحد المطاعم التي فتحت أبوابها مؤخرا، واختار مكانا هادئًا ونادى النادل يسأله عن اﻷطباق التي يقدمونها من أجل أن يأخذ طلبيته إلى الطباخ لتحضير ما طلبه علي. دوَّن النادل ما يريد علي تناوله من مأكوﻻت وذهب بها إلى الطباخ من أجل تحضيرها، بعد مدة وجيزة، عاد النادل إلى علي وهو يحمل كل ما طلبه وقدمها متمنيا أنه يعجبه اﻷكل، تذوق علي المأكوﻻت وأبدى إعجابه اﻷولي بها، وبدأ في اﻷكل إلى أن أنهى كل ما في الصحون، دفع الحساب، وخرج من المطعم شاكرا النادل على حسن اﻷستقبال. هل تتساءل اﻵن، ما علاقة هذه القصة بالواجهات البرمجية؟ وهل تساءلت يومًا عن طريقة عمل تطبيقات الهواتف الذكية، وكيف تتصل بخوادم الشركات المطورة لها، هل استطعت الوصول إلى إجابات كافية عن ذلك؟ سأبين لك ما العلاقة بين المثال السابق والواجهات البرمجية وكيف أن الواجهات البرمجية ماهي إﻻ تطبيق لمثالنا باختلاف بسيط وهو مكان التطبيق فقط، فمثالنا هو من الواقع الذي نعيشه يوميًا ونراه دائمًا حتى تعودنا عليه حتى أصبحنا ﻻ ندركه، أما الواجهات البرمجية، فقد أصبحت جزءًا ﻻ يتجزأ من حياة مبرمج المواقع وتطبيقات الويب المهنية. كنت قد نوهتك ﻷن تسأل نفسك عن طريقة ربط تطبيقات الهواتف الذكية مع خوادم الشركات. هنالك طريقتين لربط تطبيقات الهواتف الذكية مع خوادم الشركات المطورة، الطريقة اﻷقدم تسمى SOAP وهي اختصار لجملة Simple Object Access Protocol، أما الطريقة اﻷحدث فهي الواجهة البرمجيةللتطبيقات API وهي اختصار لجملة Application Programming Interface، وهي التي سأركز عليها، ولكن باختصار، API هي طريقة لتواصل البرمجيات في ما بينها باستخدام صيغة JavaScript Object Notation والتي تعرف اختصارا بـ JSON. لن أدخل في التفاصيل التاريخية وسأبقى مركزا على الجانب التقني فقط، لهذا أتوقع منك أن تحاول البحث عن تاريخ ابتكار وتطوير تقنية API والتقنية المكملة لها REST والتي هي اختصار لجملة REpresentational State Transfer. مصطلحات وجب معرفتها سنسرد بعض المصطلحات باللغة الإنجليزية والعربية الضروري على كل مطور ويب أن يعرفها: Backend: الواجهة الخلفية، هي المسؤولة عن العمليات المنطقية للنظام، تتعامل مع الملفات أيضا ومع قواعد البيانات. Frontend: الواجهات الأمامية، كل ما يراه المستخدم ويتعامل معه بشكل مباشر، ويتم ربطها مع النظم الخلفية بما يعرف بالواجهة البرمجية للتطبيقات API. API: الواجهة البرمجية للتطبيقات، هي حلقة الوصل ما بين النظم أو الواجهة الخلفية والواجهات الأمامية. Request: الطلب الذي يرسله العميل (قد تكون الواجهة الأمامية) إلى الخادم Server الموجود في الواجهة الخلفية. Header: ترويسة الطلب Request المرسل والذي يحوي بعض البيانات الوصفية التي تصف الطلبية وحالها وأية معلومات إضافية مطلوبة. Body: جسم أو متن الطلب المرسل والذي يحوي غالبًا على البيانات المتبادلة في الطلبية. Response: استجابة أو رد الخادم وهي المعلومات الراجعة من الخادم إلى العميل مقدم الطلب ردًا على طلبه. تحوي المعلومات الراجعة من الخادم إلى العميل على ترويسة Header وأيضا على متن Body. Endpoint: نقطة الوصول، وهي نقطة اتصال الواجهات الأمامية مع موقع محدد في الواجهة الخلفية أي نقطة محددة تتصل عبرها الواجهة الأمامية مع الواجهة الخلفية لغرض محدَّد. HTTP Client Software: عميل خادم HTTP وهو برنامج يساعد على تسريع التعامل مع الواجهات البرمجية بتوفير آلية واضحة في عملية إرسال واستقبال الطلبيات والردود. هل تعرفت على أي من المصطلحات التي ذكرناها قبل قليل؟ لا بأس إن لم تفعل، فسنشرحها لك حتى تكون لديك معرفة مبدئية بموضوع الواجهات البرمجية. لماذا نستخدم الواجهات البرمجية للتطبيقات APIs وما هي فائدتها؟ تُعَد الواجهات البرمجية للتطبيقات طبقة الحماية الأولى First Security Layer للبرمجية الموجودة على خادم الويب، بسبب أنها تفصل ما بين النظم الخلفية والعمليات الجارية على قواعد البيانات عن الواجهات الأمامية سواءً كانت صفحات ويب عادية أو تطبيقات هواتف ذكية. أي أن أي تطبيق ويب أو موقع اليوم يتألف من واجهة خلفية وواجهة أمامية وواجهة برمجية تعد وصلة وصل بينهما. أما الواجهة الخلفية، فتحوي على كامل العمليات والإجراءات والخدمات التي يوفرها التطبيق أو الموقع مثل معالجة صورة أو بيانات أو حتى تقديم خدمة الطقس. أما الواجهة الأمامية فهي الواجهة التي يراها المستخدم والمسؤولة عن عرض البيانات القادمة من الواجهة الخلفية للمستخدم بصورة مناسبة ومتناسقة مع إرسال البيانات من المستخدم إلى الخادم بالشكل الذي يطلبها، فالبيانات المتبادلة تلك تكون بشكلها الخام (تستعمل غالبًا صيغة JSON أو حتى صيغة XML)، أما الواجهة البرمجية للتطبيقات API فهي صلة الوصل كما ذكرنا ووظيفتها استلام البيانات من الواجهة الأمامية وتسلميها للواجهة الخلفية وإرسال البيانات من الواجهة الخلفية إلى الأمامية بطريقة وأسلوب موحد أي هي التي تؤمن عملية التفاهم بين الواجهة الأمامية والخلفية لتأمين التخاطب فيما بينهما. كيف تعمل الواجهات البرمجية للتطبيقات API سأحاول قدر اﻹمكان تبسيط آلية عمل الواجهات البرمجية بمثال عملي من حياتنا اليومية، وليكن مثلا منصة فيسبوك. كما تعلم أنه بإمكانك الدخول إلى حسابك في فيسبوك من أي جهاز تريد، سواءً من هاتفك الذكي أو من جهازك اللوحي أو من جهاز الحاسوب بل بإمكانك الدخول منها مجتمعة وفي نفس الوقت، وهنا يجب أن تطرح سؤاﻻ مهمًا، كيف تتم مزامنة حسابك في كل تلك اﻷجهزة؟ هنا تأتي أهمية الواجهة البرمجية، بحيث أن كل تلك اﻷجهزة متصلة بنظام خلفي واحد وكلها تتصل بالواجهة البرمجية التي تكون حلقة الوصل ما بين كل اﻷجهزة المتصلة و النظام الخلفي. سنأخذ مثاﻻ من حياتنا اليومية وهو موقع فيسبوك، سنقوم بالدخول إلى حسابنا باستخدام الأجهزة التي بحوزتنا، إن لم تكن لديك أجهزة غير جهاز الحاسوب، افتح أكثر من متصفح، ليس نفس المتصفح، مثلا متصفح كروم Google Chrome ومتصفح فايرفوكس Mozilla Firefox، في هذه الحالة يمكنك فتح حسابك 4 مرات باستخدام التصفح الخفي، في متصفح كروم يسمى Incognito Mode أما في متصفح فايرفوكس فيسمى Private Mode. هل قمت بذلك؟ كيف تستطيع إرسال رسائل إلى أصدقائك من أي متصفح وتشاهدها في نفس الوقت من بقية المتصفحات؟ قم بالدخول إلى حسابك على فيسبوك من هاتفك الذكي، من التطبيق الرسمي أو من المتصفح، هل تستطيع أن ترى الرسائل التي قمت بإرسالها على هاتفك أيضا، كيف يحدث ذلك؟ كيف تستطيع الدخول إلى حسابك من أماكن مختلفة في نفس الوقت؟ سأشرح العملية بأكملها بشكل بسيط وبالمقارنة مع مثالنا في بداية المقال وبدون الدخول في التفاصيل الدقيقة في الوقت الحالي. عند دخول علي مطور الويب إلى المطعم، كان عليه أن يختار طاولة محددة برقم حتى يعلم النادل موقعه وأنه يريد تناول الطعام وبالتالي يستطيع تقديم مختلف الخدمات التي يعرضها المطعم. هنا الطاولة وتفاصيلها (من رقم وحجم وغيرهما) تعتبر المكان المتفق عليه من أجل اﻹستفادة من خدمات المطعم، ويمكن القول أنها نقطة الوصول إلى خدمات المطعم Endpoint. في حالة موقع فيسبوك، وعند قيامك فتح التطبيق مثلا، سيتصل تطبيقك بخادم الشركة، في نقطة متفق عليها ومحددة مسبقًا في التطبيق وفيها فقط يستطيع الخادم أن يقدم خدماته للتطبيق. جاء النادل إلى عليٍ والذي يسمى العميل client ليأخذ الطلبات منه، ودون أية ملاحظات أو أي خدمات أخرى، وبعدها ذهب إلى المطبخ ليخبر الطباخ بالطلبات من أجل تحضيرها. هنا نسمي العملية: إرسال طلب Send Request من العميل علي إلى الطباخ في المطعم مقدمة الخدمة. في حالة موقع فيسبوك، أقرب عملية لذلك المثال عملية تسجيل الدخول حيث تُدخل اسم المستخدم الخاص بك مع كلمة المرور، تأخذ الواجهة الأمامية منك هذه المعلومات وترسلها للواجهة الخلفية لموقع فيسبوك لتتحقق منها ومن الطلب الخاص بك، طلب تسجيل الدخول. يستلم الطباخ الطلبية ويتأكد من أنها طلبية صالحة ويمكنك تحضيرها (أي ليست طلبية شراء ملابس مثلًا) ثم يبدأ بتحضيرها وعندما ينتهي منها، يعطيها للنادل الذي يرتبها بدوره في صينية ويأخذها إلى علي ليضعها على طاولته حتى يتسنى له البدء في تذوقها. هذه العملية تسمى: اﻹستجابة Send Response أي استجاب الطباخ لطلبية علي وقدم له ما يريد. وفي حالة موقع فيسبوك، إن كانت المعلومات المقدمة صالحة، سيقوم خادم فيسبوك بالسماح لك بالدخول واستعراض مختلف الصفحات واﻷجزاء الخاصة به والاستفادة من خدمته التي يقدمها. هل اتضحت الصورة العامة اﻵن؟ ببساطة، الواجهة البرمجية تنفذ عمل النادل في المطعم، حيث أن النادل يقوم بأخذ طلبات الزبائن إلى الطباخ وفريقه لتحضيرها وبعد ذلك، يقوم بأخذ تلك استجابة الطباخ لتلك الطلبات إلى أصحابها، أي أن الواجهة البرمجية تأخذ الطلبات من المستخدمين (الواجهة الأمامية) إلى النظام الخلفي لتقوم بعمل محدد ومن ثم تعيد النتائج المتحصل عليها إلى طالبيها أي تعيدها للواجهة الأمامية مرةً أخرى. خاتمة تعرفنا على ماهية الواجهة البرمجية للتطبيقات وأهم المصطلحات فيها وكيف يستفيد منها المطورون في بناء تطبيقات الويب الحديثة واستثمارها في التواصل ما بين الواجهة الأمامية والخلفية لتطبيقات الويب والمواقع الحالية، فالتعامل مع الواجهة البرمجية للتطبيقات ضروري لأي مبرمج متخصص في تطوير الويب، وعليه أن يعي مفهوم الواجهة البرمجة تمامًا إذ أصبح هذا المفهوم هو المفهوم الحديث في التواصل ما بين الواجهة البرمجية الخلفية والأمامية للمواقع وتطبيقات الويب، أضف إلى ذلك أن الكثير من الخدمات والمواقع أصبحت تتيح واجهتها البرمجية (مثل الواجهة البرمجية للمطورين من فيسبوك وتويتر وغيرهما) للاستفادة منها أو حتى هنالك واجهة برمجية مخصصة فقط لتقديم خدمات محددة (مثل واجهة برمجية للحصول على معلومات الطقس) وتقدمها للمطورين للاستفادة من تلك الخدمات في مختلف المشاريع. اقرأ أيضًا المقال التالي: الاتصال بواجهة زد البرمجية وفهم عملية الاستيثاق والتصريح كيفية إنشاء متجر إلكتروني متكامل باستعمال منصة زد الواجهة البرمجية Fetch API في جافاسكريبت
    1 نقطة
  2. لسلام عليكم الرجاء المساعدة في عدم فاعلية الكود التالي App function App() { return ( <> <Routes> <Route path="/" element={ <AppRoute redirect='/login' user={Auth.auth} > <Chat/> </AppRoute> } /> <Route path="/register" element={ <AppRoute redirect='/' user={Auth.guest} > <Register/> </AppRoute> } /> <Route path="/login" element={ <AppRoute redirect='/' user={Auth.guest} > <Login/> </AppRoute> } /> <Route path= "*" element={ <NotFound/> }/> </Routes> </> ); } AppRoute const AppRoute = ({ user, children, redirect }) => { if (!user) { return <Navigate to={redirect} />; } return children; }; Auth const Auth = { auth: () => localStorage.getItem('user') !== null, guest: () => localStorage.getItem('user') === null, }; مثلما تلاحظون، في صورة عدم وجود مستخدم في ذاكرة المتصفح فإنه يتوجه مباشرة إلى صفحة تسجيل الدخول إلا أن النتيجة التي تحصلت عليها عكس ذلك ففي صورة كانت ذاكرة المتصفح فارغة فإنه يتوجه إلى الصفحة الرئيسية شكرا على المساعدة
    1 نقطة
  3. السلام عليكم منذ فتره رايت مقطع في اليوتيوب يشرح عن اهم الاضافات في المتصفح التي تساعد الطلاب في الدراسه من اليوتيوب اضافة متصفح لمعرفة تعليقات و ملاحظات باقي المتابعين لكن للاسف نسيت الفيديو و نسيت اسم الاضافة اذا امكن المساعده اذا كان احدكم يستخدمها او سمع عنها شكرا لكم
    1 نقطة
  4. السلام عليكم ورحمةالله وبركاته هل يمكن تنفيذ هذه الفكرةبالووردبريس اخواني الكرام ؟؟ موقع الكتروني خاص بتاجير السيارات مربوط بمواقع اخرى ويتم تحديث السعر للمنتجات بناء على الموقع الاخر بارك الله فيكم
    1 نقطة
  5. السلام عليكم حاولت افهم return ماقدرت الي فهمته ترجع القيمه اريد مثال يفهمني ايش هي return وايش فايدتها
    1 نقطة
  6. console.log(number); // 5 ليه حطيت اسم الداله ليه مو اسم المتغير بخصوص القصه هل تقصد بانني اعطي اخي المال ليقوم بشراء لي تفاحه واخبره ان يجلب التفاحه لي هكذا تقصد؟
    1 نقطة
  7. هل لديك الخبرة الكافية لفعل ذلك؟ الأمر أشبه بتعلم قيادة السيارة للمرة الأولى، هل يمكنك قيادة السيارة وأنت تفعل شيء آخر؟ بالطبع لا، لكن بعد فترة من التمرس واكتساب الخبرة تستطيع ذلك. الأمر نفسه في البرمجة، عليك بتعلم المسار البرمجي الذي اخترته بالترتيب والتدرج بشكل مناسب لكي لا تصاب بالإحباط بدون داعي، فمثلاً دورة علوم الحساب مملة فعلاً لأنك لا تعمل على تنفيذ مشاريع حقيقية بل نماذج فقط وتريد كتابة الكود بأسرع وقت وهناك الكثير من الشرح النظري. اسمح لي بالتحدث بواقعية معك، إذا اتبعت نفس النهج مع كل شيء في حياتك لن تتعلم شيء ذو قيمة، فعملية التعلم مملة وبحاجة إلى التكرار الممتع بها هو عند رؤية مستواك يتطور وأصبحت قادر على تنفيذ المشاريع بعد فترة. لكن أن ترى نتائج فورية بعد أسبوع مثلاً؟ بالطبع لا، وإلا كان الجميع تعلم البرمجة، عليك أن تصاحب الملل، وتبتعد عن دفعات الدوبامين القصيرة من خلال وسائل التواصل والتيك توك وما شابه.
    1 نقطة
  8. مرحبا اقوم ببناء تطبيق اندرويد باستخدام Django & React ماهي الاصدارات الذي ينصح بالعمل عليها لعدم حدوث تضارب بين الحزم؟ ( اصدار بايثون واصدار react متوافقين)؟
    1 نقطة
  9. التعلم والاستمرار في اكتساب المعرفة هو شيء جيد ومحمود، ولا يوجد قاعدة صارمة تنص على عدم تعلم أكثر من شيء في آن واحد. يعتمد الأمر على الأفراد واهتماماتهم وقدراتهم على التعلم المتعدد. ولكن يجب عليك التفرقه بين التخطيط الجيد لدراسة مجالات متعددة وبين العشوائية التي تنقلك من مجال إلى آخر التعلم المتعدد أو التعلم في مجالات متعددة يمكن أن يكون له فوائد عدة. فمن خلال تعلم مجالات مختلفة، يمكنك توسيع رؤيتك وفهمك للعالم والتفكير بشكل أوسع. قد يساعدك اكتساب المهارات والمعرفة في مجالات متعددة على استفادة من تبادل الأفكار والمفاهيم بين هذه المجالات وتطبيقها في سياقات جديدة. ومع ذلك، يجب أن تكون حذرًا ومنظمًا في تعلمك المتعدد لضمان التركيز والتقدم في كل مجال بطريقة فعالة. قد تحتاج إلى تخصيص وقت وجهد لكل مجال على حدة لضمان التقدم والفهم الجيد. من المهم تحديد أهداف واضحة لكل مجال وتنظيم جدول زمني يتيح لك التركيز على كل مجال بشكل منفصل. بشكل عام، التعلم في مجالات متعددة يمكن أن يكون مفيدًا ومثيرًا، ولكن من المهم أن تكون منظمًا وتحافظ على التركيز والتقدم في كل مجال بشكل فعال. قم بتحديد أهدافك وتخطيط جيد لوقتك وتوازن بين التعلم والاستراحة لتحقيق أفضل النتائج.
    1 نقطة
  10. السلام عليكم. في صورة عدم النجاح في الإمتحان النهائي. هل توجد فرص أخرى لإعادة الإمتحان أم تسحب الشهادة و لايتسنى الحصول عليها. شكرا.
    1 نقطة
  11. صحيح يمكنك إعادة الامتحان مرة أخرى ، لا مشكلة في ذلك ، يمكنك مراجعة مركز المساعدة من هنا يوجد العديد من المقالات المفيدة
    1 نقطة
  12. إذا أردتي تجنب استخدام jQuery يمكنك تنفيذ نفس الأمر من خلال جافاسكريبت النقية من خلال الكود التالي: // دالة لإنشاء كائن التاريخ وإخراجه function getCurrentYear() { // إنشاء كائن تاريخ const currentDate = new Date(); // الحصول على العام الحالي const year = currentDate.getFullYear(); // إرجاع العام الحالي return year; } // تعيين نص السنة الحالية لعنصر `currentYear` document.querySelector("#currentYear").textContent = getCurrentYear(); وبذلك لن تحتاجين إلى تضمين مكتبة jQuery من خلال رابط CDN.
    1 نقطة
  13. سنتحدّث في هذا الدرس عن كيفيّة تطبيق مبادئ البرمجة كائنيّة التوجّه في سي شارب وذلك من خلال إنشاء واستخدام الأصناف والكائنات في هذه اللغة. يمكن التصريح عن صنف في سي شارب باستخدام الكلمة المحجوزة class يليها اسم الصنف وهو يتبع لنفس قواعد التسمية للمتغيّرات، علمًا أنّه يفضّل أن يكون الحرف الأوّل من اسم الصنف حرفًا طباعيًّا كبيرًا. انظر إلى الشكل التالي حيث نرى الصنف البسيط Employee والذي يُعبّر عن موظّف في إحدى الشركات: يحتوي هذا الصنف على ثلاثة حقول بيانات data fields هي: الاسم FirstName الكنية LastName الراتب Salary تستطيع اعتبارها حاليًّا أنّها تمثّل خصائص للصنف Employee، كما يحتوي هذا الصنف على تابع وحيد اسمه DisplayInfo الهدف منه هو الحصول على تمثيل نصيّ لكلّ كائن ننشئه من هذا الصنف كما سنرى بعد قليل، يشبه التابع إلى حدٍّ كبير الدّالة function في لغات البرمجة الأخرى. لا يتطلّب هذا التابع أيّ وسائط في حين أنّه يُرجع قيمة نصيّة من النوع string. هذه الحقول بالإضافة إلى التابع السابق تُعتبر أعضاء ضمن الصنف Employee كما ذكرنا ذلك مسبقًا. تقع أعضاء أيّ صنف ضمن حاضنتيه. لاحظ الكلمة المحجوزة public والموجودة قبل كلّ تصريح لحقل أو تابع ضمن الصنف Employee. هذه الكلمة عبارة عن مُحدّد وصول access modifier. تتحكّم محدّدات الوصول بقابلية الوصول إلى أعضاء الصنف من خارجه، سنتعامل مع نوعين آخرين من محدّدات الوصول وهما private و protected. يكفي أن تعلم الآن أنّ أي عضو في الصنف يمتلك محدّد وصول public يمكن الوصول إليه سواءً من داخل الصنف (أو بشكل أدق من داخل الكائن) أو من خارجه. كما من المفيد أن نعلم أنّه من الممكن استخدام محدّدات الوصول مع الأصناف أيضًا كما سنرى في درس لاحق. إذا أردنا إنشاء كائن جديد من الصنف Employee فعلينا التصريح عن متغيّر مناسب من النوع Employee وذلك على الشكل التالي: Employee empObject; صرّحنا عن المتغيّر empObject على أنّه من النوع Employee. لاحظ التشابه في التصريح عن المتغيّرات بين أنواع موجودة ضمن سي شارب وبين أنواع ننشئها بأنفسنا. التصريح السابق غير كافي لإنشاء الكائن. لإنشاء كائن من النوع Employee علينا استخدام العامل new الذي يعمل على إنشاء كائن من أيّ صنف نرغبه ويعمل على إعادة المرجع (العنوان) لذلك الكائن في الذاكرة. استخدام العامل new سهل حيث يمكننا كتابة ما يلي بعد عبارة التصريح السابقة: empObject = new Employee(); يقوم العامل new بإنشاء كائن جديد من الصنف Employee ثمّ يُسند مرجع (عنوان) هذا الكائن ضمن المتغيّر empObject. لاحظ القوسين الموجودين بعد اسم الصنف Employee. في الحقيقة يُعبّر هذين القوسين عن استدعاء لبانية constructor الصنف Employee عند إنشاء الكائن. ولكن أين هذه البانية؟ هذا ما سنراه بعد قليل. يمكن الآن الوصول إلى الحقول والتوابع الموجودة ضمن الكائن عن طريق كتابة المتغيّر الذي يحوي العنوان إلى الكائن (أي المتغيّر empObject) ثم نضع نقطة وبعدها اسم الحقل أو التابع الذي نريد الوصول إليه. في العبارة التالية سنسند القيمة "Mohammad" إلى الحقل FirstName من الكائن empObject (الكائن الذي يشير إليه empObject): empObject.FirstName = "Mohammad"; حان الآن وقت التنفيذ العمليّ. انظر إلى البرنامج Lesson06_01 الذي يوضّح كيفية إنشاء الصنف Employee وكيفيّة إنشاء كائنين منه: 1 using System; 2 3 namespace Lesson06_01 4 { 5 6 class Employee 7 { 8 public string FirstName; 9 public string LastName; 10 public double Salary; 11 12 public string DisplayInfo() 13 { 14 string result = string.Format("{0} {1} - Salary: {2:N0}", 15 this.FirstName, this.LastName, this.Salary); 16 17 return result; 18 } 19 } 20 21 class Program 22 { 23 static void Main(string[] args) 24 { 25 Employee employee1, employee2; 26 27 employee1 = new Employee(); 28 employee1.FirstName = "Mohammad"; 29 employee1.LastName = "Mansoor"; 30 employee1.Salary = 1000; 31 32 employee2 = new Employee(); 33 employee2.FirstName = "Saleh"; 34 employee2.LastName = "Mahmoud"; 35 employee2.Salary = 2500; 36 37 Console.WriteLine("First Employee: {0}", employee1.DisplayInfo()); 38 Console.WriteLine("Second Employee: {0}", employee2.DisplayInfo()); 39 } 40 } 41 } عند تنفيذ البرنامج سنحصل على الخرج التالي: First Employee: Mohammad Mansoor - Salary: 1,000.00 Second Employee: Saleh Mahmoud - Salary: 2,500.00 نلاحظ من النظرة الأولى للبرنامج السابق أنّه لدينا صنفان ضمن نطاق الاسم Lesson06_01 وهما Employee و Program. يقع التصريح عن الصنف Employee في الأسطر بين 6 و 19 ويحتوي هذا الصنف كما رأينا قبل قليل على أربعة أعضاء وهي عبارة عن ثلاثة حقول FirstName و LastName و Salary بالإضافة إلى التابع DisplayInfo الموجود بين السطرين 12 و18. تنحصر وظيفة هذا التابع في الحصول على التمثيل النصيّ لأيّ كائن ننشئه من الصنف Employee. يحتوي التابع DisplayInfo على أسلوب جميل لتنسيق النصوص يشبه ذلك الأسلوب الذي كنّا نستخدمه مع التابع WriteLine. يحتوي الصنف string على تابع اسمه Format يقبل عدّة وسائط (السطر 14) أولها نصّ تنسيقي، أمّا الوسائط التالية فهي القيم التي ستجد لها أمكنةً ضمن النص التنسيقي، كما كنّا نستخدم التابع WriteLine بالضبط. يُرجع التابع Format نصًّا منسّقًا بحسب القيم الممرّرة له. الشيء الوحيد المختلف هو كيفيّة تنسيق قيمة الراتب Salary باستخدام مُحدّد التنسيق :N0 الموجود ضمن {2:N0}. يخبر هذا المحدّد التابع Format أنّ القيمة التي ستوضع في هذا المكان (وهي قيمة Salary) يجب أن تُنسّق على شكل رقم ذي فاصلة آلاف وبدون فاصلة عشريّة. يفيد مثل هذا التنسيق في الحصول على أرقام منسّقة بشكل محترف تُعبّر عن الراتب الذي يحصل عليه الموظّف وهي تبدو مثل 1,000 أو 2,500. جرّب استخدام التنسيق {2:N1} و {2:N2} ولاحظ الفرق. لاحظ أنّني قد استخدمت الكلمة المحجوزة this متبوعةً بنقطة قبل اسم كل حقل. في الحقيقة تُشير هذه الكلمة إلى الكائن الحالي الذي يتمّ منه استدعاء التابع DisplayInfo كما سنرى ذلك بعد قليل. أمّا لإرجاع القيمة النصيّة من التابع DisplayInfo فإنّنا ببساطة نستخدم الكلمة المحجوزة return ونضع بعدها القيمة المراد إرجاعها. الصنف Program المصرّح عنه في الأسطر بين 21 و 40 هو الصنف الذي تعاملنا معه في جميع البرامج التي كتبناها حتى الآن. يحتوي هذا الصنف على التابع Main الذي يمثّل نقطة الدخول للبرنامج كما نعلم. يبدأ التابع Main بالتصريح عن متغيرين من النوع Employee وهما employee1 و employee2 ثمّ ينشئ كائنًا من النوع Employee باستخدام العامل new (السطر 27) ويسنده إلى المتغيّر employee1. بعد ذلك يمكن استخدام أيّ حقل أو تابع معرّف ضمن الصنف Employee عن طريق المتغيّر employee1 بشرط أن يكون له محدّد وصول public كما هو واضح في الأسطر من 28 حتى 30. يتكرّر نفس الأمر بالنسبة للمتغيّر employee2 الذي سيحمل كائنًا مختلفًا عن الكائن الموجود ضمن employee1. أخيرًا وفي السطرين 37 و38 يتم طباعة التمثيل النصيّ لكلّ من الكائنين باستخدام التابع DisplayInfo. تجدر الإشارة إلى أنّه عند وصول تنفيذ البرنامج إلى السطر 37 وإلى الاستدعاء ()employee1.DisplayInfo تحديدًا سيؤدّي ذلك إلى انتقال التنفيذ إلى السطر 14 ضمن هذا التابع لتنفيذ التعليمات البرمجيّة ضمنه ومن ثمّ الحصول على التمثيل النصيّ للكائن employee1 وإرجاعه إلى السطر 37 مرّة أخرى ليعمل البرنامج على تمرير هذه القيمة النصيّة للتابع WriteLine ومن ثمّ العرض على الشاشة، وبالطبع يتكرّر نفس الأمر تمامًا بالنسبة للكائن ضمن employee2 في السطر 38. إذا كنت تستخدم Visual Studio 2015 بأيّ إصدار فأنصحك أن تنفّذ هذا البرنامج بشكل خُطَوي لكي تتعرّف على آلية عمل هذا البرنامج بشمل عمليّ. اضغط على المفتاح F11 (أو من القائمة Debug > Step Into) لتنفيذ البرنامج باستخدام منقّح الأخطاء debugger. ستلاحظ ظهور مستطيل أصفر يُشير إلى مكان التنفيذ الحالي، وكلما ضغطت المفتاح F11 سينتقل تنفيذ البرنامج إلى العبارة البرمجيّة التالية خطوة بخطوة. البانية constructor ضمن الصنف البانية constructor هي تابع من نوع خاص يجب أن تكون موجودة ضمن أيّ صنف في سي شارب. في حال تمّ إغفالها سيعمل المترجم على توليد واحدة افتراضيّة من أجلنا. في الحقيقة وظيفة البانية هي بناء الكائن وحجز مكان مناسب له في الذاكرة، حيث يتم استدعاء البانية عند إنشاء الكائن باستخدام العامل new. لا يمكن للبواني إرجاع قيمة مخصّصة كما نفعل مع التوابع الأخرى عادةً، في الحقيقة هي تُرجع كائنًا من الصنف الموجودة ضمنه. ولكن يمكن أن تقبل وسائط نمرّرها إليها. استبدل الصنف Employee التالي بذلك الموجود ضمن البرنامج Lesson06_01: 1 class Employee 2 { 3 public string FirstName; 4 public string LastName; 5 public double Salary; 6 7 public Employee() 8 { 9 Console.WriteLine("Hello, I'm in Employee's constructor!"); 10 } 11 12 public string DisplayInfo() 13 { 14 string result = string.Format("{0} {1} - Salary: {2:N0}", 15 this.FirstName, this.LastName, this.Salary); 16 17 return result; 18 } 19 } لقد أضفنا في هذه النسخة البانية ()Employee للصنف Employee. نفّذ البرنامج لتحصل على الخرج التالي: *** Hello, I'm in Employee's constructor! *** *** Hello, I'm in Employee's constructor! *** First Employee: Mohammad Mansoor - Salary: 1,000 Second Employee: Saleh Mahmoud - Salary: 2,500 لاحظ أنّ العبارة: *** Hello, I'm in Employee's constructor! *** قد ظهرت مرّتين في الخرج، وذلك بسبب أنّنا أنشأنا كائنين حيث تُنفّذ هذه البانية من أجل كلّ عملية إنشاء. ولكن السؤال المطروح هنا، ماذا سنستفيد من هذه البانية؟ تُستخدم البواني عمومًا عندما نريد تهيئة الكائن ببعض القيم الضرورية لجعل حالته مستقرّة وذلك أثناء إنشائه وقبل محاولة الوصول إليه من أيّ مصدر خارجيّ. انظر الآن إلى الصنف Employee المعدّل الذي يحوي بانية تقوم ببعض الأعمال المفيدة: 1 class Employee 2 { 3 public string FirstName; 4 public string LastName; 5 public double Salary; 6 7 public Employee(string firstName, string lastName, double salary) 8 { 9 this.FirstName = firstName; 10 this.LastName = lastName; 11 this.Salary = salary; 12 } 13 14 public string DisplayInfo() 15 { 16 string result = string.Format("{0} {1} - Salary: {2:N0}", 17 this.FirstName, this.LastName, this.Salary); 18 19 return result; 20 } 21 22 } تتطلّب البانية هذه المرّة ثلاثة وسائط، تمثّل قيمًا سيتمّ إسنادها إلى الحقول. هذه الوسائط هي: firstName و lastName و salary (لاحظ أنّ اسم كلّ منها يبدأ بحرف طباعي صغير لتمييزها عن حقول الصنف). إذا استبدلت هذا الصنف الجديد بالصنف القديم الموجود ضمن البرنامج Lesson06_01 وحاولت تنفيذ البرنامج فستحصل على خطأ. السبب في ذلك بسيط، وهو أنّ العبارتين في السطرين 27 و 32 من البرنامج Lesson06_01 تحاولان إنشاء كائنين من الصنف Employee عن طريق بانية لا تتطلّب أيّة وسائط وهذا ما لا يتوفّر في الصنف Employee الجديد. فعندما يلاحظ مترجم سي شارب وجود بانية واحدة على الأقل بصرف النظر عن عدد الوسائط التي تتطلّبها فإنّه يمتنع عن توليد بانية افتراضية بشكل تلقائي مثلما كان يفعل من قبل. يوجد حلّ سريع لهذه المشكلة يتمثّل في توفير بانية لا تحتاج لأيّة وسائط كما كان الوضع السابق. انظر إلى النسخة الأخيرة للصنف Employee: 1 class Employee 2 { 3 public string FirstName; 4 public string LastName; 5 public double Salary; 6 7 public Employee(string firstName, string lastName, double salary) 8 { 9 this.FirstName = firstName; 10 this.LastName = lastName; 11 this.Salary = salary; 12 } 13 14 public Employee() 15 { 16 17 } 18 public string DisplayInfo() 19 { 20 string result = string.Format("{0} {1} - Salary: {2:N0}", 21 this.FirstName, this.LastName, this.Salary); 22 23 return result; 24 } 25 26 } بعد اعتماد هذا الصنف ضمن البرنامج Lesson06_01، سيعمل البرنامج الآن بشكل طبيعي ويظهر الخرج كما هو متوقّع. ولكن تأمّل معي هذا الصنف قليلًا، ألا تلاحظ وجود بانيتين له؟ هذا أمر طبيعي ووارد جدًّا في سي شارب حيث يمكن كتابة أكثر من تابع بنفس الاسم طالما اختلف عدد أو أنواع الوسائط الممرّرة لكلّ منهما. نسمي هذه الميزة بزيادة التحميل overloading للتوابع. فعند وجود استدعاء للتابع المزاد تحميله يتمّ اختيار الشكل المناسب بناءً على عدد وأنواع الوسائط الممرّرة. لاحظ أنّ البانية عديمة الوسائط فارغة ولا بأس في ذلك. ولكنّ السؤال هنا كيف يمكن الاستفادة من البانية ذات الوسائط الثلاثة. الأمر بسيط، استبدل محتويات التابع Main في البرنامج Lesson06_01 بالشيفرة البسيطة المكافئة التالية: 1 Employee employee1, employee2; 2 3 employee1 = new Employee("Mohammad", "Mansoor", 1000); 4 employee2 = new Employee("Saleh", "Mahmoud", 2500); 5 6 Console.WriteLine("First Employee: {0}", employee1.DisplayInfo()); 7 Console.WriteLine("Second Employee: {0}", employee2.DisplayInfo()); انظر كم أصبحت الشيفرة نظيفة وقصيرة ومريحة للعين. إليك الآن البرنامج Lesson06_02 كاملًا بعد التعديل: 1 using System; 2 3 namespace Lesson06_02 4 { 5 6 class Employee 7 { 8 public string FirstName; 9 public string LastName; 10 public double Salary; 11 12 public Employee(string firstName, string lastName, double salary) 13 { 14 this.FirstName = firstName; 15 this.LastName = lastName; 16 this.Salary = salary; 17 } 18 19 public Employee() 20 { 21 22 } 23 24 public string DisplayInfo() 25 { 26 string result = string.Format("{0} {1} - Salary: {2:N0}", 27 this.FirstName, this.LastName, this.Salary); 28 29 return result; 30 } 31 32 33 } 34 35 36 class Program 37 { 38 static void Main(string[] args) 39 { 40 Employee employee1, employee2; 41 42 employee1 = new Employee("Mohammad", "Mansoor", 1000); 43 employee2 = new Employee("Saleh", "Mahmoud", 2500); 44 45 Console.WriteLine("First Employee: {0}", employee1.DisplayInfo()); 46 Console.WriteLine("Second Employee: {0}", employee2.DisplayInfo()); 47 } 48 } 49 } تمارين داعمة تمرين 1 أضف تابعًا جديدًا إلى الصنف Employee الموجود في البرنامج Lesson06_02 السابق وسمّه GetSalaryAfterTax. وظيفة هذا التابع هي الحصول على قيمة الراتب للموظّف بعد تطبيق الضريبة Tax عليه. اعتبر نسبة الضريبة 2%. تلميح: اضرب قيمة الراتب Salary بالعدد 0.98 للحصول على قيمة الراتب بعد خصم الضريبة. فإذا كان الراتب 1500 مثلًا، يجب أن يُرجع التابع GetSalaryAfterTax القيمة 1470. تمرين 2 أنشئ صنفًا جديدًا سمّه MyRectangle والذي يُعبّر عن مستطيل في المستوي، بحيث يحتوي على الحقلين Width و Height (من النوع double لكلّ منهما)، بالإضافة إلى التابع GetArea لحساب مساحة المستطيل. ثمّ اكتب برنامجًا بسيطًا يوضّح استخدام هذا الصنف من خلال إنشاء كائنين منه. احسب مساحة كل مستطيل (كائن) واعرض النتيجة على الشاشة. الخلاصة تعلّمنا في هذا الدرس أساسيّات إنشاء الأصناف والكائنات، وكيفية التعامل مع الحقول والتوابع والبواني الموجودة ضمن الصنف. كما أخذنا لمحة سريعة حول محدّدات الوصول وكيفية التعامل مع محدّد الوصول public، علمًا أنّنا ستوضّح كيفيّة التعامل مع باقي المحدّدات في الدرس التالي الذي سنتحدّث فيه عن المزيد حول هذا الموضوع المهم والأساسي لتطوير التطبيقات باستخدام سي شارب.
    1 نقطة
  14. شكرا جزيل باش مهندس اين نستطيع الحصول على بقية الدروس
    1 نقطة
×
×
  • أضف...