https://wiki.hsoub.com/api.php?action=feedcontributions&user=%D8%B9%D8%A7%D8%B7%D9%81-%D8%A8%D9%86-%D8%B9%D9%84%D9%8A&feedformat=atomموسوعة حسوب - مساهمات المستخدم [ar]2024-03-28T18:43:06Zمساهمات المستخدمMediaWiki 1.35.0https://wiki.hsoub.com/index.php?title=TypeScript&diff=31643TypeScript2021-12-10T20:00:35Z<p>عاطف-بن-علي: /* الدوال */</p>
<hr />
<div><noinclude>{{DISPLAYTITLE:TypeScript}}</noinclude><br />
لغة TypeScript لغة برمجة مفتوحة المصدر من تطوير شركة Microsoft، تُعدّ امتدادًا وتوسعةً للغة JavaScript، حيث أضافت العديد من المزايا إليها، خاصّة دعم الأنواع (types) الذي يُساعد على تجنّب الأخطاء والعلل البرمجيّة وتوفير شيفرة برمجية نقية قابلة للقراءة أكثر من شيفرة JavaScript العادية.<br />
==لغة TypeScript==<br />
===[[TypeScript/Guide|مدخل إلى TypeScript]]===<br />
تعرَّف على أساسيات اللغة وكيفية استخدامها في تطبيق JavaScript الخاص بك.<br />
===[[TypeScript/basic_types|الأنواع الأساسية]]===<br />
ستجد في هذا القسم شرحًا وافيًا حول أنواع البيانات الأساسية في لغة TypeScript.<br />
===[[TypeScript/variable_declarations|التصريح عن المتغيّرات]]===<br />
يشرح هذا القسم كيفية التصريح عن جميع أنواع المتغيرات (Variable Declarations) والثوابت باستعمال <code>var</code> و <code>let</code> و <code>const</code>. يتطرق أيضًا إلى شرح كيفية تفكيك ونشر المصفوفات والكائنات عند التصريح عن المغيرات.<br />
<br />
===[[TypeScript/interfaces|الواجهات]]===<br />
تركيز التحقق من الأنواع (type-checking) على شكل قيم من مبادئ TypeScript الأساسية. يُصطلَح عليه أحيانًا بالتعبير duck typing أو التحقق من الأنواع الفرعيّة هيكليًّا (structural subtyping). تعمل الواجهات (interfaces) في TypeScript على تسمية هذه الأنواع، وهي طريقة قويّة لتعريف عقود (contracts) داخل شيفرتك أو عقود مع شيفرةٍ خارج مشروعك.<br />
<br />
===[[TypeScript/classes|الأصناف]]===<br />
بدءًا من الإصدار ECMAScript 2015 المعروف كذلك بالإصدار ECMAScript 6، يُمكن لمبرمجي JavaScript بناء التطبيقات باستخدام البرمجة كائنيّة التوجّه المعتمِدة على الأصناف (classes). وتسمح TypeScript للمطورين باستعمال هذه التقنيات الآن، وتُترجِمها إلى لغة JavaScript تعمل على جميع المنصات المتصفحات المعروفة، دون الحاجة إلى انتظار دعم النسخة التالية من JavaScript.<br />
<br />
===[[TypeScript/functions|الدوال]]===<br />
تلعب الدوال (functions) الدور الرئيس في وصف كيفيّة القيام بالأمور. يشرح هذا القسم الدوال في TypeScript وأنواعها وكيفية تعريفها والمعاملات المُمرَّرة إليها. يعرِّج أيضًا على شرح الكلمة <code>this</code> المفتاحية والدوال السهمية. <br />
<br />
===[[TypeScript/generics|الأنواع المُعمَّمة]]===<br />
الأنواع المُعمّمة (generics) من الأدوات الرئيسية التي تُساعد على بناء مكوّنات قابلة لإعادة الاستعمال في لغات مثل C# وJava، إذ تُعطي القُدرة على إنشاء مكوّنات يُمكن لها العمل مع عدّة أنواعٍ من البيانات عوضًا عن نوع واحد فقط. ما يسمح للمستخدمين بالاعتماد على هذه المكونات واستعمال الأنواع الخاصة بهم.<br />
<br />
===[[TypeScript/enums|الثوابت المتعددة]]===<br />
تسمح الثوابت المتعدّدة بتعريف مجموعة مُسمّاةٍ من الثوابت، إذ يُسهّل استخدام الثوابت المتعدّدة توضيحَ نية استعمال الشيفرة أو إنشاء مجموعة حالات مختلفة. تُوفّر TypeScript كلا من الثوابت المتعددة المعتمِدة على الأعداد وتلك المُعتمِدة على السلاسل النصية كذلك.<br />
<br />
===[[TypeScript/type_inference|استنتاج الأنواع]]===<br />
سيغطّي هذا القسم آلية استنتاج الأنواع في TypeScript، خاصّةً أين وكيف تُستنتَج الأنواع.<br />
<br />
===[[TypeScript/type_compatibility|توافقية الأنواع]]===<br />
توافقيّة الأنواع في TypeScript مبنيّةٌ على التحقق من الأنواع الفرعيّة هيكليًّا (structural subtyping). والتحقّق من الأنواع هيكليًّا طريقةٌ للربط بين الأنواع حسب عناصرها فقط لا غير. وهذا مُعاكسٌ للتحقق من الأنواع اسميًّا (nominal typing).<br />
<br />
===[[TypeScript/advanced_types|أنواع متقدمة]] ===<br />
تدعم TypeScript أنواعًا متقدمةً من البيانات يمكن استعمالها في شيفرتك. من هذه الأنواع: أنواع التقاطع والاتحاد والتمييز والقيم الفارغة ...إلخ. توفر أيضًا حرّاس الأنواع التي تستعمل لأداء عدة وظائف منها التخلص من أنواع محددة مثل النوع <code>null</code>. توفِّر أيضًا ميّزة الأنواع الشرطيّة التي تسمح لنا بالتعبير عن اقترانات أنواع غير موحّدة.<br />
<br />
===[[TypeScript/symbols|الرموز]]===<br />
هي نوعٌ أوليّ مثل النوع <code>number</code> والنوع <code>string</code> وهي فريدة وغير قابلة للتعديل. يُمكن استخدام الرموز كمفاتيح لخاصيات الكائنات كما السلاسل النصيّة، ويُمكن كذلك مزجها مع تصريحات الخاصيات المحسوبة عن خاصيات الكائنات وعناصر الأصناف.<br />
<br />
===[[TypeScript/iterators_and_generators|المكررات (iterators) والمولدات (generators)]]===<br />
طريقة التعامل مع المكرِّرات في TypeScript، وجملة <code>for..of</code>.<br />
<br />
===[[TypeScript/modules|الوحدات]]===<br />
أضافت نسخة ECMAScript 2015 مبدأ الوحدات (modules) إلى لغة JavaScript، وهذا المبدأ موجود كذلك في لغة TypeScript. تُنفَّذ الوحدات داخل مجالها (scope) الخاص وليس في المجال العام (global scope)؛ هذا يعني بأنّ المتغيّرات، والدوال، والأصناف وغيرها من الكائنات المعرفة في وحدةٍ لا تكون مرئيّةً خارج الوحدة إلا في حالة صُدِّرَت صراحةً وبوضوح. في المقابل، إذا أردت استخدام متغير أو دالة أو صنف أو واجهة أو غير ذلك ممّا صُدِّر من طرف وحدة أخرى، فلا بد لك أن تَسْتَورِدَها.<br />
<br />
===[[TypeScript/namespaces|مجالات الأسماء]]===<br />
يشرح هذا القسم كيفيّة تنظيم شيفرتك باستخدام مجالات الأسماء (namespaces) في لغة TypeScript.<br />
<br />
===[[TypeScript/namespaces_and_modules|مجالات الأسماء والوحدات]]===<br />
تُوضِّح هذه الصّفحة الأساليب التي يُمكن بها تنظيم الشيفرة باستخدام مجالات الأسماء والوحدات في TypeScript. سيغطّي هذا القسم بعض المواضيع المتقدّمة في آليّة استخدام مجالات الأسماء والوحدات، وسيتطرّق إلى بعض الأخطاء الشائعة التي يقع فيها من يستخدم هذين الأسلوبين في TypeScript.<br />
<br />
===[[TypeScript/module_resolution|تقرير الوحدات]]===<br />
تقريرُ (أو حلُّ) الوحداتِ (Module resolution) هي العمليّة التي يعتمد عليها المترجم (compiler) لاكتشاف ما يُشير إليه استيرادٌ (import) معيّن. تتطلّب قراءة هذا القسم فهمًا عامًّا للوحدات، لذا انظر <nowiki/>[[TypeScript/modules|توثيق الوحدات]] للاستزادة قبل البدء بقراءته.<br />
<br />
===[[TypeScript/declaration_merging|دمج التصريحات]]===<br />
مبدأ دمج التصريحات (declaration merging) من المزايا التي تنفرد بها TypeScript. تصِف بعض المبادئ الفريدة الموجودة في لغة TypeScript شكل كائنات JavaScript على مستوى الأنواع. سيُساعد فهم هذا المبدأ على العمل مع شيفرة JavaScript الموجودة مسبقًا. إضافة إلى أنّها توفّر قدرة على إعمال مبادئ تجريد (abstraction concepts) أكثر تقدّمًا.<br />
<br />
===[[TypeScript/jsx|JSX]]===<br />
JSX بنيةٌ (syntax) مشابهةٌ للغة XML يُمكن تضمينها وتحويلها إلى شيفرة JavaScript صالحة، لكن آلية عملية التحويل تختلف من تطبيق (implementation) إلى آخر. اشتهرت JSX باستخدامها مع مكتبة React، لكنها تملك تطبيقات أخرى غير React. تدعم لغة TypeScript تضمين JSX، وتدقيق الأنواع فيها، وكذا ترجمة JSX إلى JavaScript مباشرةً.<br />
<br />
===[[TypeScript/decorators|المزخرفات]]===<br />
مع إضافة الأصناف إلى TypeScript ونسخة ES6، فقد ظهرت كذلك حاجةٌ إلى ميزات إضافية لدعم تعديل الأصناف وعناصر الأصناف أو توصيفها (annotating). توفّر المزخرفات (Decorators) طريقة لإضافة توصيفات وبنية برمجة وصفيّة (meta-programming) لتصريحات الأصناف وعناصرها. المزخرفات حاليًّا [https://github.com/tc39/proposal-decorators اقتراح في المرحلة 2] (stage 2 proposal) في JavaScript وهي متوفّرة كميّزة تجريبيّة في TypeScript.<br />
<br />
===[[TypeScript/mixins|المخاليط]]===<br />
إضافةً إلى تسلسلات البرمجة كائنية التوجه التقليدية، هناك كذلك طريقة شائعة لبناء أصناف من مكونات قابلة لإعادة الاستعمال، وهي بناؤها عبر دمج أصناف جزئية أبسط. قد تكون فكرة المخاليط (mixins) أو السمات (traits) في لغات مثل Scala مألوفة بالنسبة إليك، وقد أصبح نمط المخاليط مشهورًا في مجتمع JavaScript كذلك.<br />
<br />
===[[TypeScript/triple_slash_directives|تعليمات الشرطات المائلة الثلاث]]===<br />
تعليمات الشرطات المائلة الثلاث (Triple-slash directives) هي تعليقات تكتب في سطر واحد تحتوي على وسم XML واحد. تُستخدَم محتويات التعليق كتعليمات (إرشادات) للمترجم.<br />
<br />
===[[TypeScript/type_checking_javascript_files|التحقق من الأنواع في ملفات JavaScript]]===<br />
أصبحت TypeScript منذ النسخة 2.3 تدعم التحقق من الأنواع والإبلاغ عن الأخطاء في ملفّات <code>.js</code> مع خيار المترجم <code>--checkJs</code>.<br />
<br />
==ملفات التعريفات==<br />
===[[TypeScript/declaration_files/introduction|مدخل إلى ملفات التصريحات (Declaration Files)]]===<br />
هذا القسم مصمَّم لإرشادك إلى كيفيّة كتابة ملفّات تصريحاتٍ (Declaration Files) عاليّة الجودة في TypeScript. يفترض هذا القسم أنّ لك معرفةً بأساسيّات لغة TypeScript. اقرأ توثيق لغة TypeScript في الأعلى لتفهم مبادئ اللغة الأساسيّة، خاصّة [[TypeScript/basic types|الأنواع]] و<nowiki/>[[TypeScript/namespaces|مجالات الأسماء]].<br />
<br />
===[[TypeScript/declaration_files/library_structures|هياكل المكتبات]]===<br />
طريقة هيكلة ملفّ التصريحات الخاص بك تعتمد عمومًا على كيفيّة اعتماد المستخدمين على المكتبة. هناك عدّة طرق يُمكن بها توفير المكتبة ليستخدمها الآخرون في JavaScript. وستحتاج إلى كتابة ملفّ تصريحاتٍ ملائم حسب هيكل المكتبة التي ترغب بكتابة ملفّ تصريحات لها. يغطي هذا القسم كيفيّة التعرّف على أنماط المكتبات الشائعة، وكيفيّة كتابة ملف تصريحاتٍ مناسب لنمط المكتبة.<br />
<br />
===[[TypeScript/declaration_files/by_example|ملفات التصريحات اعتمادًا على الأمثلة]]===<br />
الهدف من هذا القسم هو تعليمك كيفيّة كتابة ملف تعريف عالي الجودة. هذا القسم يريك أولًا توثيق واجهة برمجية (API) معيّنة مع طريقة استعمالها، ثم يشرح كيفية كتابة التصريح الملائم.<br />
<br />
===[[TypeScript/declaration_files/do_s_and_don_ts|افعل ولا تفعل]]===<br />
يعطيك هذا القسم العديد من النصائح والتنبيهات المفيدة والأخطاء الشائعة التي ستحتاج إليها لكتابة شيفرة نقية ونظيفة وفعَّالة باستعمال لغة TypeScript.<br />
<br />
===[[TypeScript/declaration_files/deep_dive|التعمق في ملفات التصريحات]]===<br />
دليلك لكتابة ملفّات تعريفات معقّدة ذات واجهة برمجيّة سهلة الاستخدام.<br />
<br />
===[[TypeScript/declaration_files/templates|قوالب ملفات التصريحات]]===<br />
يوجد في هذا القسم قائمة بملفّات تصريحاتٍ ستساعدك كبدايةٍ لكتابة ملفّاتك الخاصّة؛ للاستفادة من هذا القسم، انظر صفحة <nowiki/>[[TypeScript/declaration files/library structures|هياكل المكتبات]] للتعرف على الملفّ الذي يجب عليك استخدامه.<br />
===[[TypeScript/declaration_files/publishing|نشر ملفات التصريحات]]===<br />
يشرح هذا القسم الطريقتان الرئيسيتان لنشر ملفات تصريحاتك التي أنشأتها على منصة npm وهما: تجميعه (bundling) مع حزمة npm الخاصة بك، أو نشره على [https://www.npmjs.com/~types منظمة @types] على npm.<br />
<br />
===[[TypeScript/declaration_files/consumption|استخدام ملفات التصريحات]]===<br />
أصبح استخدام ملفات التصريحات سهلًا جدًّا منذ النسخة 2.0 من TypeScript، إذ أصبح الحصول عليها واستخدامها والعثور عليها أبسط من ذي قبل. سيساعدك هذا القسم على القيام بهذه العمليات الثلاث.<br />
<br />
==إعدادات المشروع==<br />
===[[TypeScript/tsconfig.json|tsconfig.json]]===<br />
وجود ملفٍّ باسم tsconfig.json في مجلّدٍ ما إشارةٌ إلى أنّ المجلّد هو جذر (root) مشروع TypeScript. يُحدِّد الملفّ tsconfig.json الملفات الجذر (root files) وخيارات الترجمة المطلوبة لترجمة المشروع.<br />
<br />
===[[TypeScript/compiler_options|خيارات المترجم]]===<br />
يوضح هذا القسم جميع الخيارات التي يمكن استعمالها مع مترجم TypeScript للتحكم بسير عمله والتعديل على سلوكه أثناء ترجمة الشيفرات. <br />
<br />
===[[TypeScript/compiler_options_in_msbuild|ضبط خيارات المترجم في مشاريع MSBuild]]===<br />
يشرح هذا القسم كيفية تحديد خيارات المترجم وضبطها عبر استخدام خاصيات MSBuild في مشروع MSBuild.<br />
<br />
===[[TypeScript/integrating_with_build_tools|استعمال أدوات البناء مع TypeScript]]===<br />
يوضّح هذا القسم كيفيّة استخدام أدوات البناء (Build tools) المشهورة مع شيفرة TypeScript.<br />
<br />
===[[TypeScript/nightly_builds|البناءات الليليّة]]===<br />
يُنشَر بناء ليليّ (nightly build) من [https://github.com/Microsoft/TypeScript/tree/master فرع master] في مستودع TypeScript كل منتصف ليلٍ بتوقيت PST إلى NPM و NuGet. هذا القسم يشرح كيفية الحصول على هذا البناء وكيفية الاعتماد عليه مع أدواتك.<br />
<br />
== مصادر ==<br />
* [https://www.typescriptlang.org/docs/home.html توثيق TypeScript الرسمي.]<br />
[[تصنيف:TypeScript]]<br />
{{#seo:<br />
description=شرح TypeScript باللغة العربية مدعّم بالأمثلة ضمن توثيق موسوعة حسوب الكامل وعالي الجودة لمختلف لغات البرمجة وتقنيات الويب والجوال.<br />
}}</div>عاطف-بن-عليhttps://wiki.hsoub.com/index.php?title=React&diff=30218React2021-02-14T17:58:20Z<p>عاطف-بن-علي: مراجعة الترجمة</p>
<hr />
<div>React (والتي تُعرَف أيضًا باسم React.js أو ReactJS) هي مكتبة JavaScript تُستخدَم لبناء واجهات المستخدم. تُدار React من شركة Facebook بالإضافة إلى مجتمع كبير من المطورين، فهي مشروعٌ مفتوح المصدر.<br />
<br />
تُسهِّل React عملية إنشاء واجهات مستخدم تفاعليّة. عليك فقط تصميم عروض (views) لكل حالة في تطبيقك، وستُحدِّث React المكوّنات الصحيحة بكفاءة وتقوم بتُصيّرها عندما تتغير بياناتك.<br />
<br />
تعتمد React بشكل أساسي على مفهوم المكوّنات (Components). حيث يجب عليك بناء مكوّنات مُغلَّفة تُدير حالتها الخاصّة، ومن ثمّ تُركِّب هذه المكوّنات مع بعضها لإنشاء واجهات مستخدم مُعقّدة. ولمّا كان منطق المكوّنات مكتوبا باستخدام JavaScript بدلًا من صيغة القوالب، فبإمكانك تمرير الكثير من البيانات عبر تطبيقك بسهولة وإبقاء الحالة بعيدة عن DOM.<br />
<br />
تسير React على مبدأ «تعلّم مرّة واكتب في أي مكان»، إذ لا تفترض تعاملك مع تقنية مُحدّدة، بل تستطيع تطوير ميزات جديدة فيها دون إعادة كتابة شيفرة جديدة. يُمكِن تصيير React على الخادوم باستخدام [[Node.js]]، ويُمكن من خلالها إنشاء تطبيقات الهواتف النقالة عبر React Native.<br />
<br />
{{:React/Topics}}<br />
[[تصنيف:React]]<br />
{{#seo:<br />
description=شرح React.js باللغة العربية مدعّم بالأمثلة ضمن توثيق موسوعة حسوب الكامل وعالي الجودة لمختلف لغات البرمجة وتقنيات الويب والجوال.<br />
}}</div>عاطف-بن-عليhttps://wiki.hsoub.com/index.php?title=Laravel/Topics&diff=29792Laravel/Topics2020-08-03T05:23:38Z<p>عاطف-بن-علي: تصحيح ترجمة dependencies</p>
<hr />
<div>== البدء باستخدام Laravel ==<br />
=== [[Laravel/installation|التثبيت]] ===<br />
شرح متطلبات الخادوم، وكيفية تثبيت Laravel وضبط خادوم الويب.<br />
<br />
=== [[Laravel/configuration|الضبط]] ===<br />
كيفية ضبط إطار Laravel، والدخول في وضع الصيانة.<br />
<br />
=== [[Laravel/structure|بنية المجلدات في Laravel]] ===<br />
التعرّف على بنية المجلدات الموجودة في إطار Laravel ووظيفة كلٍّ منها.<br />
<br />
=== [[Laravel/homestead|بيئة Laravel Homestead]] ===<br />
التعرف على طريقة استخدام Laravel Homestead لتسهيل توفير بيئة متكاملة تشغِّل إطار Laravel.<br />
<br />
=== [[Laravel/valet|بيئة تطوير Valet Laravel]] ===<br />
بيئة Valet Laravel تشبه بيئة Laravel Homestead لكنها مخصصة لأجهزة ماك.<br />
<br />
=== [[Laravel/deployment|النشر على الخادوم الإنتاجي]] ===<br />
شرح النقاط المهمة التي يجب الانتباه إليها عند نشر تطبيق Laravel على خادومٍ إنتاجي.<br />
<br />
== المفاهيم البنيوية ==<br />
=== [[Laravel/lifecycle|دورة حياة الطلب (Request Lifecycle)]] ===<br />
أخذ نظرة عامة عمّا يجري داخل إطار Laravel لفهم آلية عمله فهمًا جيدًا.<br />
<br />
=== [[Laravel/container|حاوي الخدمات (Service Container)]] ===<br />
شرح طريقة إضافة التبعيات باستخدام حاوي الخدمات.<br />
<br />
=== [[Laravel/providers|مقدمو الخدمات (Service Providers)]] ===<br />
شرح مفهوم تقديم الخدمات، وكيفية تسجيل مقدمي الخدمات.<br />
<br />
=== [[Laravel/facades|الواجهات الساكنة (Facades)]] ===<br />
شرح مفهوم الواجهات الساكنة ومتى نستخدمها، وكيفية عملها.<br />
<br />
=== [[Laravel/contracts|العقود (Contracts)]] ===<br />
شرح مفهوم العقود ومتى نستخدمها، وكيفية عملها.<br />
<br />
== الأساسيات ==<br />
=== [[Laravel/routing|التوجيه (Routing)]] ===<br />
شرح أساسيات التوجيه المستعملة في إطار Laravel.<br />
===[[Laravel/middleware|البرمجيات الوسيطة (Middleware)]]===<br />
كيفية تعريف وتسجيل البرمجيات الوسيطة التي توفِّر آلية لفرز طلبيات HTTP.<br />
===[[Laravel/csrf|الحماية من هجمات CSRF]]===<br />
سبل الحماية من هجمات تزوير الطلب العابر للمواقع.<br />
===[[Laravel/controllers|وحدات التحكّم (Controllers)]]===<br />
تعريف وحدات التحكم والفائدة منها وطريقة استعمالها.<br />
===[[Laravel/requests|طلبات HTTP]]===<br />
التعامل مع طلبات HTTP في Laravel.<br />
===[[Laravel/responses|ردود HTTP]]===<br />
التعامل مع ردود HTTP في Laravel.<br />
===[[Laravel/views|الواجهات (Views)]]===<br />
كيفية إنشاء الواجهات وطريقة تمرير البيانات إليها.<br />
===[[Laravel/urls|توليد عناوين URL]]===<br />
طريقة توليد روابط URL لمختلف أجزاء التطبيق.<br />
===[[Laravel/session|جلسات HTTP]]===<br />
شرح كيفية تخزين البيانات في الجلسات واستردادها، وغير ذلك من المواضيع المرتبطة بالجلسات.<br />
===[[Laravel/validation|التحقق (Validation)]]===<br />
كيفية التحقق من صحة البيانات الواردة إلى التطبيق.<br />
===[[Laravel/errors|معالجة الأخطاء (Error Handling)]]===<br />
شرح كيف يعالج إطار Laravel الأخطاء.<br />
===[[Laravel/logging|التسجيل (Logging)]]===<br />
ضبط Laravel لتسجيل الرسائل على ملفات أو في سجل النظام أو إلى قناة Slack مخصصة.<br />
<br />
== الواجهة الأمامية ==<br />
=== [[Laravel/blade|قوالب Blade]] ===<br />
التعريف بمحرك القولبة الخاص بإطار Laravel وشرح كيفيّة استخدامه.<br />
<br />
=== [[Laravel/localization|التوطين]] ===<br />
شرح طريقة التوطين في Laravel.<br />
<br />
=== [[Laravel/frontend|بناء Javascript و CSS]] ===<br />
شرح كيفية تعامل Laravel مع الواجهات الأمامية.<br />
<br />
=== [[Laravel/mix|ترجمة الأصول (Laravel Mix)]] ===<br />
كيفيّة معالجة الأصول في تطبيق Laravel.<br />
<br />
== الأمان والحماية ==<br />
=== [[Laravel/authentication|الاستيثاق (Authentication)]] ===<br />
شرح برمجة نظام الاستيثاق وطرقه.<br />
<br />
=== [[Laravel/passport|الاستثياق باستخدام واجهة API خارجية (API Authentication)]] ===<br />
شرح برمجة نظام الاستيثاق باستخدام واجهة برمجية خارجية.<br />
<br />
=== [[Laravel/authorization|الترخيص (Authorization)]] ===<br />
كيفيّة ترخيص عمليات المستخدم على مورد معين.<br />
<br />
=== [[Laravel/encryption|التشفير (Encryption)]] ===<br />
شرح كيف يشفّر Laravel البيانات.<br />
<br />
=== [[Laravel/hashing|التجزئة (Hashing)]] ===<br />
التعرّف على كيفيّة التجزئة لتخزين كلمات مرور المستخدم.<br />
<br />
=== [[Laravel/passwords|إعادة تعيين كلمات المرور (Password Reset)]] ===<br />
شرح طرق إعادة تعيين كلمات المرور المنسية.<br />
<br />
== التعمق في Laravel ==<br />
=== [[Laravel/artisan|الأمر Artisan console) Artisan)]] ===<br />
التعريف بواجهة الأوامر المُرفقة مع Laravel.<br />
<br />
=== [[Laravel/broadcasting|البث (Broadcasting)]] ===<br />
كيفيّة بثّ الأحداث عن طريق websocket.<br />
<br />
=== [[Laravel/cache|التخزين المؤقت (Cache)]] ===<br />
التعريف بالواجهات البرمجيّة الخاصة بالتخزين المؤقت.<br />
<br />
=== [[Laravel/collections|المجموعات (Collections)]] ===<br />
كيفيّة التعامل مع مصفوفات البيانات عن طريق المجموعات.<br />
<br />
=== [[Laravel/events|الأحداث (Events)]] ===<br />
التعريف بالأحداث والمُنصتات وكيفيّة التعامل معهنّ.<br />
<br />
=== [[Laravel/filesystem|تخزين الملفات (File storage)]] ===<br />
شرح كيف يخزن Laravel الملفات.<br />
<br />
=== [[Laravel/helpers|الدوال المساعدة (Helpers)]] ===<br />
التعريف بالدوال المساعدة وطريقة استعمالها.<br />
<br />
=== [[Laravel/mail|التعامل مع البريد الإلكتروني (Mail)]] ===<br />
شرح كيف يتعامل Laravel مع الرسائل الإلكترونية.<br />
<br />
=== [[Laravel/notifications|الإشعارات (Notifications)]] ===<br />
شرح كيف يتعامل Laravel مع الإشعارات.<br />
<br />
=== [[Laravel/packages|الحزم (Package development)]] ===<br />
التعريف بالحزم وطريقة استخدامها.<br />
<br />
=== [[Laravel/queues|طوابير الانتظار (Queues)]] ===<br />
شرح طريقة التعامل مع طوابير الانتظار.<br />
<br />
=== [[Laravel/scheduling|جدولة المهام (Task scheduling)]] ===<br />
تعريف جدولة المهام وبيان كيفيّتها.<br />
<br />
== قواعد البيانات ==<br />
=== [[Laravel/database|مقدمة إلى التعامل مع قواعد البيانات]] ===<br />
شرح أساسيات التعامل مع قواعد البيانات في إطار Laravel.<br />
<br />
=== [[Laravel/queries|منشئ الاستعلامات]] ===<br />
التعريف بمنشئ الاستعلامات في Laravel وكيفيّة عمله.<br />
<br />
=== [[Laravel/pagination|ترقيم الصفحات Pagination]] ===<br />
شرح كيفيّة ترقيم الصفحات مع بيان استخداماته.<br />
<br />
=== [[Laravel/migrations|تهجير قاعدة البيانات]] ===<br />
تعريف تهجير قاعدة البيانات وشرح كيفيّته.<br />
<br />
=== [[Laravel/seeding|بذر قواعد البيانات بالبيانات الاختبارية Seeding]] ===<br />
شرح كيفيّة بذر قواعد البيانات بالبيانات الاختبارية.<br />
<br />
=== [[Laravel/redis|التعامل مع قواعد بيانات Redis]] ===<br />
كيفيّة استخدام Redis مع إطار Laravel.<br />
<br />
== رابط الكائنات بالعلاقات Eloquent ==<br />
=== [[Laravel/eloquent|مقدمة إلى رابط الكائنات بالعلاقات Eloquent]] ===<br />
التعريف برابط الكائنات بالعلاقات Eloquent المضمّن في Laravel.<br />
<br />
=== [[Laravel/eloquent_relationships|العلاقات في رابط الكائنات بالعلاقات Eloquent]] ===<br />
شرح مفهوم العلاقات في رابط الكائنات بالعلاقات Eloquent مع بيان كيفيّة استخدامها.<br />
<br />
=== [[Laravel/eloquent_collections|المجموعات في رابط الكائنات بالعلاقات Eloquent]] ===<br />
تعريف المجموعات في رابط الكائنات بالعلاقات Eloquent.<br />
<br />
=== [[Laravel/eloquent_mutators|المعدلات في رابط الكائنات بالعلاقات Eloquent]] ===<br />
التعريف بالمعدلات والموصلات في رابط الكائنات بالعلاقات Eloquent وشرح طريقة استعمالها.<br />
<br />
=== [[Laravel/eloquent_resources|الموارد في رابط الكائنات بالعلاقات Eloquent]] ===<br />
تعريف الموارد في رابط الكائنات بالعلاقات Eloquent.<br />
<br />
=== [[Laravel/eloquent_serialization|السلسلة في رابط الكائنات بالعلاقات Eloquent]] ===<br />
شرح كيفيّة السلسلة في رابط الكائنات بالعلاقات Eloquent.<br />
<br />
== الاختبار ==<br />
=== [[Laravel/testing|مقدمة إلى التعامل مع الاختبارات]] ===<br />
التعريف ببيئة الاختبارات في Laravel.<br />
<br />
=== [[Laravel/http_tests|اختبارات HTTP]] ===<br />
شرح كيفية اختبارات HTTP.<br />
<br />
=== [[Laravel/dusk|اختبارات المتصفح (Laravel Dusk)]] ===<br />
كيفيّة أتمتة المتصفّح واختبار الواجهات البرمجيّة.<br />
<br />
=== [[Laravel/database_testing|اختبارات قواعد البيانات]] ===<br />
شرح أساسيات اختبارات قواعد البيانات.<br />
<br />
=== [[Laravel/mocking|تزييف الأحداث لأغراض الاختبار Mocking]] ===<br />
شرح مفهوم تزييف الأحداث للاختبار مع بيان طرقه.<br />
<br />
== الحزم الرسمية ==<br />
=== [[Laravel/billing|Laravel Cashier]] ===<br />
التعريف بحزمة اشتراكات خدمات الفواتير Stripe و Braintree.<br />
<br />
=== [[Laravel/envoy|مشغِّل المهام Envoy]] ===<br />
التعريف بمشغّل المهام وكيفيّة ضبطه.<br />
<br />
=== [[Laravel/horizon|Laravel Horizon]] ===<br />
التعريف بحزمة التحكم في نظام الطوابير.<br />
<br />
=== [[Laravel/passport|الاستثياق باستخدام واجهة API خارجية]] ===<br />
شرح برمجة نظام الاستيثاق باستخدام واجهة برمجية خارجية.<br />
<br />
=== [[Laravel/scout|Laravel Scout]] ===<br />
التعريف بحزمة البحث عن نص كامل في نماذج Eloquent وكيفيّة ضبطها.<br />
<br />
=== [[Laravel/socialite|Laravel Socialite]] ===<br />
التعريف بحزمة الاستيثاق مع موفري OAuth وكيفيّة ضبطها.</div>عاطف-بن-عليhttps://wiki.hsoub.com/index.php?title=Laravel/installation&diff=29791Laravel/installation2020-08-03T05:22:20Z<p>عاطف-بن-علي: مراجعة الترجمة</p>
<hr />
<div><noinclude>{{DISPLAYTITLE:تثبيت Laravel }}</noinclude><br />
== متطلبات الخادوم ==<br />
يتطلب إطار [[Laravel]] بعض متطلبات النظام. بالطبع ، يتم استيفاء جميع هذه المتطلبات من خلال النظام الوهمي لبيئة -Laravel (باسم [[Laravel/homestead|Homestead]])- لذلك يوصى باستخدام بيئة [[Laravel/homestead|Homestead]] بيئة تطوير [[Laravel]] المحلية الخاصة بك.<br />
<br />
ومع ذلك، إذا لم تكن بيئة [[Laravel/homestead|Homestead]] متاحةً لك أو لم ترغب في استخدامها، فستحتاج إلى التأكد من أن الخادوم يلبي المتطلبات التالية:<br />
* PHP >= 7.1.3<br />
* ملحق OpenSSL PHP<br />
* ملحق PDO PHP<br />
* ملحق Mbstring PHP<br />
* ملحق Tokenizer PHP<br />
* ملحق XML PHP<br />
* ملحق Ctype PHP<br />
* ملحق JSON PHP<br />
* ملحق BCMath PHP<br />
<br />
== تثبيت Laravel ==<br />
يستخدم إطار العمل [[Laravel]] برمجية Composer لإدارة التبعيات. لذا تأكد من تثبيت Composer على حاسوبك، قبل استخدام [[Laravel]].<br />
<br />
=== باستخدام مُثبِّت [[Laravel]] ===<br />
حمّل أوّلًا مثبّت [[Laravel]] باستخدام Composer :<syntaxhighlight lang="text"><br />
composer global require "laravel/installer"<br />
<br />
</syntaxhighlight>احرص على إضافة مجلد <code>vendor/bin</code> الخاصة ببرنامج Composer إلى متغير البيئة <code>$PATH</code> بحيث يمكن تحديد موقع الملف القابل للتنفيذ لإطار عمل [[Laravel]] بواسطة النظام الخاص بك. يوجد هذا المجلد في مواقع مختلفة اعتمادًا على نظام التشغيل الخاص بك؛ ومع ذلك، من الشائع أن يوجد في المسارات الآتية:<br />
<br />
· في نظام ماك: في المسار <code>$HOME/.composer/vendor/bin</code><br />
<br />
· في توزيعات لينكس: في المسار <code>$HOME/.config/composer/vendor/bin</code><br />
<br />
بعد تثبيته، سيُنشِئ الأمر <code>laravel new</code> مجلدًا يحتوي على نسخة جديدة من إطار [[Laravel]]. على سبيل المثال، سيُنشِئ الأمر <code>laravel new blog</code> مجلدًا جديدًا باسم blog يحتوي على تثبيت [[Laravel]] جديد مع جميع تبعيات [[Laravel]] اللازمة.<syntaxhighlight lang="text"><br />
laravel new blog<br />
</syntaxhighlight><br />
<br />
=== باستخدام Composer ===<br />
بدلا عن ذلك، يمكنك أيضًا تثبيت [[Laravel]] بتنفيذ الأمر <code>create-project</code> الخاص ببرمجية Composer في الطرفية على جهازك:<syntaxhighlight lang="text"><br />
composer create-project --prefer-dist laravel/laravel blog<br />
</syntaxhighlight><br />
<br />
=== باستخدام خادوم التطوير المحلي ===<br />
إذا كنت قد قمت بتثبيت [[PHP]] محليًا وترغب في استخدام خادوم التطوير الخاص بلغة PHP لخدمة تطبيقك، فيمكنك استخدام الأمر <code>Artisan serve</code>. سيبدأ هذا الأمر خادوم تطوير على<code><nowiki>http://localhost:8000</nowiki></code>:<syntaxhighlight lang="text"><br />
php artisan serve<br />
</syntaxhighlight>بالطبع، تتوفر خيارات التطوير المحلية الأكثر قوة من خلال [[Laravel/homestead|Homestead]] و [[Laravel/valet|Valet]].<br />
<br />
== الضبط ==<br />
<br />
=== المجلد العام ===<br />
بعد تثبيت [[Laravel]] ، يجب عليك ضبط جذر لخادوم الويب الخاص بك ليكون المجلد public. يعمل الملف <code>index.php</code> في هذا المسار بصفته وحدة تحكم أمامية لجميع طلبات HTTP التي تدخل التطبيق الخاص بك.<br />
<br />
=== ملفات الضبط ===<br />
تُخزَّن كافة ملفات الضبط الخاصة بإطار [[Laravel]] في مجلد <code>config.</code> كل خيار من تلك الخيارات موثقٌ توثيقًا كاملًا، لذلك لا تتردد في إلقاء نظرة على الملفات والتعرف على الخيارات المتاحة لك.<br />
<br />
=== أذونات المجلد ===<br />
بعد تثبيت Laravel، قد تحتاج إلى ضبط بعض الأذونات (permissions). يجب أن تكون المجلدات داخل مجلد storage ومجلد <code>bootstrap/cache</code> قابلةً للكتابة بواسطة خادوم الويب أو فلن يعمل Laravel. إذا كنت تستخدم بيئة عمل [[Laravel/homestead|Homestead]]، فستكون الأذونات المطلوبة مضبوطةً مسبقًا.<br />
<br />
=== مفتاح التطبيق ===<br />
أول ما عليك فعله بعد تثبيت Laravel هو ضبط مفتاح التطبيق الخاص بك إلى سلسلة نصية عشوائية. إذا قمت بتثبيت [[Laravel]] باستخدام Composer أو مثبت Laravel، فقد ضُبِطَ هذا المفتاح لك باستخدام الأمر <code>php artisan key:generate</code>.<br />
<br />
يجب أن تكون هذه السلسلة بطول 32 محرفًا عادةً. يمكن تعيين المفتاح في ملف البيئة .env. إذا لم تُعِد تسمية الملف <code>.env.example</code> إلى <code>.env</code>، فيجب عليك القيام بذلك الآن. إذا لم يُضبَط مفتاح التطبيق، فلن تكون جلسات المستخدم الخاصة بك وغيرها من البيانات المشفرة آمنة!<br />
<br />
=== الضبط الإضافي ===<br />
لا يحتاج Laravel إلى أي ضبط آخر مبدئيًا. يمكنك البدء بالتطوير فورًا. ومع ذلك، قد ترغب في مراجعة الملف <code>config/app.php</code> وتوثيقه. هذا الملف يحتوي على العديد من الخيارات مثل المنطقة الزمنية (timezone) والمحليّة (locale ) والتي قد ترغب في تغييرها وفقًا لتطبيقك.<br />
<br />
قد ترغب أيضًا في تكوين بعض المكونات الإضافية في [[Laravel]]، مثل:<br />
* ذاكرة التخزين المؤقتة<br />
* قاعدة البيانات<br />
* الجلسة<br />
<br />
== ضبط خادوم الويب ==<br />
<br />
=== عناوين URL جذابة ===<br />
<br />
==== خادوم [[Apache]] ====<br />
يتضمن Laravel الملف <code>public/.htaccess</code> الذي يُستخدم لتوفير عناوين URL دون وحدة التحكم <code>index.php</code> الأمامية في المسارات. قبل تخديم <nowiki/>[[Laravel]] مع [[Apache]]، تأكد من تفعيل الوحدة <code>mod_rewrite</code> بحيث تُنفَّذ محتويات ملف <code>.htaccess</code> بواسطة الخادوم.<br />
<br />
إذا كان ملف <code>.htaccess</code> الذي يأتي مع [[Laravel]] لا يعمل مع تثبيت [[Apache]] عندك، فجرّب هذا الملف البديل:<syntaxhighlight lang="text"><br />
Options +FollowSymLinks -Indexes<br />
RewriteEngine On<br />
<br />
RewriteCond %{HTTP:Authorization} .<br />
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]<br />
<br />
RewriteCond %{REQUEST_FILENAME} !-d<br />
RewriteCond %{REQUEST_FILENAME} !-f<br />
RewriteRule ^ index.php [L]<br />
<br />
</syntaxhighlight><br />
<br />
==== خادوم <nowiki/>[[Nginx]] ====<br />
إذا كنت تستخدم خادوم [[Nginx]]، فإن تعليمة الضبط الآتية في ملف ضبط موقعك سيوجه جميع الطلبات إلى وحدة التحكم الأمامية <code>index.php</code>: <syntaxhighlight lang="php"><br />
location / {<br />
try_files $uri $uri/ /index.php?$query_string;<br />
}<br />
</syntaxhighlight>بالطبع، عند استخدام [[Laravel/homestead|Homestead]] أو [[Laravel/valet|Valet]]، سيتم ضبط عناوين URL جذابة تلقائيًا.<br />
<br />
== مصادر ==<br />
* [https://laravel.com/docs/5.7/installation صفحة Installation في توثيق Laravel الرسمي.]<br />
[[تصنيف:Laravel|{{SUBPAGENAME}}]]<br />
[[تصنيف:Laravel Getting started|{{SUBPAGENAME}}]]</div>عاطف-بن-عليhttps://wiki.hsoub.com/index.php?title=Laravel/Topics&diff=29790Laravel/Topics2020-08-03T05:14:38Z<p>عاطف-بن-علي: مراجعة الترجمة</p>
<hr />
<div>== البدء باستخدام Laravel ==<br />
=== [[Laravel/installation|التثبيت]] ===<br />
شرح متطلبات الخادوم، وكيفية تثبيت Laravel وضبط خادوم الويب.<br />
<br />
=== [[Laravel/configuration|الضبط]] ===<br />
كيفية ضبط إطار Laravel، والدخول في وضع الصيانة.<br />
<br />
=== [[Laravel/structure|بنية المجلدات في Laravel]] ===<br />
التعرّف على بنية المجلدات الموجودة في إطار Laravel ووظيفة كلٍّ منها.<br />
<br />
=== [[Laravel/homestead|بيئة Laravel Homestead]] ===<br />
التعرف على طريقة استخدام Laravel Homestead لتسهيل توفير بيئة متكاملة تشغِّل إطار Laravel.<br />
<br />
=== [[Laravel/valet|بيئة تطوير Valet Laravel]] ===<br />
بيئة Valet Laravel تشبه بيئة Laravel Homestead لكنها مخصصة لأجهزة ماك.<br />
<br />
=== [[Laravel/deployment|النشر على الخادوم الإنتاجي]] ===<br />
شرح النقاط المهمة التي يجب الانتباه إليها عند نشر تطبيق Laravel على خادومٍ إنتاجي.<br />
<br />
== المفاهيم البنيوية ==<br />
=== [[Laravel/lifecycle|دورة حياة الطلب (Request Lifecycle)]] ===<br />
أخذ نظرة عامة عمّا يجري داخل إطار Laravel لفهم آلية عمله فهمًا جيدًا.<br />
<br />
=== [[Laravel/container|حاوي الخدمات (Service Container)]] ===<br />
شرح طريقة إضافة الاعتمادات باستخدام حاوي الخدمات.<br />
<br />
=== [[Laravel/providers|مقدمو الخدمات (Service Providers)]] ===<br />
شرح مفهوم تقديم الخدمات، وكيفية تسجيل مقدمي الخدمات.<br />
<br />
=== [[Laravel/facades|الواجهات الساكنة (Facades)]] ===<br />
شرح مفهوم الواجهات الساكنة ومتى نستخدمها، وكيفية عملها.<br />
<br />
=== [[Laravel/contracts|العقود (Contracts)]] ===<br />
شرح مفهوم العقود ومتى نستخدمها، وكيفية عملها.<br />
<br />
== الأساسيات ==<br />
=== [[Laravel/routing|التوجيه (Routing)]] ===<br />
شرح أساسيات التوجيه المستعملة في إطار Laravel.<br />
===[[Laravel/middleware|البرمجيات الوسيطة (Middleware)]]===<br />
كيفية تعريف وتسجيل البرمجيات الوسيطة التي توفِّر آلية لفرز طلبيات HTTP.<br />
===[[Laravel/csrf|الحماية من هجمات CSRF]]===<br />
سبل الحماية من هجمات تزوير الطلب العابر للمواقع.<br />
===[[Laravel/controllers|وحدات التحكّم (Controllers)]]===<br />
تعريف وحدات التحكم والفائدة منها وطريقة استعمالها.<br />
===[[Laravel/requests|طلبات HTTP]]===<br />
التعامل مع طلبات HTTP في Laravel.<br />
===[[Laravel/responses|ردود HTTP]]===<br />
التعامل مع ردود HTTP في Laravel.<br />
===[[Laravel/views|الواجهات (Views)]]===<br />
كيفية إنشاء الواجهات وطريقة تمرير البيانات إليها.<br />
===[[Laravel/urls|توليد عناوين URL]]===<br />
طريقة توليد روابط URL لمختلف أجزاء التطبيق.<br />
===[[Laravel/session|جلسات HTTP]]===<br />
شرح كيفية تخزين البيانات في الجلسات واستردادها، وغير ذلك من المواضيع المرتبطة بالجلسات.<br />
===[[Laravel/validation|التحقق (Validation)]]===<br />
كيفية التحقق من صحة البيانات الواردة إلى التطبيق.<br />
===[[Laravel/errors|معالجة الأخطاء (Error Handling)]]===<br />
شرح كيف يعالج إطار Laravel الأخطاء.<br />
===[[Laravel/logging|التسجيل (Logging)]]===<br />
ضبط Laravel لتسجيل الرسائل على ملفات أو في سجل النظام أو إلى قناة Slack مخصصة.<br />
<br />
== الواجهة الأمامية ==<br />
=== [[Laravel/blade|قوالب Blade]] ===<br />
التعريف بمحرك القولبة الخاص بإطار Laravel وشرح كيفيّة استخدامه.<br />
<br />
=== [[Laravel/localization|التوطين]] ===<br />
شرح طريقة التوطين في Laravel.<br />
<br />
=== [[Laravel/frontend|بناء Javascript و CSS]] ===<br />
شرح كيفية تعامل Laravel مع الواجهات الأمامية.<br />
<br />
=== [[Laravel/mix|ترجمة الأصول (Laravel Mix)]] ===<br />
كيفيّة معالجة الأصول في تطبيق Laravel.<br />
<br />
== الأمان والحماية ==<br />
=== [[Laravel/authentication|الاستيثاق (Authentication)]] ===<br />
شرح برمجة نظام الاستيثاق وطرقه.<br />
<br />
=== [[Laravel/passport|الاستثياق باستخدام واجهة API خارجية (API Authentication)]] ===<br />
شرح برمجة نظام الاستيثاق باستخدام واجهة برمجية خارجية.<br />
<br />
=== [[Laravel/authorization|الترخيص (Authorization)]] ===<br />
كيفيّة ترخيص عمليات المستخدم على مورد معين.<br />
<br />
=== [[Laravel/encryption|التشفير (Encryption)]] ===<br />
شرح كيف يشفّر Laravel البيانات.<br />
<br />
=== [[Laravel/hashing|التجزئة (Hashing)]] ===<br />
التعرّف على كيفيّة التجزئة لتخزين كلمات مرور المستخدم.<br />
<br />
=== [[Laravel/passwords|إعادة تعيين كلمات المرور (Password Reset)]] ===<br />
شرح طرق إعادة تعيين كلمات المرور المنسية.<br />
<br />
== التعمق في Laravel ==<br />
=== [[Laravel/artisan|الأمر Artisan console) Artisan)]] ===<br />
التعريف بواجهة الأوامر المُرفقة مع Laravel.<br />
<br />
=== [[Laravel/broadcasting|البث (Broadcasting)]] ===<br />
كيفيّة بثّ الأحداث عن طريق websocket.<br />
<br />
=== [[Laravel/cache|التخزين المؤقت (Cache)]] ===<br />
التعريف بالواجهات البرمجيّة الخاصة بالتخزين المؤقت.<br />
<br />
=== [[Laravel/collections|المجموعات (Collections)]] ===<br />
كيفيّة التعامل مع مصفوفات البيانات عن طريق المجموعات.<br />
<br />
=== [[Laravel/events|الأحداث (Events)]] ===<br />
التعريف بالأحداث والمُنصتات وكيفيّة التعامل معهنّ.<br />
<br />
=== [[Laravel/filesystem|تخزين الملفات (File storage)]] ===<br />
شرح كيف يخزن Laravel الملفات.<br />
<br />
=== [[Laravel/helpers|الدوال المساعدة (Helpers)]] ===<br />
التعريف بالدوال المساعدة وطريقة استعمالها.<br />
<br />
=== [[Laravel/mail|التعامل مع البريد الإلكتروني (Mail)]] ===<br />
شرح كيف يتعامل Laravel مع الرسائل الإلكترونية.<br />
<br />
=== [[Laravel/notifications|الإشعارات (Notifications)]] ===<br />
شرح كيف يتعامل Laravel مع الإشعارات.<br />
<br />
=== [[Laravel/packages|الحزم (Package development)]] ===<br />
التعريف بالحزم وطريقة استخدامها.<br />
<br />
=== [[Laravel/queues|طوابير الانتظار (Queues)]] ===<br />
شرح طريقة التعامل مع طوابير الانتظار.<br />
<br />
=== [[Laravel/scheduling|جدولة المهام (Task scheduling)]] ===<br />
تعريف جدولة المهام وبيان كيفيّتها.<br />
<br />
== قواعد البيانات ==<br />
=== [[Laravel/database|مقدمة إلى التعامل مع قواعد البيانات]] ===<br />
شرح أساسيات التعامل مع قواعد البيانات في إطار Laravel.<br />
<br />
=== [[Laravel/queries|منشئ الاستعلامات]] ===<br />
التعريف بمنشئ الاستعلامات في Laravel وكيفيّة عمله.<br />
<br />
=== [[Laravel/pagination|ترقيم الصفحات Pagination]] ===<br />
شرح كيفيّة ترقيم الصفحات مع بيان استخداماته.<br />
<br />
=== [[Laravel/migrations|تهجير قاعدة البيانات]] ===<br />
تعريف تهجير قاعدة البيانات وشرح كيفيّته.<br />
<br />
=== [[Laravel/seeding|بذر قواعد البيانات بالبيانات الاختبارية Seeding]] ===<br />
شرح كيفيّة بذر قواعد البيانات بالبيانات الاختبارية.<br />
<br />
=== [[Laravel/redis|التعامل مع قواعد بيانات Redis]] ===<br />
كيفيّة استخدام Redis مع إطار Laravel.<br />
<br />
== رابط الكائنات بالعلاقات Eloquent ==<br />
=== [[Laravel/eloquent|مقدمة إلى رابط الكائنات بالعلاقات Eloquent]] ===<br />
التعريف برابط الكائنات بالعلاقات Eloquent المضمّن في Laravel.<br />
<br />
=== [[Laravel/eloquent_relationships|العلاقات في رابط الكائنات بالعلاقات Eloquent]] ===<br />
شرح مفهوم العلاقات في رابط الكائنات بالعلاقات Eloquent مع بيان كيفيّة استخدامها.<br />
<br />
=== [[Laravel/eloquent_collections|المجموعات في رابط الكائنات بالعلاقات Eloquent]] ===<br />
تعريف المجموعات في رابط الكائنات بالعلاقات Eloquent.<br />
<br />
=== [[Laravel/eloquent_mutators|المعدلات في رابط الكائنات بالعلاقات Eloquent]] ===<br />
التعريف بالمعدلات والموصلات في رابط الكائنات بالعلاقات Eloquent وشرح طريقة استعمالها.<br />
<br />
=== [[Laravel/eloquent_resources|الموارد في رابط الكائنات بالعلاقات Eloquent]] ===<br />
تعريف الموارد في رابط الكائنات بالعلاقات Eloquent.<br />
<br />
=== [[Laravel/eloquent_serialization|السلسلة في رابط الكائنات بالعلاقات Eloquent]] ===<br />
شرح كيفيّة السلسلة في رابط الكائنات بالعلاقات Eloquent.<br />
<br />
== الاختبار ==<br />
=== [[Laravel/testing|مقدمة إلى التعامل مع الاختبارات]] ===<br />
التعريف ببيئة الاختبارات في Laravel.<br />
<br />
=== [[Laravel/http_tests|اختبارات HTTP]] ===<br />
شرح كيفية اختبارات HTTP.<br />
<br />
=== [[Laravel/dusk|اختبارات المتصفح (Laravel Dusk)]] ===<br />
كيفيّة أتمتة المتصفّح واختبار الواجهات البرمجيّة.<br />
<br />
=== [[Laravel/database_testing|اختبارات قواعد البيانات]] ===<br />
شرح أساسيات اختبارات قواعد البيانات.<br />
<br />
=== [[Laravel/mocking|تزييف الأحداث لأغراض الاختبار Mocking]] ===<br />
شرح مفهوم تزييف الأحداث للاختبار مع بيان طرقه.<br />
<br />
== الحزم الرسمية ==<br />
=== [[Laravel/billing|Laravel Cashier]] ===<br />
التعريف بحزمة اشتراكات خدمات الفواتير Stripe و Braintree.<br />
<br />
=== [[Laravel/envoy|مشغِّل المهام Envoy]] ===<br />
التعريف بمشغّل المهام وكيفيّة ضبطه.<br />
<br />
=== [[Laravel/horizon|Laravel Horizon]] ===<br />
التعريف بحزمة التحكم في نظام الطوابير.<br />
<br />
=== [[Laravel/passport|الاستثياق باستخدام واجهة API خارجية]] ===<br />
شرح برمجة نظام الاستيثاق باستخدام واجهة برمجية خارجية.<br />
<br />
=== [[Laravel/scout|Laravel Scout]] ===<br />
التعريف بحزمة البحث عن نص كامل في نماذج Eloquent وكيفيّة ضبطها.<br />
<br />
=== [[Laravel/socialite|Laravel Socialite]] ===<br />
التعريف بحزمة الاستيثاق مع موفري OAuth وكيفيّة ضبطها.</div>عاطف-بن-عليhttps://wiki.hsoub.com/index.php?title=Design_Patterns/factory_method&diff=29664Design Patterns/factory method2020-03-12T06:30:11Z<p>عاطف-بن-علي: تعديل صياغة بعض الجمل وإصلاح أخطاء إملائية</p>
<hr />
<div><noinclude>{{DISPLAYTITLE:نمط أسلوب المصنع Factory Method}}</noinclude><br />
أسلوب المصنع (factory method) هو نمط تصميم إنشائي (creational) يوفر واجهة لإنشاء الكائنات (objects) داخل فئات رئيسة (superclasses) لكنها تسمح في نفس الوقت للفئات الثانوية (subclasses) بتغيير نوع تلك الكائنات التي سيتم إنشاؤها.<br />
<br />
== المشكلة ==<br />
[[ملف:factory1.png|تصغير|(ش.1) إضافة فئة جديدة إلى البرنامج ليست سهلة إن كانت بقية الشيفرة مقترنة بالفئات الموجودة مسبقًا.]]<br />
تخيل أنك تنشئ تطبيقًا لشحن البضائع، ولا تتعامل أول نسخة من ذلك التطبيق إلا مع الشحن البري بالشاحنات (Trucks)، فمن المنطقي حينها أن يكون أغلب شيفرتك البرمجية تحت فئة <code>Trucks</code>، لكن لنفرض أن التطبيق اشتهر بعد مدة وتوسعت الطلبات وبدأت تتلقى طلبات شحن بحري، فإنك ستحتاج عندئذ إلى إضافة فئة جديدة ليكن اسمها <code>Ships</code> مثلًا.<br />
لكن هذا الأسلوب سيحدِث تغييرات في كل الشيفرة البرمجية لديك، وإن قررت بعد فترة أخرى إضافة نوع آخر من الشحن إلى التطبيق -الجوي مثلًا- فستخوض هذه العملية كلها مرة ثالثة، وستكون النتيجة شيفرة مزدحمة فوضوية تملؤها العبارات الشرطية التي ستغير سلوك التطبيق بناءً على فئة كائنات الشحن. انظر (ش.1)<br />
<br />
== الحل ==<br />
[[ملف:solution1.png|تصغير|(ش.2) الفئات الفرعية بإمكانها تغيير فئة الكائنات التي يعيدها أسلوب المصنع.]]<br />
يقترح أسلوب المصنع هنا أن تستبدل الاستدعاءات المباشرة لإنشاء الكائنات -من خلال معامِل <code>new</code>- باستدعاءات لأسلوب factory الخاص، ما سيحدث هو أن الكائنات سيتم إنشاؤها بمعامل <code>new</code> كما تقدم لكنها ستُستَدعى من داخل أسلوب المصنع. ويشار إلى تلك الكائنات التي تُعاد (returned) بأسلوب المصنع باسم المنتجات (products).<br />
<br />
قد يبدو هذا التغيير لا معنى له في البداية، فما زدنا على نقل استدعاء الإنشاء (construction call) من مكان إلى آخر داخل البرنامج، لكن لاحظ الآن أنك تستطيع تخطي أسلوب المصنع داخل فئة فرعية (subclass) وتغير فئة المنتجات التي أنشئت بواسطته. انظر (ش.2)<br />
<br />
غير أن الأمر مقيَّد نوعًا ما، فالفئات الفرعية لن تعيد أنواعًا مختلفة من المنتجات إلا إن كانت تلك المنتجات لديها فئة أو واجهة أساسية مشتركة، كذلك يجب أن يكون نوع الإعادة لأسلوب المصنع في الفئة الأساسية مصرحًا به كالواجهة المشتركة التي ذكرناها.<br />
[[ملف:solution2-en.png|تصغير|(ش.3) يجب أن تتبع كل المنتجات نفس الواجهة.]]<br />
فمثلًا، يجب أن تستخدم الفئتان <code>Truck</code> و <code>Ship</code> واجهة <code>Transport</code> التي تصرح عن أسلوب اسمه <code>deliver</code>، وتنفذ كل فئة هذا الأسلوب بشكل مختلف، فالشاحنات تسلم حمولتها على الأرض، والسفن تسلمها عبر البحار، ويعيد أسلوب المصنع كائنات الشاحنات في فئة <code>RoadLogistics</code>، بينما يعيد سفنًا في فئة <code>SeaLogistics</code>. انظر (ش.3)<br />
<br />
[[ملف:solution3.png|تصغير|(ش.4) طالما أن كل فئات المنتجات تستخدم واجهة مشتركة فيمكنك تمرير كائناتهم إلى شيفرة العميل دون تعطيلها.]]<br />
<br />
ولا ترى الشيفرة البرمجية التي تستخدم أسلوب المصنع -قد يطلق عليها عادة شيفرة العميل (client code)- أي فرق بين المنتجات الحقيقية التي أعيدت من خلال الفئات الفرعية، ويعامل العميل جميع المنتجات مثل واجهة <code>Transport</code> افتراضية. ويعرف العميل أن كل كائنات النقل يجب أن يكون لديها أسلوب <code>deliver</code>، لكن لا يهم عنده كيفية عملها بالضبط. انظر (ش.4)<br />
<br />
== البُنية ==<br />
[[ملف:structure-indexed.png|تصغير]]<br />
# يصرّح '''المنتج''' بالواجهة التي ستكون مشتركة لكل الكائنات التي يمكن إنتاجها بواسطة المنشئ (creator) وفئاته الفرعية.<br />
# '''المنتجات الحقيقية (concrete products)''' هي الاستخدامات المختلفة لواجهة المنتج.<br />
# تصرّح فئة '''المنشئ''' عن أسلوب المصنع الذي يعيد كائنات المنتج الجديد، من المهم أن نوع الإعادة من هذا الأسلوب يطابق واجهة المنتج. تستطيع تصريح أسلوب المصنع بصفته أسلوبا افتراضيا لإجبار كل الفئات الفرعية على استخدام نسخها الخاص من الأسلوب، وكطريقة بديلة فإن أسلوب المصنع الأساسي يمكنه إعادة بعض الأنواع الافتراضية للمنتجات. لاحظ أن الوظيفة الأساسية للمنشئ (creator) '''ليست إنشاء المنتجات''' رغم التسمية التي توحي بهذا، فإن فئة المنشئ عادة يكون لها منطق عمل متعلق بالمنتجات، ويساعد أسلوب المصنع في فصل هذا المنطق عن فئات المنتجات الحقيقية. إليك مثالًا يوضح الأمر، تستطيع شركات البرمجيات الكبيرة توفير أقسام لتدريب المبرمجين، لكن ذلك لا يعني أن الوظيفة الأساسية للشركة ككل هي إنتاج مبرمجين، بل كتابة البرامج هي وظيفتها.<br />
# تتخطى '''المنشئات الحقيقية (Concrete Creators)''' أسلوب المصنع الأساسي لذا تعيد نوعًا مختلفًا من المنتجات. لاحظ أن أسلوب المصنع قد لا '''ينشئ''' حالات جديدة دومًا، فقد يعيد أحيانًا كائنات موجودة من مصادر مختلفة مثل الذاكرة المؤقتة (Cache memory) أو حوض الكائنات (object pool)، أو غيرها.<br />
<br />
== مثال توضيحي ==<br />
[[ملف:example.png|تصغير|مثال الصندوق الحواري الذي سيعمل على أكثر من منصة.]]<br />
يوضح المثال كيف يمكن استخدام '''أسلوب المصنع''' لإنشاء عناصر واجهة لأكثر من منصة دون الحاجة إلى جمع شيفرة العميل (client code) مع فئات واجهات المنتجات الحقيقية.<br />
<br />
تستخدم فئة الصندوق الحواري الأساسية عناصر واجهة مختلفة لإخراج نافذتها، وقد تبدو تلك العناصر بشكل مختلف لكل نظام تشغيل، لكنها ستتصرف بشكل ثابت فيهم جميعًا، فالزر الذي يظهر لك في ويندوز هو نفس الزر الذي سيظهر لك في لينكس.<br />
<br />
وحين يأتي دور أسلوب المصنع فلن تضطر إلى إعادة كتابة محتوى الصندوق الحواري لكل نظام تشغيل، فإن صرحنا أسلوبَ مصنع ينتج أزرارًا داخل فئة الصندوق الحواري الأساسية، فيمكننا لاحقًا إنشاء فئة صندوق حواري فرعية تعيد أزارًا بأسلوب ويندوز من أسلوب المصنع وتكتسب الفئة الفرعية عندئد أغلب شيفرة الصندوق الحواري من الفئة الأساسية لكنها ستُخرج أزرارًا بأسلوب ويندوز على الشاشة بسبب أسلوب المصنع.<br />
<br />
ولكي يعمل هذا النمط، يجب أن تعمل فئة الصندوق الحواري الأساسية مع أزرار افتراضية: مثل فئة أساسية أو واجهة تتبعها كل أزرار المنتجات الحقيقية، وبهذه الطريقة تظل شيفرة الصندوق الحواري عاملة بغض النظر عن نوع الأزرار التي تعمل معها.<br />
<br />
بالطبع يمكنك تطبيق هذا المنظور على عناصر الواجهة الأخرى كذلك، لكن مع كل أسلوب مصنع تضيفه إلى الصندوق الحواري فإنك تقترب أكثر من نمط [[Design Patterns/abstract factory|المصنع المجرد]].<syntaxhighlight lang="java"><br />
// تصرح فئة المنشئ عن أسلوب المصنع الذي يجب أن يعيد أحد الكائنات من فئة المنتج، وتوضح فئات المنشئ الفرعية<br />
// عادة استخدامات لهذا الأسلوب.<br />
class Dialog is<br />
// قد يوفر المنشئ أيضًا بعض الاستخدامات الافتراضية لأسلوب المصنع.<br />
abstract method createButton()<br />
<br />
// لاحظ أنه برغم التسمية فإن وظيفة المنشئ الأساسية ليست إنشاء منتجات، لكن له منطق عمل<br />
// يعتمد على كائنات المنتجات المعادة بأسلوب المصنع.<br />
// وتستطيع الفئات الفرعية تغيير منطق العمل ذاك بشكل غير مباشر عن طرق تخطي أسلوب المصنع<br />
// وإعادة نوع مختلف من المنتجات منه.<br />
method renderWindow() is<br />
// استدع أسلوب المصنع لإنشاء كائن منتج.<br />
Button okButton = createButton()<br />
// والآن، استخدم المنتج.<br />
okButton.onClick(closeDialog)<br />
okButton.render()<br />
<br />
<br />
// المنشئات الحقيقية تتخطى أسلوب المصنع لتغير نوع المنتج.<br />
class WindowsDialog extends Dialog is<br />
method createButton() is<br />
return new WindowsButton()<br />
<br />
class WebDialog extends Dialog is<br />
method createButton() is<br />
return new HTMLButton()<br />
<br />
<br />
// تصرح واجهة المنتج عن العمليات التي يجب أن تستخدمها كل المنتجات الحقيقية.<br />
interface Button is<br />
method render()<br />
method onClick(f)<br />
<br />
// توفر المنتجات الحقيقية استخدامات مختلفة لواجهة المنتج.<br />
class WindowsButton implements Button is<br />
method render(a, b) is<br />
// أخرج الزر بأسلوب ويندوز.<br />
method onClick(f) is<br />
// اربط حدث نقرة محلية في نظام التشغيل.<br />
<br />
class HTMLButton implements Button is<br />
method render(a, b) is<br />
// Return an HTML representation of a button.<br />
method onClick(f) is<br />
// اربط حدث نقرة في المتصفح.<br />
<br />
<br />
class Application is<br />
field dialog: Dialog<br />
<br />
// يختار التطبيق نوع المنشئ بناءً على الإعدادات الحالية أو إعدادات البيئة.<br />
method initialize() is<br />
config = readApplicationConfigFile()<br />
<br />
if (config.OS == "Windows") then<br />
dialog = new WindowsDialog()<br />
else if (config.OS == "Web") then<br />
dialog = new WebDialog()<br />
else<br />
throw new Exception("Error! Unknown operating system.")<br />
<br />
// تعمل الشيفرة الحالية للعميل مع نسخة من منشئ حقيقي، ولو من خلال واجهته الأساسية، فطالما أن العميل<br />
// يظل عاملًا مع المنشئ من خلال واجهة أساسيةن فيمكنك تمرير أي فئة منشئ فرعية إليه.<br />
method main() is<br />
dialog.initialize()<br />
dialog.render() <br />
</syntaxhighlight><br />
<br />
== قابلية التطبيق ==<br />
* '''استخدم أسلوب المصنع عند عدم معرفة أنواع الكائنات التي ستتعامل شيفرتك معها، وكذلك عند عدم معرفة اعتمادياتها.'''<br />
يفصل أسلوب المصنع شيفرة إنشاء المنتج عن الشيفرة التي تستخدم المنتج، ومن ثم يكون من السهل زيادة شيفرة إنشاء المنتج بشكل منفصل عن بقية الشيفرة. فمثلًان لإضافة نوع جديد من المنتجات إلى التطبيق، لن تحتاج إلا إلى إنشاء فئة creator فرعية جديدة لتتخطى بها أسلوب المصنع داخلها.<br />
* '''استخدم أسلوب المصنع حين تريد تزويد مستخدمي مكتبتك أو إطار عملك بطريقة لزيادة عناصره الداخلية.'''<br />
أسهل طريقة لتوسيع السلوك الافتراضي لمكتبة أو إطار عمل هو الاكتساب أو الوراثة (inheritance)، لكن أنّى لإطار العمل معرفة أن فئتك الفرعية يجب أن تُستخدم بدلًا من العنصر القياسي؟<br />
<br />
الحل هو تقليل الشيفرة التي ستنشئ العناصر في إطار العمل إلى أسلوب مصنع وحيد، وتسمح لأي كان أن يتخطى تلك الطريقة إضافة إلى توسعة العنصر ذاته.<br />
<br />
لنرى كيفية عمل ذلك، تخيل أنك تكتب تطبيقًا باستخدام إطار عمل مفتوح المصدر لواجهة المستخدم، يجب أن تكون الأزرار في تطبيقك دائرية الحواف، لكن إطار العمل لا يوفر سوى أزرار مربعة. الحل هنا أن توسع فئة <code>Button</code> بفئة فرعية لتكن <code>RoundButton</code>، لكنك الآن ستضطر إلى إخبار فئة <code>UIFramework</code> الرئيسية أن تستخدم فئة الأزرار الفرعية الجديدة بدلًا من الافتراضية.<br />
<br />
ولفعل ذلك تنشئ فئة فرعية لتكن <code>UIWithRoundButtons</code> من فئة إطار العمل الأساسية وتتخطى أسلوب <code>createButton</code> الخاص بها، ويمكنك أن تجعل فئتك الفرعية تعيد كائنات <code>RoundButton</code> رغم أن هذا الأسلوب يعيد كائنات <code>Button</code> في فئته الأساسية. والآن لم يتبق سوى أن تستخدم فئة <code>UIWithRoundButtons</code> بدلًا من <code>UIFramework</code>.<br />
* '''استخدم أسلوب المصنع عند توفير موارد النظام بإعادة استخدام الكائنات الموجودة بدلًا من إعادة إنشائهم في كل مرة.'''<br />
قد تحدث تلك الحالة حين تتعامل مع كائنات كبيرة وتستهلك الموارد مثل اتصالات قواعد البيانات أو أنظمة الملفات أو موارد الشبكات. إليك ما يجب فعله لإعادة استخدام كائن موجود فعلًا:<br />
# أولًا عليك توفير بعض المساحة لمتابعة كل الكائنات المنشأة.<br />
# عندما يطلب شخص أحد الكائنات فإن البرنامج يبحث عن كائن متاح في حوض الكائنات (object pool)، ثم يعيده إلى شيفرة العميل.<br />
# إن لم تكن هناك كائنات متاحة فيجب أن ينشئ البرنامج واحدًا ويضيفه إلى الحوض..<br />
هذه شيفرة طويلة، ويجب أن تجمعها كلها في مكان واحد لكي لا تلوث البرنامج بشيفرة مكررة.<br />
<br />
لعل أنسب مكان يمكن أن توضع فيه تلك الشيفرة هو منشئ (constructor) الفئة الذي نحاول أن نعيد استخدام كائناته، لكن يجب أن يعيد المنشئ '''كائنات جديدة''' افتراضيًا، فلا يعيد حالات موجودة فعلًا، لذا تحتاج أن يكون لديك أسلوب عادي قادر على إنشاء كائنات جديدة إضافة إلى إعادة استخدام الكائنات الموجودة، وهذا يشبه كثيرًا أسلوب المصنع.<br />
<br />
== كيفية الاستخدام ==<br />
# تأكد أن تتبع كل المنتجات نفس الواجهة، ويجب أن تصرح هذا الواجهة عن الأساليب التي تناسب كل منتج.<br />
# أضف أسلوب مصنع فارغ داخل فئة المنشئ (creator)، يجب أن يطابق نوع الإعادة واجهة المنتج المشتركة.<br />
# ابحث عن كل المراجع إلى منشئات المنتج (product constructors) داخل شيفرة المنشئ (creator)، واستبدل كل واحدة فيهم باستدعاءات إلى أسلوب المصنع في نفس الوقت الذي تستخرج فيه شيفرة إنشاء المنتج (creation code) إلى أسلوب المصنع، قد تحتاج إلى إضافة معامل مؤقت لأسلوب المصنع من أجل التحكم في نوع المنتج المُعاد. وقد تبدو شيفرة أسلوب المصنع في هذه المرحلة قبيحة، وقد يكون فيها معامل <code>switch</code> كبير يلتقط أي فئة منتج ليمثّلها، لكننا سنحل هذا قريبًا.<br />
# أنشئ سلسلة من فئات creator الفرعية لكل نوع من المنتجات الموجودة في أسلوب المصنع، وتخطى أسلوب المصنع في الفئات الفرعية واستخرج الأجزاء المناسبة من شيفرة البناء (construction code) من الأسلوب الأساسي.<br />
# إن كانت أنواع المنتجات كثيرة وليس من المنطقي إنشاء فئات فرعية لهم جميعًا فيمكنك إعادة استخدام معامل التحكم (control parameter) من الفة الأساسية داخل الفئات الفرعية. فمثلًا، تخيل أن لديك الهرمية التالية من الفئات: فئة <code>Mail</code> الأساسية مع بضعة فئات فرعية: <code>AirMail</code> و <code>GroundMail</code>، فتكون فئات واجهة <code>Transport</code> هي <code>Plane</code> و <code>Truck</code> و <code>Train</code>. وبينما تستخدم <code>AirMail</code> كائنات من <code>Plane</code>، فإن <code>GroundMail</code> ستعمل مع كائنات <code>Truck</code> و <code>Train</code> كليهما. يمكنك إنشاء فئات فرعية جديدة (<code>TrainMail</code> مثلًا) لمعالجة كلا الحالتين، لكن هناك خيار آخر، يمكن لشيفرة العميل أن تمرر وسيطًا (argument) لأسلوب المصنع الخاص بفئة <code>GroundMail</code> لاختيار أي المنتجات التي يريد استقبالها.<br />
# إن أصبح أسلوب المصنع الأساسي فارغًا بعد كل الاستخراجات فيمكنك تحويله ليكون مجردًا (abstract)، أما إن تبقى شيء ما فيمكنك جعله السلوك الافتراضي للأسلوب.<br />
<br />
== المزايا والعيوب ==<br />
<br />
=== المزايا ===<br />
* تتجنب الربط الوثيق بين منتجات المنشئ (creator products) والمنتجات الحقيقية (Concrete Products).<br />
* مبدأ المسؤولية الواحدة. يمكنك نقل شيفرة إنشاء المنتج إلى مكان واحد في البرنامج، لتسهيل عملية دعم الشيفرة.<br />
* مبدأ المفتوح/المغلق. يمكنك إدخال أنواع جديدة من المنتجات داخل البرنامج دون تعطيل شيفرة العميل الحالية.<br />
<br />
=== العيوب ===<br />
قد تصبح الشيفرة أكثر تعقيدًا بما أنك تحتاج إلى إضافة فئات فرعية كثيرة لتُستخدم داخل النمط، وأفضل حالة ستكون لديك هي عندما تضيف النمط إلى هيكل قائم بالفعل من فئات المنشئ (creator classes).<br />
<br />
== العلاقات مع الأنماط الأخرى ==<br />
* تستخدم تصميمات كثيرة أسلوب المصنع بما أنه أقل تعقيدًا وأكثر قابلية للتخصيص باستخدام الفئات الفرعية، ثم تنتقل إلى أسلوب [[Design Patterns/abstract factory|المصنع المجرد]] أو [[Design Patterns/prototype|النموذج الأولي]] أو الباني (Builder)، حيث أنهم أكثر مرونة لكن أكثر تعقيدًا في المقابل.<br />
* تُبنى فئات المصنع المجرد عادة على سلسلة من أساليب المصنع، لكنك تستطيع استخدام النموذج الأولي لتشكيل الأساليب فوق تلك الفئات.<br />
* يمكنك استخدام أسلوب المصنع إلى جانب [[Design Patterns/iterator|المكرِّر]] لتسمح لمجموعات من الفئات الفرعية بإعادة أنواع مختلفة من المكرٍّرات تتوافق مع المجموعات.<br />
* لا يُبنى النموذج الأولي على الاكتساب (inheritance) لذلك ليس لديه عيوبه، لكن من الناحية الأخرى فإنه يتطلب عملية بدء معقدة من الكائن المستنسخ، أما أسلوب المصنع فمبني على الاكتساب لكنه لا يتطلب خطوة بدء.<br />
* أسلوب المصنع هو استثناء من أسلوب القالب (Template Method)، لكنه قد يخدم كمرحلة داخل أسلوب كبير من نوع القالب.<br />
<br />
== الاستخدام في لغة جافا ==<br />
'''المستوى: ★ ☆ ☆'''<br />
<br />
'''الانتشار: ★ ★ ★'''<br />
<br />
'''أمثلة الاستخدام''': يستخدم نمط أسلوب المصنع بشكل واسع في شيفرة جافا، فهو مفيد حين تريد أن تكون شيفرتك على درجة عالية من المرونة. ويوجد النمط في مكتبات جافا التالية:<br />
* [http://docs.oracle.com/javase/8/docs/api/java/util/Calendar.html#getInstance-- ()java.util.Calendar#getInstance]<br />
* [http://docs.oracle.com/javase/8/docs/api/java/util/ResourceBundle.html#getBundle-java.lang.String- ()java.util.ResourceBundle#getBundle]<br />
* [http://docs.oracle.com/javase/8/docs/api/java/text/NumberFormat.html#getInstance-- ()java.text.NumberFormat#getInstance]<br />
* [http://docs.oracle.com/javase/8/docs/api/java/nio/charset/Charset.html#forName-java.lang.String- ()java.nio.charset.Charset#forName]<br />
* [http://docs.oracle.com/javase/8/docs/api/java/net/URLStreamHandlerFactory.html (java.net.URLStreamHandlerFactory#createURLStreamHandler(String] تُعيد كائنات مفردة (Singleton) مختلفة بناءً على البروتوكول.<br />
* [https://docs.oracle.com/javase/8/docs/api/java/util/EnumSet.html#of(E) ()java.util.EnumSet#of]<br />
* [https://docs.oracle.com/javase/8/docs/api/javax/xml/bind/JAXBContext.html#createMarshaller-- ()javax.xml.bind.JAXBContext#createMarshaller] وأساليب أخرى مشابهة.<br />
يمكن ملاحظة أساليب المصنع من الأساليب الإنشائية التي تنشئ كائنات من فئات حقيقية (concrete classes) لكنها تعيدها ككائنات من نوع مجرد (abstract type) أو واجهة مجردة (abstract interface).<br />
<br />
=== مثال: إنتاج عناصر واجهة رسومية للمنصات المختلفة ===<br />
تلعب الأزرار دور المنتجات والصناديق الحوارية تمثل دور المنشئات (creators)، تتطلب الأنواع المختلفة من الصناديق الحوارية أنواعها الخاصة من العناصر، هذا هو السبب الذي ننشئ فئة فرعية لكل نوع من أنواع الصناديق الحوارية ونتخطى أساليب المصنع الخاصة بها.<br />
<br />
والآن، سيمثّل كل نوع من أنواع الصناديق الحوارية فئة زر مناسبة، ويعمل الصندوق الأساسي مع المنتجات مستخدمًا واجهتهم المشتركة، لهذا تبقى شيفرتها عاملة بعد كل تلك التغييرات.<br />
<br />
==== الأزرار ====<br />
<br />
===== buttons/Button.java: واجهة مشتركة للمنتج =====<br />
<syntaxhighlight lang="java"><br />
package refactoring_guru.factory_method.example.buttons;<br />
<br />
/**<br />
* واجهة مشتركة لكل الأزرار.<br />
*/<br />
public interface Button {<br />
void render();<br />
void onClick();<br />
}<br />
</syntaxhighlight><br />
<br />
===== buttons/HtmlButton.java: منتج حقيقي =====<br />
<syntaxhighlight lang="java"><br />
package refactoring_guru.factory_method.example.buttons;<br />
<br />
/**<br />
* HTML استخدام الزر في.<br />
*/<br />
public class HtmlButton implements Button {<br />
<br />
public void render() {<br />
System.out.println("<button>Test Button</button>");<br />
onClick();<br />
}<br />
<br />
public void onClick() {<br />
System.out.println("Click! Button says - 'Hello World!'");<br />
}<br />
}<br />
</syntaxhighlight><br />
<br />
===== buttons/WindowsButton.java: منتج حقيقي آخر =====<br />
<syntaxhighlight lang="java"><br />
package refactoring_guru.factory_method.example.buttons;<br />
<br />
import javax.swing.*;<br />
import java.awt.*;<br />
import java.awt.event.ActionEvent;<br />
import java.awt.event.ActionListener;<br />
<br />
/**<br />
* استخدام للزر في ويندوز.<br />
*/<br />
public class WindowsButton implements Button {<br />
JPanel panel = new JPanel();<br />
JFrame frame = new JFrame();<br />
JButton button;<br />
<br />
public void render() {<br />
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);<br />
JLabel label = new JLabel("Hello World!");<br />
label.setOpaque(true);<br />
label.setBackground(new Color(235, 233, 126));<br />
label.setFont(new Font("Dialog", Font.BOLD, 44));<br />
label.setHorizontalAlignment(SwingConstants.CENTER);<br />
panel.setLayout(new FlowLayout(FlowLayout.CENTER));<br />
frame.getContentPane().add(panel);<br />
panel.add(label);<br />
onClick();<br />
panel.add(button);<br />
<br />
frame.setSize(320, 200);<br />
frame.setVisible(true);<br />
onClick();<br />
}<br />
<br />
public void onClick() {<br />
button = new JButton("Exit");<br />
button.addActionListener(new ActionListener() {<br />
public void actionPerformed(ActionEvent e) {<br />
frame.setVisible(false);<br />
System.exit(0);<br />
}<br />
});<br />
}<br />
}<br />
</syntaxhighlight><br />
<br />
==== المصنع ====<br />
<br />
===== factory/Dialog.java: منشئ الأساس (Base Creator) =====<br />
<syntaxhighlight lang="java"><br />
package refactoring_guru.factory_method.example.factory;<br />
<br />
import refactoring_guru.factory_method.example.buttons.Button;<br />
<br />
/**<br />
* فئة المصنع الأساسية، لاحظ أن المصنع هنا مجرد دور للفئة، ينبغي أن يكون له منطق عمل يحتاج منتجات مختلفة<br />
* لكي يُنشأ.<br />
*/<br />
public abstract class Dialog {<br />
<br />
public void renderWindow() {<br />
// ... other code ...<br />
<br />
Button okButton = createButton();<br />
okButton.render();<br />
}<br />
<br />
/**<br />
* ستتخطى الفئات الفرعية هذا الأسلوب من أجل إنشاء كائنات أزرار محددة<br />
*/<br />
public abstract Button createButton();<br />
}<br />
</syntaxhighlight><br />
<br />
===== factory/HtmlDialog.java: منشئ حقيقي =====<br />
<syntaxhighlight lang="java"><br />
package refactoring_guru.factory_method.example.factory;<br />
<br />
import refactoring_guru.factory_method.example.buttons.Button;<br />
import refactoring_guru.factory_method.example.buttons.HtmlButton;<br />
<br />
/**<br />
* HTML الحواري أزرار HTML سينتِج صندوق.<br />
*/<br />
public class HtmlDialog extends Dialog {<br />
<br />
@Override<br />
public Button createButton() {<br />
return new HtmlButton();<br />
}<br />
}<br />
</syntaxhighlight><br />
<br />
===== factory/WindowsDialog.java: منشئ حقيقي آخر =====<br />
<syntaxhighlight lang="java"><br />
package refactoring_guru.factory_method.example.factory;<br />
<br />
import refactoring_guru.factory_method.example.buttons.Button;<br />
import refactoring_guru.factory_method.example.buttons.WindowsButton;<br />
<br />
/**<br />
* صندوق ويندوز الحواري سيُنتِج أزرار ويندوز.<br />
*/<br />
public class WindowsDialog extends Dialog {<br />
<br />
@Override<br />
public Button createButton() {<br />
return new WindowsButton();<br />
}<br />
}<br />
</syntaxhighlight><br />
<br />
===== Demo.java: شيفرة العميل =====<br />
<syntaxhighlight lang="java"><br />
package refactoring_guru.factory_method.example;<br />
<br />
import refactoring_guru.factory_method.example.factory.Dialog;<br />
import refactoring_guru.factory_method.example.factory.HtmlDialog;<br />
import refactoring_guru.factory_method.example.factory.WindowsDialog;<br />
<br />
/**<br />
* فئة عينة العرض، كل شيء يُجمَّع هنا.<br />
*/<br />
public class Demo {<br />
private static Dialog dialog;<br />
<br />
public static void main(String[] args) {<br />
configure();<br />
runBusinessLogic();<br />
}<br />
<br />
/**<br />
* يُختار المصنع الحقيقي عادة بناءً على الإعدادات أو خيارات البيئة.<br />
*/<br />
static void configure() {<br />
if (System.getProperty("os.name").equals("Windows 10")) {<br />
dialog = new WindowsDialog();<br />
} else {<br />
dialog = new HtmlDialog();<br />
}<br />
}<br />
<br />
/**<br />
* يجب أن تعمل شيفرة العميل مع المصانع والمنتجات عبر واجهات نظرية، <br />
* فبهذه الطريقة لا يهم أي مصنع تعمل معه ولا نوع المنتج الذي تعيده.<br />
*/<br />
static void runBusinessLogic() {<br />
dialog.renderWindow();<br />
}<br />
}<br />
</syntaxhighlight><br />
<br />
===== OutputDemo.txt: نتائج التنفيذ (صندوق HTML) =====<br />
<syntaxhighlight lang="html"><br />
<button>Test Button</button><br />
Click! Button says - 'Hello World!'<br />
</syntaxhighlight><br />
<br />
===== OutputDemo.png: نتائج التنفيذ (صندوق حواري في ويندوز) =====<br />
[[ملف:dpfm.OutputDemo.png]]<br />
== الاستخدام في لغة #C ==<br />
'''المستوى: ★ ☆ ☆'''<br />
<br />
'''الانتشار: ★ ★ ★'''<br />
<br />
'''أمثلة الاستخدام''': يستخدم أسلوب المصنع بكثرة في شيفرة #C، وهو مفيد في كتابة شيفرة عالية المرونة.<br />
<br />
كما تقدم في شرح الاستخدام في لغة جافا، يمكن ملاحظة أساليب المصنع من الأساليب الإنشائية التي تنشئ كائنات من فئات حقيقية (concrete classes) لكنها تعيدها ككائنات من نوع مجرد (abstract type) أو واجهة مجردة (abstract interface).<br />
<br />
=== مثال: بُنية النمط ===<br />
يوضح هذاالمثال بنية نمط أسلوب المصنع، ويركز على إجابة الأسئلة التالية:<br />
* ما الفئات التي يتكون منها؟<br />
* ما الأدوار التي تلعبها هذه الفئات؟<br />
* كيف ترتبط عناصر النمط ببعضها؟<br />
<br />
==== Program.cs: مثال على البنية ====<br />
<syntaxhighlight lang="c#"><br />
using System;<br />
<br />
namespace RefactoringGuru.DesignPatterns.FactoryMethod.Structural<br />
{<br />
abstract class Creator<br />
{<br />
public abstract IProduct FactoryMethod();<br />
<br />
public string SomeOperation()<br />
{<br />
var product = FactoryMethod();<br />
<br />
var result = "Creator: The same creator's code has just worked with " + product.Operation();<br />
<br />
return result;<br />
}<br />
}<br />
<br />
class ConcreteCreator1 : Creator<br />
{<br />
public override IProduct FactoryMethod()<br />
{<br />
return new ConcreteProduct1();<br />
}<br />
}<br />
<br />
class ConcreteCreator2 : Creator<br />
{<br />
public override IProduct FactoryMethod()<br />
{<br />
return new ConcreteProduct2();<br />
}<br />
}<br />
<br />
interface IProduct<br />
{<br />
string Operation();<br />
}<br />
<br />
class ConcreteProduct1 : IProduct<br />
{<br />
public string Operation()<br />
{<br />
return "{Result of ConcreteProduct1}";<br />
}<br />
}<br />
<br />
class ConcreteProduct2 : IProduct<br />
{<br />
public string Operation()<br />
{<br />
return "{Result of ConcreteProduct2}";<br />
}<br />
}<br />
<br />
class Client<br />
{<br />
public void Main()<br />
{<br />
Console.WriteLine("App: Launched with the ConcreteCreator1.");<br />
ClientMethod(new ConcreteCreator1());<br />
<br />
Console.WriteLine("");<br />
<br />
Console.WriteLine("App: Launched with the ConcreteCreator2.");<br />
ClientMethod(new ConcreteCreator2());<br />
}<br />
<br />
public void ClientMethod(Creator creator)<br />
{<br />
// ...<br />
Console.WriteLine("Client: I'm not aware of the creator's class, but it still works.\n"<br />
+ creator.SomeOperation());<br />
// ...<br />
}<br />
}<br />
<br />
class Program<br />
{<br />
static void Main(string[] args)<br />
{<br />
new Client().Main();<br />
}<br />
}<br />
}<br />
</syntaxhighlight><br />
<br />
==== Output.txt: المخرجات ====<br />
<syntaxhighlight lang="text"><br />
App: Launched with the ConcreteCreator1.<br />
Client: I'm not aware of the creator's class, but it still works.<br />
Creator: The same creator's code has just worked with {Result of ConcreteProduct1}<br />
<br />
App: Launched with the ConcreteCreator2.<br />
Client: I'm not aware of the creator's class, but it still works.<br />
Creator: The same creator's code has just worked with {Result of ConcreteProduct2}<br />
</syntaxhighlight><br />
<br />
== الاستخدام في لغة PHP ==<br />
'''المستوى: ★ ☆ ☆'''<br />
<br />
'''الانتشار: ★ ★ ★'''<br />
<br />
'''أمثلة الاستخدام''': يستخدم نمط أسلوب المصنع بكثرة في شيفرة PHP، وهو مفيد في كتابة شيفرة عالية المرونة.<br />
<br />
=== مثال: بُنية النمط ===<br />
يوضح هذاالمثال بنية نمط أسلوب المصنع، ويركز على إجابة الأسئلة التالية:<br />
* ما الفئات التي يتكون منها؟<br />
* ما الأدوار التي تلعبها هذه الفئات؟<br />
* كيف ترتبط عناصر النمط ببعضها؟<br />
بعد تعلم بنية النمط سيكون من السهل استيعاب المثال التالي بناءً على مثال لحالة حقيقية في PHP.<br />
<br />
==== FactoryMethodStructural.php: مثال على البنية ====<br />
<syntaxhighlight lang="php"><br />
<?php<br />
<br />
namespace RefactoringGuru\FactoryMethod\Structural;<br />
<br />
/**<br />
* تصرح فئة المنشئ عن أسلوب المصنع الذي يجب أن يعيد كائنًا من فئة أحد المنتجات<br />
* وتوضح الفئة الفرعية للمنشئ في الغالب استخدامات هذا الأسلوب.<br />
*/<br />
abstract class Creator<br />
{<br />
/**<br />
* لاحظ أن المنشئ قد يوضح بعض الاستخدامات الافتراضية لأسلوب المصنع.<br />
*/<br />
public abstract function factoryMethod(): Product;<br />
<br />
/**<br />
* لاحظ كذلك أن وظيفة المنشئ الأساسية ليست إنشاء المنتجات، رغم مايوحي به الاسم،<br />
* لكن له عادة منطق عمل يعتمد على كائنات المنتج المعادة بواسطة أسلوب المصنع.<br />
* وتستطيع الفئات الفرعية تغيير منطق العمل ذاك بشكل غير مباشر عبر تخطي أسلوب<br />
* المصنع وإعادة نوع مختلف من المنتجات منه.<br />
*/<br />
public function someOperation(): string<br />
{<br />
// Call the factory method to create a Product object.<br />
$product = $this->factoryMethod();<br />
// Now, use the product.<br />
$result = "Creator: The same creator's code has just worked with ".<br />
$product->operation();<br />
<br />
return $result;<br />
}<br />
}<br />
<br />
/**<br />
* تتخطى المنشئات الحقيقية أسلوب المصنع من أجل تغيير نوع المنتج.<br />
*/<br />
class ConcreteCreator1 extends Creator<br />
{<br />
/**<br />
* لاحظ أن توقيع الأسلوب لا يزال يستخدم نوع المنتج النظري برغم أن المنتج الحقيقي مُعاد فعلًا من الأسلوب<br />
* بهذه الطريقة يظل المنشئ مستقلًا من فئات المنتج الحقيقي.<br />
*/<br />
public function factoryMethod(): Product<br />
{<br />
return new ConcreteProduct1();<br />
}<br />
}<br />
<br />
class ConcreteCreator2 extends Creator<br />
{<br />
public function factoryMethod(): Product<br />
{<br />
return new ConcreteProduct2();<br />
}<br />
}<br />
<br />
/**<br />
* تصرح واجهة المنتج عن العمليات التي يجب أن تستخدمها المنتجات الحقيقية.<br />
*/<br />
interface Product<br />
{<br />
public function operation(): string;<br />
}<br />
<br />
/**<br />
* توضح المنتجات الحقيقية الاستخدامات المختلفة لواجهة المنتج.<br />
*/<br />
class ConcreteProduct1 implements Product<br />
{<br />
public function operation(): string<br />
{<br />
return "{Result of the ConcreteProduct1}";<br />
}<br />
}<br />
<br />
class ConcreteProduct2 implements Product<br />
{<br />
public function operation(): string<br />
{<br />
return "{Result of the ConcreteProduct2}";<br />
}<br />
}<br />
<br />
/**<br />
* تعمل شيفرة العميل مع نسخة من منشئ حقيقي ولو من خلال واجهته الأساسية، فطالما أن العميل يظل<br />
* عاملًا مع المنشئ من خلال واجهة أساسية فيمكنك تمرير أي فئة منشئ فرعية إليه<br />
*/<br />
function clientCode(Creator $creator)<br />
{<br />
// ...<br />
print("Client: I'm not aware of the creator's class, but it still works.\n"<br />
.$creator->someOperation());<br />
// ...<br />
}<br />
<br />
/**<br />
* يختار التطبيق نوع منشئ بناءً على الإعدادات أو البيئة.<br />
*/<br />
print("App: Launched with the ConcreteCreator1.\n");<br />
clientCode(new ConcreteCreator1());<br />
print("\n\n");<br />
<br />
print("App: Launched with the ConcreteCreator2.\n");<br />
clientCode(new ConcreteCreator2());<br />
</syntaxhighlight><br />
<br />
==== Output.txt: المخرجات ====<br />
<syntaxhighlight lang="text"><br />
App: Launched with the ConcreteCreator1.<br />
Client: I'm not aware of the creator's class, but it still works.<br />
Creator: The same creator's code has just worked with {Result of the ConcreteProduct1}<br />
<br />
App: Launched with the ConcreteCreator2.<br />
Client: I'm not aware of the creator's class, but it still works.<br />
Creator: The same creator's code has just worked with {Result of the ConcreteProduct2}<br />
</syntaxhighlight><br />
<br />
=== مثال: حالة حقيقية ===<br />
في هذا المثال، يوضح نمط أسلوب المصنع واجهة لإنشاء موصلات شبكة اجتماعية يمكن استخدامها لتشجيل الدخول إلى الشبكة وإنشاء منشورات ومن ثم إمكانية تنفيذ نشاطات أخرى، وكل ذلك دون دمج شيفرة العميل مع فئات محددة للشبكة الاجتماعية.<br />
<br />
==== FactoryMethodRealWorld.php: مثال لحالة حقيقية ====<br />
<syntaxhighlight lang="php"><br />
<?php<br />
<br />
namespace RefactoringGuru\FactoryMethod\RealWorld;<br />
<br />
/**<br />
* نمط التصميم: أسلوب المصنع<br />
*<br />
* الهدف: تحديد واجهة لإنشاء الكائنات، مع السماح للفئات الفرعية باختيار الفئة التي تمثلها.<br />
* يسمح أسلوب المصنع كذلك للفئة أن ترجئ التمثيل إلى فئات فرعية.<br />
* <br />
* مثال: يوفر نمط أسلوب المصنع هنا واجهة لإنشاء موصلات شبكة اجتماعية يمكن استخدامها لتسجيل الدخول إلى<br />
* الشبكة وإنشاء منشورات ومن ثَمَّ تنفيذ نشاطات أخرى، دون ربط شيفرة العميل بأي فئات محددة للشبكة.<br />
*/<br />
<br />
/**<br />
* (constructor) يصرِّح المنشئ عن أسلوب المصنع الذي يمكن استخدامه كبديل لاستدعاءات المنشئ<br />
* المباشرة للمنتجات.<br />
*<br />
* - قبل: $p = new FacebookConnector()<br />
* - بعد: $p = $this->getSocialNetwork()<br />
*<br />
* الفرعية SocialNetworkPoster يسمح هذا بتغيير نوع المنتج المُنشأ بفئات<br />
*/<br />
abstract class SocialNetworkPoster<br />
{<br />
/**<br />
* أسلوب المصنع الفعلي، لاحظ أنه يعيدالموصل النظري.<br />
* يسمح هذا للفئات الفرعية أن تعيد أي موصلات حقيقية دون خرق ميثاق الفئة الرئيسية.<br />
*/<br />
public abstract function getSocialNetwork(): SocialNetworkConnector;<br />
<br />
/**<br />
* حين يُستخدم أسلوب المصنع داخل منطق عمل لمنشئ، فإن الفئات الفرعية قد تُغيِّر المنطق بشكل غير مباشر<br />
* من خلال إعادة أنواع موصلات مختلفة من أسلوب المصنع.<br />
*/<br />
public function post($content)<br />
{<br />
// Call the factory method to create a Product object...<br />
$network = $this->getSocialNetwork();<br />
// ...then use it as you will.<br />
//<br />
// ...ثم استخدمها كما تشاء.<br />
$network->logIn();<br />
$network->createPost($content);<br />
$network->logout();<br />
}<br />
}<br />
<br />
<br />
/**<br />
* 'post' هذا المنتج الحقيقي يدعم فيس بوك، تذكر أن هذه الفئة تكتسب أسلوب<br />
* من الفئة الأم. المنشئات الحقيقية هي الفئات التي يستخدمها العميل فعليًا.<br />
*/<br />
class FacebookPoster extends SocialNetworkPoster<br />
{<br />
private $login, $password;<br />
<br />
public function __construct($login, $password)<br />
{<br />
$this->login = $login;<br />
$this->password = $password;<br />
}<br />
<br />
public function getSocialNetwork(): SocialNetworkConnector<br />
{<br />
return new FacebookConnector($this->login, $this->password);<br />
}<br />
}<br />
<br />
/**<br />
* هذا المنتج الحقيقي يدعم شبكة لينكدإن.<br />
*/<br />
class LinkedInPoster extends SocialNetworkPoster<br />
{<br />
private $email, $password;<br />
<br />
public function __construct($email, $password)<br />
{<br />
$this->email = $email;<br />
$this->password = $password;<br />
}<br />
<br />
public function getSocialNetwork(): SocialNetworkConnector<br />
{<br />
return new LinkedInConnector($this->email, $this->password);<br />
}<br />
}<br />
<br />
/**<br />
* تصرح واجهة المنتج عن سلوك الأنواع المختلفة من المنتجات.<br />
*/<br />
interface SocialNetworkConnector<br />
{<br />
public function logIn();<br />
<br />
public function logOut();<br />
<br />
public function createPost($content);<br />
}<br />
<br />
/**<br />
* فيس بوك API هذا المنتج الحقيقي يستخدم.<br />
*/<br />
class FacebookConnector implements SocialNetworkConnector<br />
{<br />
private $login, $password;<br />
<br />
public function __construct($login, $password)<br />
{<br />
$this->login = $login;<br />
$this->password = $password;<br />
}<br />
<br />
public function logIn()<br />
{<br />
print("Send HTTP API request to log in user $this->login with " .<br />
"password $this->password\n");<br />
}<br />
<br />
public function logOut()<br />
{<br />
print("Send HTTP API request to log out user $this->login\n");<br />
}<br />
<br />
public function createPost($content)<br />
{<br />
print("Send HTTP API requests to create a post in Facebook timeline.\n");<br />
}<br />
}<br />
<br />
/**<br />
* لينكدإن API هذا المنتج الحقيقي يستخدم.<br />
*/<br />
class LinkedInConnector implements SocialNetworkConnector<br />
{<br />
private $email, $password;<br />
<br />
public function __construct($email, $password)<br />
{<br />
$this->email = $email;<br />
$this->password = $password;<br />
}<br />
<br />
public function logIn()<br />
{<br />
print("Send HTTP API request to log in user $this->email with " .<br />
"password $this->password\n");<br />
}<br />
<br />
public function logOut()<br />
{<br />
print("Send HTTP API request to log out user $this->email\n");<br />
}<br />
<br />
public function createPost($content)<br />
{<br />
print("Send HTTP API requests to create a post in LinkedIn timeline.\n");<br />
}<br />
}<br />
<br />
/**<br />
* SocialNetworkPoster تستطيع شيفرة العميل أن تعمل مع أي فئة فرعية لـ<br />
* بما أنها لا تعتمد على فئات حقيقية.<br />
*/<br />
function clientCode(SocialNetworkPoster $creator)<br />
{<br />
// ...<br />
$creator->post("Hello world!");<br />
$creator->post("I had a large hamburger this morning!");<br />
// ...<br />
}<br />
<br />
/**<br />
* أثناء مرحلة البدء، يمكن للتطبيق اختيار الشبكة التي يريد العمل معها، وينشئ كائنًا من الفئة الفرعية<br />
* المناسبة، ويمرره إلى شيفرة العميل.<br />
*/<br />
print("Testing ConcreteCreator1:\n");<br />
clientCode(new FacebookPoster("john_smith", "******"));<br />
print("\n\n");<br />
<br />
print("Testing ConcreteCreator2:\n");<br />
clientCode(new LinkedInPoster("john_smith@example.com", "******"));<br />
</syntaxhighlight><br />
<br />
==== Output.txt: المخرجات ====<br />
<syntaxhighlight lang="text"><br />
Testing ConcreteCreator1:<br />
Send HTTP API request to log in user john_smith with password ******<br />
Send HTTP API requests to create a post in Facebook timeline.<br />
Send HTTP API request to log out user john_smith<br />
Send HTTP API request to log in user john_smith with password ******<br />
Send HTTP API requests to create a post in Facebook timeline.<br />
Send HTTP API request to log out user john_smith<br />
<br />
<br />
Testing ConcreteCreator2:<br />
Send HTTP API request to log in user john_smith@example.com with password ******<br />
Send HTTP API requests to create a post in LinkedIn timeline.<br />
Send HTTP API request to log out user john_smith@example.com<br />
Send HTTP API request to log in user john_smith@example.com with password ******<br />
Send HTTP API requests to create a post in LinkedIn timeline.<br />
Send HTTP API request to log out user john_smith@example.com<br />
</syntaxhighlight><br />
== الاستخدام في لغة بايثون ==<br />
'''المستوى: ★ ☆ ☆'''<br />
<br />
'''الانتشار: ★ ★ ★'''<br />
<br />
'''أمثلة الاستخدام''': يستخدم أسلوب المصنع بكثرة في شيفرة بايثون، وهو مفيد في كتابة شيفرة عالية المرونة.<br />
<br />
يمكن ملاحظة أساليب المصنع من الأساليب الإنشائية التي تنشئ كائنات من فئات حقيقية (concrete classes) لكنها تعيدها ككائنات من نوع مجرد (abstract type) أو واجهة مجردة (abstract interface).<br />
<br />
=== مثال: بُنية النمط ===<br />
يوضح هذاالمثال بنية نمط أسلوب المصنع، ويركز على إجابة الأسئلة التالية:<br />
* ما الفئات التي يتكون منها؟<br />
* ما الأدوار التي تلعبها هذه الفئات؟<br />
* كيف ترتبط عناصر النمط ببعضها؟<br />
<br />
==== main.py: مثال تصوري ====<br />
<syntaxhighlight lang="python"><br />
from __future__ import annotations<br />
from abc import ABC, abstractmethod<br />
<br />
<br />
class Creator(ABC):<br />
"""<br />
تصرح فئة المنشئ عن أسلوب المصنع الذي يجب أن يعيد كائنًا من فئة أحد المنتجات<br />
وتوضح الفئة الفرعية للمنشئ في الغالب استخدامات هذا الأسلوب.<br />
"""<br />
<br />
@abstractmethod<br />
def factory_method(self):<br />
"""<br />
لاحظ أن المنشئ قد يوضح بعض الاستخدامات الافتراضية لأسلوب المصنع.<br />
"""<br />
pass<br />
<br />
def some_operation(self) -> str:<br />
"""<br />
لاحظ كذلك أن وظيفة المنشئ الأساسية ليست إنشاء المنتجات، رغم مايوحي به الاسم،<br />
لكن له عادة منطق عمل يعتمد على كائنات المنتج المعادة<br />
بواسطة أسلوب المصنع.<br />
وتستطيع الفئات الفرعية تغيير منطق العمل ذاك بشكل غير مباشر<br />
عبر تخطي أسلوب المصنع وإعادة نوع مختلف من المنتجات معه.<br />
"""<br />
<br />
# استدع أسلوب المصنع لإنشاء كائن منتج.<br />
product = self.factory_method()<br />
<br />
# والآن، استخدم المنتج.<br />
result = f"Creator: The same creator's code has just worked with {product.operation()}"<br />
<br />
return result<br />
<br />
<br />
"""<br />
تتخطى المنشئات الحقيقية أسلوب المصنع من أجل تغيير نوع المنتج.<br />
"""<br />
<br />
<br />
class ConcreteCreator1(Creator):<br />
"""<br />
لاحظ أن توقيع الأسلوب لا يزال يستخدم نوع المنتج النظري برغم <br />
أن المنتج الحقيقي مُعاد فعلًا من الأسلوب، وبهذه الطريقة يظل <br />
المنشئ مستقلًا من فئات المنتج الحقيقي.<br />
"""<br />
<br />
def factory_method(self) -> ConcreteProduct1:<br />
return ConcreteProduct1()<br />
<br />
<br />
class ConcreteCreator2(Creator):<br />
def factory_method(self) -> ConcreteProduct2:<br />
return ConcreteProduct2()<br />
<br />
<br />
class Product(ABC):<br />
"""<br />
تصرح واجهة المنتج عن العمليات التي يجب أن تستخدمها المنتجات الحقيقية.<br />
"""<br />
<br />
@abstractmethod<br />
def operation(self) -> str:<br />
pass<br />
<br />
<br />
"""<br />
توضح المنتجات الحقيقية الاستخدامات المختلفة لواجهة المنتج.<br />
"""<br />
<br />
<br />
class ConcreteProduct1(Product):<br />
def operation(self) -> str:<br />
return "{Result of the ConcreteProduct1}"<br />
<br />
<br />
class ConcreteProduct2(Product):<br />
def operation(self) -> str:<br />
return "{Result of the ConcreteProduct2}"<br />
<br />
<br />
def client_code(creator: Creator) -> None:<br />
"""<br />
تعمل شيفرة العميل مع نسخة من منشئ حقيقي ولو من خلال واجهته<br />
الأساسية، فطالما أن العميل يظل عاملًا مع المنشئ من خلال<br />
واجهة أساسية فيمكنك تمرير أي فئة منشئ فرعية إليه.<br />
"""<br />
<br />
print(f"Client: I'm not aware of the creator's class, but it still works.\n"<br />
f"{creator.some_operation()}", end="")<br />
<br />
<br />
if __name__ == "__main__":<br />
print("App: Launched with the ConcreteCreator1.")<br />
client_code(ConcreteCreator1())<br />
print("\n")<br />
<br />
print("App: Launched with the ConcreteCreator2.")<br />
client_code(ConcreteCreator2())<br />
</syntaxhighlight><br />
<br />
==== Output.txt: نتائج التنفيذ ====<br />
<syntaxhighlight lang="text"><br />
App: Launched with the ConcreteCreator1.<br />
Client: I'm not aware of the creator's class, but it still works.<br />
Creator: The same creator's code has just worked with {Result of the ConcreteProduct1}<br />
<br />
App: Launched with the ConcreteCreator2.<br />
Client: I'm not aware of the creator's class, but it still works.<br />
Creator: The same creator's code has just worked with {Result of the ConcreteProduct2}<br />
</syntaxhighlight><br />
<br />
== الاستخدام في لغة روبي ==<br />
'''المستوى: ★ ☆ ☆'''<br />
<br />
'''الانتشار: ★ ★ ★'''<br />
<br />
'''أمثلة الاستخدام''': يستخدم أسلوب المصنع بكثرة في شيفرة روبي، وهو مفيد في كتابة شيفرة عالية المرونة.<br />
<br />
يمكن ملاحظة أساليب المصنع من الأساليب الإنشائية التي تنشئ كائنات من فئات حقيقية (concrete classes) لكنها تعيدها ككائنات من نوع مجرد (abstract type) أو واجهة مجردة (abstract interface).<br />
<br />
=== مثال: بُنية النمط ===<br />
يوضح هذاالمثال بنية نمط أسلوب المصنع، ويركز على إجابة الأسئلة التالية:<br />
* ما الفئات التي يتكون منها؟<br />
* ما الأدوار التي تلعبها هذه الفئات؟<br />
* كيف ترتبط عناصر النمط ببعضها؟<br />
<br />
==== main.rb: مثال تصوري ====<br />
<syntaxhighlight lang="ruby"><br />
# تصرح فئة المنشئ عن أسلوب المصنع الذي يجب أن يعيد كائنًا من فئة أحد المنتجات<br />
# وتوضح الفئة الفرعية للمنشئ في الغالب استخدامات هذا الأسلوب.<br />
class Creator<br />
# لاحظ أن المنشئ قد يوضح بعض الاستخدامات الافتراضية لأسلوب المصنع.<br />
def factory_method<br />
raise NotImplementedError, "#{self.class} has not implemented method '#{__method__}'"<br />
end<br />
<br />
# لاحظ كذلك أن وظيفة المنشئ الأساسية ليست إنشاء المنتجات، رغم مايوحي به الاسم،<br />
# لكن له عادة منطق عمل يعتمد على كائنات المنتج المعادة<br />
# بواسطة أسلوب المصنع.<br />
# وتستطيع الفئات الفرعية تغيير منطق العمل ذاك بشكل غير مباشر<br />
# عبر تخطي أسلوب المصنع وإعادة نوع مختلف من المنتجات معه.<br />
<br />
def some_operation<br />
# استدع أسلوب المصنع لإنشاء كائن منتج.<br />
product = factory_method<br />
<br />
# والآن، استخدم المنتج.<br />
result = "Creator: The same creator's code has just worked with #{product.operation}"<br />
<br />
result<br />
end<br />
end<br />
<br />
# تتخطى المنشئات الحقيقية أسلوب المصنع من أجل تغيير نوع المنتج.<br />
class ConcreteCreator1 < Creator<br />
# لاحظ أن توقيع الأسلوب لا يزال يستخدم نوع المنتج النظري برغم <br />
# أن المنتج الحقيقي مُعاد فعلًا من الأسلوب، وبهذه الطريقة يظل <br />
# المنشئ مستقلًا من فئات المنتج الحقيقي.<br />
<br />
def factory_method<br />
ConcreteProduct1.new<br />
end<br />
end<br />
<br />
class ConcreteCreator2 < Creator<br />
# @return [ConcreteProduct2]<br />
def factory_method<br />
ConcreteProduct2.new<br />
end<br />
end<br />
<br />
# تصرح واجهة المنتج عن العمليات التي يجب أن تستخدمها المنتجات الحقيقية.<br />
class Product<br />
# return [String]<br />
def operation<br />
raise NotImplementedError, "#{self.class} has not implemented method '#{__method__}'"<br />
end<br />
end<br />
<br />
# توضح المنتجات الحقيقية الاستخدامات المختلفة لواجهة المنتج.<br />
class ConcreteProduct1 < Product<br />
# @return [String]<br />
def operation<br />
'{Result of the ConcreteProduct1}'<br />
end<br />
end<br />
<br />
class ConcreteProduct2 < Product<br />
# @return [String]<br />
def operation<br />
'{Result of the ConcreteProduct2}'<br />
end<br />
end<br />
<br />
# تعمل شيفرة العميل مع نسخة من منشئ حقيقي ولو من خلال واجهته<br />
# الأساسية، فطالما أن العميل يظل عاملًا مع المنشئ من خلال<br />
# واجهة أساسية فيمكنك تمرير أي فئة منشئ فرعية إليه.<br />
<br />
def client_code(creator)<br />
print "Client: I'm not aware of the creator's class, but it still works.\n"\<br />
"#{creator.some_operation}"<br />
end<br />
<br />
puts 'App: Launched with the ConcreteCreator1.'<br />
client_code(ConcreteCreator1.new)<br />
puts "\n\n"<br />
<br />
puts 'App: Launched with the ConcreteCreator2.'<br />
client_code(ConcreteCreator2.new)<br />
</syntaxhighlight><br />
<br />
==== output.txt: نتائج التنفيذ ====<br />
<syntaxhighlight lang="text"><br />
App: Launched with the ConcreteCreator1.<br />
Client: I'm not aware of the creator's class, but it still works.<br />
Creator: The same creator's code has just worked with {Result of the ConcreteProduct1}<br />
<br />
App: Launched with the ConcreteCreator2.<br />
Client: I'm not aware of the creator's class, but it still works.<br />
Creator: The same creator's code has just worked with {Result of the ConcreteProduct2}<br />
</syntaxhighlight><br />
<br />
== الاستخدام في لغة Swift ==<br />
'''المستوى: ★ ☆ ☆'''<br />
<br />
'''الانتشار: ★ ★ ★'''<br />
<br />
'''أمثلة الاستخدام''': يستخدم أسلوب المصنع بكثرة في شيفرة Swift، وهو مفيد في كتابة شيفرة عالية المرونة.<br />
<br />
يمكن ملاحظة أساليب المصنع من الأساليب الإنشائية التي تنشئ كائنات من فئات حقيقية (concrete classes) لكنها تعيدها ككائنات من نوع مجرد (abstract type) أو واجهة مجردة (abstract interface).<br />
<br />
=== مثال: بُنية النمط ===<br />
يوضح هذاالمثال بنية نمط أسلوب المصنع، ويركز على إجابة الأسئلة التالية:<br />
* ما الفئات التي يتكون منها؟<br />
* ما الأدوار التي تلعبها هذه الفئات؟<br />
* كيف ترتبط عناصر النمط ببعضها؟<br />
بعد تعلم بنية النمط سيكون من السهل عليك استيعاب المثال التالي المبني على حالة واقعية في لغة Swift.<br />
<br />
==== Example.swift: مثال تصوري ====<br />
<syntaxhighlight lang="swift"><br />
import XCTest<br />
<br />
/// تصرح فئة المنشئ عن أسلوب المصنع الذي يجب أن يعيد كائنًا من فئة أحد المنتجات<br />
/// وتوضح الفئة الفرعية للمنشئ في الغالب استخدامات هذا الأسلوب.<br />
protocol Creator {<br />
<br />
/// لاحظ أن المنشئ قد يوضح بعض الاستخدامات الافتراضية لأسلوب المصنع.<br />
func factoryMethod() -> Product<br />
<br />
/// لاحظ كذلك أن وظيفة المنشئ الأساسية ليست إنشاء المنتجات، رغم مايوحي به الاسم،<br />
/// لكن له عادة منطق عمل يعتمد على كائنات المنتج المعادة<br />
/// بواسطة أسلوب المصنع.<br />
/// وتستطيع الفئات الفرعية تغيير منطق العمل ذاك بشكل غير مباشر<br />
عبر تخطي أسلوب المصنع وإعادة نوع مختلف من المنتجات معه.<br />
func someOperation() -> String<br />
}<br />
<br />
/// تستخدم هذه الإضافة السلوك الافتراضي للمنشئ، يمكن تجاوز<br />
/// هذا الأسلوب في الفئات الفرعية.<br />
extension Creator {<br />
<br />
func someOperation() -> String {<br />
// استدع أسلوب المصنع لإنشاء كائن منتج.<br />
let product = factoryMethod()<br />
<br />
// والآن، استخدم المنتج.<br />
return "Creator: The same creator's code has just worked with " + product.operation()<br />
}<br />
}<br />
<br />
/// تتخطى المنشئِات الحقيقية أسلوب المصنع من أجل تغيير نوع المنتج.<br />
class ConcreteCreator1: Creator {<br />
<br />
/// لاحظ أن توقيع الأسلوب لا يزال يستخدم نوع المنتج النظري برغم <br />
/// أن المنتج الحقيقي مُعاد فعلًا من الأسلوب، وبهذه الطريقة يظل<br />
/// المنشئ مستقلًا من فئات المنتج الحقيقي.<br />
public func factoryMethod() -> Product {<br />
return ConcreteProduct1()<br />
}<br />
}<br />
<br />
class ConcreteCreator2: Creator {<br />
<br />
public func factoryMethod() -> Product {<br />
return ConcreteProduct2()<br />
}<br />
}<br />
<br />
/// تصرح واجهة المنتج عن العمليات التي يجب أن تستخدمها المنتجات الحقيقية.<br />
protocol Product {<br />
<br />
func operation() -> String<br />
}<br />
<br />
/// توضح المنتجات الحقيقية الاستخدامات المختلفة لواجهة المنتج.<br />
class ConcreteProduct1: Product {<br />
<br />
func operation() -> String {<br />
return "{Result of the ConcreteProduct1}"<br />
}<br />
}<br />
<br />
class ConcreteProduct2: Product {<br />
<br />
func operation() -> String {<br />
return "{Result of the ConcreteProduct2}"<br />
}<br />
}<br />
<br />
<br />
/// تعمل شيفرة العميل مع نسخة من منشئ حقيقي ولو من خلال واجهته<br />
/// الأساسية، فطالما أن العميل يظل عاملًا مع المنشئ من خلال<br />
/// واجهة أساسية فيمكنك تمرير أي فئة منشئ فرعية إليه.<br />
class Client {<br />
// ...<br />
static func someClientCode(creator: Creator) {<br />
print("Client: I'm not aware of the creator's class, but it still works.\n"<br />
+ creator.someOperation());<br />
}<br />
// ...<br />
}<br />
<br />
/// لنرى الآن كيف سيعمل كل ذلك..<br />
class FactoryMethodConceptual: XCTestCase {<br />
<br />
func testFactoryMethodConceptual() {<br />
<br />
/// يختار التطبيق نوع منشئ بناءً على الإعدادات أو البيئة.<br />
<br />
print("App: Launched with the ConcreteCreator1.");<br />
Client.someClientCode(creator: ConcreteCreator1())<br />
<br />
print("\nApp: Launched with the ConcreteCreator2.");<br />
Client.someClientCode(creator: ConcreteCreator2())<br />
}<br />
}<br />
</syntaxhighlight><br />
<br />
==== Output.txt: نتائج التنفيذ ====<br />
<syntaxhighlight lang="text"><br />
App: Launched with the ConcreteCreator1.<br />
Client: I'm not aware of the creator's class, but it still works.<br />
Creator: The same creator's code has just worked with {Result of the ConcreteProduct1}<br />
<br />
App: Launched with the ConcreteCreator2.<br />
Client: I'm not aware of the creator's class, but it still works.<br />
Creator: The same creator's code has just worked with {Result of the ConcreteProduct2}<br />
</syntaxhighlight><br />
<br />
=== مثال واقعي ===<br />
<br />
==== Example.swift: مثال واقعي ====<br />
<syntaxhighlight lang="swift"><br />
import XCTest<br />
<br />
class FactoryMethodRealWorld: XCTestCase {<br />
<br />
func testFactoryMethodRealWorld() {<br />
<br />
let info = "Very important info of the presentation"<br />
<br />
let clientCode = ClientCode()<br />
<br />
/// اعرض المعلومات باستخدام الواي فاي.<br />
clientCode.present(info: info, with: WifiFactory())<br />
<br />
/// اعرض المعلومات باستخدام البلوتوث.<br />
clientCode.present(info: info, with: BluetoothFactory())<br />
}<br />
}<br />
<br />
protocol ProjectorFactory {<br />
<br />
func createProjector() -> Projector<br />
<br />
func syncedProjector(with projector: Projector) -> Projector<br />
}<br />
<br />
extension ProjectorFactory {<br />
<br />
/// ProjectorFactory التطبيق الأساسي لـ<br />
<br />
func syncedProjector(with projector: Projector) -> Projector {<br />
<br />
/// خاص بها Projector تنشئ كل نسخة جهاز عرض خاص.<br />
let newProjector = createProjector()<br />
<br />
/// زامِن أجهزة العرض.<br />
newProjector.sync(with: projector)<br />
<br />
return newProjector<br />
}<br />
}<br />
<br />
class WifiFactory: ProjectorFactory {<br />
<br />
func createProjector() -> Projector {<br />
return WifiProjector()<br />
}<br />
}<br />
<br />
class BluetoothFactory: ProjectorFactory {<br />
<br />
func createProjector() -> Projector {<br />
return BluetoothProjector()<br />
}<br />
}<br />
<br />
protocol Projector {<br />
<br />
/// واجهة جهاز العرض المجردة.<br />
<br />
var currentPage: Int { get }<br />
<br />
func present(info: String)<br />
<br />
func sync(with projector: Projector)<br />
<br />
func update(with page: Int)<br />
}<br />
<br />
extension Projector {<br />
<br />
/// الاستخدام الأساسي لأساليب أجهزة العرض.<br />
<br />
func sync(with projector: Projector) {<br />
projector.update(with: currentPage)<br />
}<br />
}<br />
<br />
class WifiProjector: Projector {<br />
<br />
var currentPage = 0<br />
<br />
func present(info: String) {<br />
print("Info is presented over Wifi: \(info)")<br />
}<br />
<br />
func update(with page: Int) {<br />
/// ... مرر الصفحة باستخدام اتصال الواي فاي.<br />
/// ...<br />
currentPage = page<br />
}<br />
}<br />
<br />
class BluetoothProjector: Projector {<br />
<br />
var currentPage = 0<br />
<br />
func present(info: String) {<br />
print("Info is presented over Bluetooth: \(info)")<br />
}<br />
<br />
func update(with page: Int) {<br />
/// ... مرر الصفحة باستخدام اتصال البلوتوث.<br />
/// ...<br />
currentPage = page<br />
}<br />
}<br />
<br />
private class ClientCode {<br />
<br />
private var currentProjector: Projector?<br />
<br />
func present(info: String, with factory: ProjectorFactory) {<br />
<br />
/// تفقد إن كان العميل يعرض شيئًا بالفعل ...<br />
<br />
guard let projector = currentProjector else {<br />
<br />
/// فارغ، أنشئ جهاز عرض جديد وابدأ العرض 'currentProjector' متغير.<br />
<br />
let projector = factory.createProjector()<br />
projector.present(info: info)<br />
self.currentProjector = projector<br />
return<br />
}<br />
<br />
/// شيفرة العميل لديها جهاز عرض بالفعل، سنزامن صفحات جهاز العرض القديم<br />
/// مع الجهاز الجديد.<br />
<br />
self.currentProjector = factory.syncedProjector(with: projector)<br />
self.currentProjector?.present(info: info)<br />
}<br />
}<br />
</syntaxhighlight><br />
<br />
==== Output.txt: نتائج التنفيذ ====<br />
<syntaxhighlight lang="text"><br />
Info is presented over Wifi: Very important info of the presentation<br />
Info is presented over Bluetooth: Very important info of the presentation<br />
</syntaxhighlight><br />
<br />
== الاستخدام في لغة TypeScript ==<br />
'''المستوى: ★ ☆ ☆'''<br />
<br />
'''الانتشار: ★ ★ ★'''<br />
<br />
'''أمثلة الاستخدام''': يستخدم أسلوب المصنع بكثرة في شيفرة TypeScript، وهو مفيد في كتابة شيفرة عالية المرونة.<br />
<br />
كما تقدم في شرح الاستخدام في لغة جافا، يمكن ملاحظة أساليب المصنع من الأساليب الإنشائية التي تنشئ كائنات من فئات حقيقية (concrete classes) لكنها تعيدها ككائنات من نوع مجرد (abstract type) أو واجهة مجردة (abstract interface).<br />
<br />
=== مثال: بُنية النمط ===<br />
يوضح هذاالمثال بنية نمط أسلوب المصنع، ويركز على إجابة الأسئلة التالية:<br />
* ما الفئات التي يتكون منها؟<br />
* ما الأدوار التي تلعبها هذه الفئات؟<br />
* كيف ترتبط عناصر النمط ببعضها؟<br />
<br />
==== index.ts: مثال تصوري ====<br />
<syntaxhighlight lang="typescript"><br />
/**<br />
* تصرح فئة المنشئ عن أسلوب المصنع الذي يجب أن يعيد كائنًا من فئة أحد المنتجات<br />
* وتوضح الفئة الفرعية للمنشئ في الغالب استخدامات هذا الأسلوب.<br />
*/<br />
abstract class Creator {<br />
/**<br />
* لاحظ أن المنشئ قد يوضح بعض الاستخدامات الافتراضية لأسلوب المصنع.<br />
*/<br />
public abstract factoryMethod(): Product;<br />
<br />
/**<br />
* لاحظ كذلك أن وظيفة المنشئ الأساسية ليست إنشاء المنتجات، رغم مايوحي به الاسم،<br />
* لكن له عادة منطق عمل يعتمد على كائنات المنتج المعادة<br />
* بواسطة أسلوب المصنع.<br />
* وتستطيع الفئات الفرعية تغيير منطق العمل ذاك بشكل غير مباشر<br />
* عبر تخطي أسلوب المصنع وإعادة نوع مختلف من المنتجات منه.<br />
<br />
*/<br />
public someOperation(): string {<br />
// استدع أسلوب المصنع لإنشاء كائن منتج.<br />
const product = this.factoryMethod();<br />
// والآن، استخدم المنتج.<br />
return `Creator: The same creator's code has just worked with ${product.operation()}`;<br />
}<br />
}<br />
<br />
/**<br />
* تتخطى المنشئات الحقيقية أسلوب المصنع من أجل تغيير نوع المنتج.<br />
*/<br />
class ConcreteCreator1 extends Creator {<br />
/**<br />
* لاحظ أن توقيع الأسلوب لا يزال يستخدم نوع المنتج النظري برغم <br />
* أن المنتج الحقيقي مُعاد فعلًا من الأسلوب، وبهذه الطريقة يظل <br />
* المنشئ مستقلًا من فئات المنتج الحقيقي.<br />
<br />
*/<br />
public factoryMethod(): Product {<br />
return new ConcreteProduct1();<br />
}<br />
}<br />
<br />
class ConcreteCreator2 extends Creator {<br />
public factoryMethod(): Product {<br />
return new ConcreteProduct2();<br />
}<br />
}<br />
<br />
/**<br />
* تصرح واجهة المنتج عن العمليات التي يجب أن تستخدمها المنتجات الحقيقية.<br />
*/<br />
interface Product {<br />
operation(): string;<br />
}<br />
<br />
/**<br />
* توضح المنتجات الحقيقية الاستخدامات المختلفة لواجهة المنتج.<br />
*/<br />
class ConcreteProduct1 implements Product {<br />
public operation(): string {<br />
return '{Result of the ConcreteProduct1}';<br />
}<br />
}<br />
<br />
class ConcreteProduct2 implements Product {<br />
public operation(): string {<br />
return '{Result of the ConcreteProduct2}';<br />
}<br />
}<br />
<br />
/**<br />
* تعمل شيفرة العميل مع نسخة من منشئ حقيقي ولو من خلال واجهته<br />
* الأساسية، فطالما أن العميل يظل عاملًا مع المنشئ من خلال<br />
* واجهة أساسية فيمكنك تمرير أي فئة منشئ فرعية إليه.<br />
*/<br />
function clientCode(creator: Creator) {<br />
// ...<br />
console.log('Client: I\'m not aware of the creator\'s class, but it still works.');<br />
console.log(creator.someOperation());<br />
// ...<br />
}<br />
<br />
/**<br />
* يختار التطبيق نوع منشئ بناءً على الإعدادات أو البيئة.<br />
*/<br />
console.log('App: Launched with the ConcreteCreator1.');<br />
clientCode(new ConcreteCreator1());<br />
console.log('');<br />
<br />
console.log('App: Launched with the ConcreteCreator2.');<br />
clientCode(new ConcreteCreator2());<br />
</syntaxhighlight><br />
<br />
==== Output.txt: نتائج التنفيذ ====<br />
<syntaxhighlight lang="text"><br />
App: Launched with the ConcreteCreator1.<br />
Client: I'm not aware of the creator's class, but it still works.<br />
Creator: The same creator's code has just worked with {Result of the ConcreteProduct1}<br />
<br />
App: Launched with the ConcreteCreator2.<br />
Client: I'm not aware of the creator's class, but it still works.<br />
Creator: The same creator's code has just worked with {Result of the ConcreteProduct2}<br />
</syntaxhighlight><br />
<br />
== انظر أيضًا ==<br />
* [[Design Patterns/singleton|نمط المفردة]].<br />
* [[Design Patterns/abstract factory|نمط المصنع المجرد]].<br />
<br />
== مصادر ==<br />
* [https://refactoring.guru/design-patterns/factory-method توثيق نمط أسلوب المصنع في موقع refactoring.guru].<br />
[[تصنيف:Design Patterns]]<br />
[[تصنيف:Creational Patterns]]<br />
[[تصنيف:Factory Method Design Pattern]]</div>عاطف-بن-عليhttps://wiki.hsoub.com/index.php?title=Design_Patterns/what_is_pattern&diff=29663Design Patterns/what is pattern2020-03-12T06:18:36Z<p>عاطف-بن-علي: تعديل صياغة بعض الجمل.</p>
<hr />
<div><noinclude>{{DISPLAYTITLE:ما هي أنماط التصميم؟}}</noinclude><br />
تشبه الأنماط (pattern) في تصميم البرمجيات وصفات الطهي، فهي ليست أطباقًا جاهزة، لكنها إرشادات لتقطيع وتجهيز المنتجات وطهيها ومن ثم تقديمها.<br />
<br />
== محتوى النمط ==<br />
يتكون وصف النمط عادة من التالي:<br />
* مشكلة يحلها النمط.<br />
* دافع لحل المشكلة باستخدام الأسلوب الذي يرشحه النمط.<br />
* هيكلة الفئات التي تكوّن الحل.<br />
* مثال بلغة برمجية.<br />
* وصف فروق تنفيذ النمط في سياقات مختلفة.<br />
* العلاقات مع الأنماط الأخرى.<br />
<br />
== من يخترع الأنماط؟ ==<br />
الأنماط تُكتشف ولا تخترع، فهي نماذج لحل مشاكل متكررة وليست أفكارًا مبتكرة أو فريدة. وأول من قدم وصفًا للأنماط كان كريستوفر أليكساندر (Christopher Alexander) في كتابه "لغة النمط: المدن والمباني والإنشاء" (A Pattern Language: Towns, Buildings, Construction)، ويتحدث في الكتاب عن "لغة" لتصميم بيئة المدن، وتجيب فصول الكتاب عن أسئلة معمارية تصف ما يجب أن تكون عليه تلك المدن، مثل ارتفاع النوافذ وعدد الطوابق لكل مبنى، وحجم المساحات الخضراء في كل حي وهكذا.<br />
<br />
وقد ألهمت فكرة الكتاب أربعة مؤلفين -عُرفوا بعصابة الأربعة- هم إريك جاما (Erich Gamma) وجون فليسيدز (John Vlissides) ورالف جونسون (Ralph Johnson) وريتشارد هيلم (Richard Helm) لينشروا كتابًا في 1995 اسمه "أنماط التصميم: عناصر البرمجيات كائنية التوجه القابلة لإعادة الاستخدام" (Design Patterns: Elements of Reusable Object-Oriented Software)، طبقوا فيه مبدأ الأنماط التقليدية على البرمجة، وقد احتوى الكتاب على ثلاثة وعشرين نمطًا تحل أغلب مشاكل التصميم كائني التوجه. وقد اكتُشفت عشرات الأنماط منذ ذلك الوقت وصار مبدأ الأنماط مشهورًا في أنواعٍ أخرى من البرمجة، ما يعني إمكانية اكتشاف أنماط جديدة خارج نطاق التصميم كائني التوجه.<br />
<br />
== تصنيف الأنماط ==<br />
تختلف الأنماط عن بعضها في مدى تعقيدها ومستوى تفاصيلها ومجال تطبيقها على النظام الذي تصممه، فبالعودة للتشبيه مع وصفات الطهي، قد يكون لديك وصفة لحساء أو قائمة ضخمة لعشاء في احتفالية. وبإسقاط ذلك المثال على الأنماط فإن أسهل صورة للأنماط هي المصطلحات (idioms) وهي ليست عامة بما أنه لا يمكن تطبيقها إلا في لغة برمجة وحيدة، وأكثر صورة عامة هي الأنماط المعمارية (architectural patterns) التي يمكن استخدامها في أي لغة تقريبًا، وهي ضرورية لتصميم البرنامج ككل وليس بعض المكونات فيه.<br />
<br />
== أهمية تعلم أنماط التصميم ==<br />
لعل أهم سبب لتعلم أنماط التصميم هو أن الأنماط تسهِّل تصميم ودعم البرامج، لكن توجد بعض الفوائد الأخرى من تعلم أنماط التصميم، أهمها ما يلي:<br />
<br />
=== الحلول المجربة والمختبرة ===<br />
ستقضي وقتًا أقل من خلال تطبيق الحلول الجاهزة بدلًا من إعادة اختراع العجلة.<br />
<br />
=== توحيد الشيفرة البرمجية ===<br />
سيكون لديك مشاكل أقل (Bugs) بما أنك تستخدم حلولًا موحدة نموذجية قد اكتشفت مشاكلها المخفية وتم حلها.<br />
<br />
=== معجم عالمي للمبرمجين ===<br />
لن تحتاج إلا إلى ذكر اسم نمط التصميم الذي استخدمته حين تريد إيصال فكرة التصميم لغيرك من المبرمجين، بدلًا من قضاء ساعة في شرح التصميم الجديد الذي ابتكرته وسرد الفئات (classes) المطلوبة.<br />
<br />
== النقد ==<br />
خرجت انتقادات كثيرة لأنماط التصميم منذ ظهورها أول مرة حتى قيل أنه ما ترك نقدها إلا الكسول، إليك أهم الانتقادات التي وُجِّهت إلى أنماط التصميم:<br />
<br />
=== حلول سريعة للغات البرمجة الضعيفة ===<br />
لا تظهر الحاجة إلى الأنماط إلا حين يختار الناس لغة أو تقنية تفتقر إلى مستوى التعبير المطلوب، وتصبح الأنماط في تلك الحالة هي الحل السريع الذي يعطي اللغة القدرات الخارقة التي تحتاجها. فمثلًا يمكن تطبيق نمط الاستراتيجية (strategy pattern) من خلال دالة (lamda) في لغات البرمجة الحديثة. وقد كان أول من تحدث عن وجهة النظر تلك هو بول جراهام (Paul Graham) في مقاله ([http://www.paulgraham.com/icad.html Revenge Of The Nerds]) .<br />
<br />
=== حلول تفتقر للكفاءة ===<br />
تحاول الأنماط أن تنظم الطرق المستخدمة بالفعل، وذلك التوحيد يراه العديد على أنه مذهب يطبقونه حرفيًا دون النظر إلى سياق المشروع الذي يعملون عليه.<br />
<br />
=== استخدام غير مبرر ===<br />
<blockquote>إن لم يكن لديك إلا مطرقة، فإن كل شيء يبدو كمسمار.</blockquote>يواجه المبتدئون مشكلة بمجرد أن يتعلموا أنماط التصميم، ذلك أنهم يحاولون استخدامها حتى في المواقف التي يؤدي فيها الغرض مجرد شيفرة غير معقدة.<br />
[[تصنيف:Design Patterns]]</div>عاطف-بن-عليhttps://wiki.hsoub.com/index.php?title=Refactoring&diff=28687Refactoring2019-06-23T12:47:40Z<p>عاطف-بن-علي: اقتراح تعديل صياغة الجملة</p>
<hr />
<div><noinclude>{{DISPLAYTITLE:إعادة التصميم (Refactoring)}}</noinclude><br />
تهدف عملية إعادة التصميم (refactoring) للحصول على شيفرة جيّدة سهلة القراءة يسهل تطويرها والتخلُّص من المتطلَّبات التقنيّة الزائدة فيها، وهذا ما يُعرَف بالشيفرة النظيفة (clean code) لأنّ الشيفرة الرديئة لا بُدَّ من انعكاسها سلبًا على نجاح المشروع البرمجيّ.<br />
<br />
== [[Refactoring/what is refactoring|كيف تكون الشيفرة نظيفة؟]] ==<br />
هدف عملية إعادة التصميم (refactoring) هو التخلُّص من المتطلَّبات التقنيّة الزائدة، إذ تحوِّل كلَّ الفوضى المنتشرة في الشيفرة إلى شيفرةٍ نظيفةٍ (clean code) ذات تصميمٍ سهل، وهذا -لا بُدَّ- أمرٌ رائعٌ. من مميزات الشيفرة النظيفة:<br />
* واضحة ومقروءة<br />
* لا تكرار فيها<br />
* بأقل عددٍ ممكنٍ من الأصناف<br />
* تجتاز الاختبارات المختلفة بنجاح<br />
* سهلة ولا تحتاج الصيانة المتكرِّرة<br />
<br />
== [[Refactoring/technical debt|فخ الأعباء التقنية]] ==<br />
يقع الكثير من المبرمجين في فخ الأعباء التقنية وهذا مكلفٌ جدًا إن لم يُعالَج في وقت مبكِّر، ومن أسبابه:<br />
* '''ضغط العمل:''' مما يؤدي لنشر بعض الميّزات (features) قبل الانتهاء منها كلِّيَّا.<br />
* '''التغافل عن عواقب الأعباء التقنيّة:''' لأنّ الأعباء التقنيّة ستحدُّ من سرعة التطوير البرمجيّ.<br />
* '''الفشل بمعالجة الترابط الشديد ما بين المكونات البرمجيّة:''' وذلك عندما يبدو المشروع كتلةً واحدةً بدلًا من وحداتٍ مستقلةٍ.<br />
* '''إهمال إجراء الاختبارات:''' وتكون النتائج حينئذٍ كارثيّة!<br />
* '''صياغة توثيقيّة هزيلة:''' تكون سببًا للكثير من المشاكل لدى المبرمجين الجُدد.<br />
* '''غياب التواصل الفعّال بين أعضاء الفريق:''' كأن يتابع المبرمجون والمطورون العمل وفقًا لمعلوماتٍ وعملياتٍ قديمةٍ من المشروع.<br />
* '''التطوير بعيد الأمد لعدّة فروع بوقتٍ واحدٍ:''' وخاصّة عندما يكون هنالك تغييرات إفراديّة.<br />
* '''تسويف عملية إعادة التصميم (refactoring):''' وهذا يعني زيادة عدد الشيفرات التي سيُعاد العمل عليها مستقبلًا.<br />
* '''لا رقابة للالتزام بالنمط المُوحَّد:''' عندما يكتب كلُّ شخصٍ شيفرةً بحسب نظرته وطريقته الخاصّة.<br />
* '''الإلمام غير الكافي:''' عندما لا يعرف المُطوِّر كيفيّة كتابة شيفرة فعّالةً ومناسبة.<br />
<br />
== [[Refactoring/when|متى نحتاج إعادة التصميم؟]] ==<br />
نحتاج إلى إعادة التصميم:<br />
# '''عند إضافة ميّزةٍ (feature) جديدة''': إذ سيصبح التحكُّم بالشيفرة النظيفة (clean code) أكثر سهولةً، وبالتالي فإنّ إجراء التغييرات سيكون أسهل بكثيرٍ مما كان عليه قبل إعادة التصميم.<br />
# '''عند إصلاح الأخطاء (bugs)''': إذ ستتَّضح الأخطاء بجهدٍ ووقتٍ أقل، وستغني إعادة التصميم المبكِّرة عن الحاجةَ لإعادة التصميم المُخصَّص لاحقًا.<br />
# '''أثناء مراجعة الشيفرة (code review)''': إذ هي الفرصةُ الأخيرة لتوضيب الشيفرة قبل نشرها للعامّة.<br />
<br />
== [[Refactoring/how to|خطوات إعادة التصميم]] ==<br />
تجري عملية إعادة التصميم عبر عدّة خطواتٍ تُحدِث تغييرًا طفيفا تدريجيًّا يجعل الشيفرة (مع كلِّ تغييرٍ) أفضل بقليلٍ، ولكنها لا تؤثر على أداء وفعاليّة البرنامج وتحافظ على استمرار عمله بشكلٍ سليمٍ، وتتلخص إعادة التصميم بالخطوات الآتية:<br />
* '''الحصول على شيفرةٍ نظيفة'''<br />
* ''' لا مهام وظيفيّة جديدة أثناء إعادة التصميم'''<br />
* '''اجتياز كافة الاختبارات السابقة'''<br />
<br />
=== مثال ===<br />
تفيد عملية إعادة التصميم في تسهيل التعليمات الشرطيّة المعقَّدة وذلك عبر عزل عملياتها في توابع مستقلَّة كما في المثال الآتي.<br />
<br />
==== الشيفرة قبل إعادة التصميم ====<br />
<syntaxhighlight lang="java"><br />
if (date.before(SUMMER_START) || date.after(SUMMER_END)) {<br />
charge = quantity * winterRate + winterServiceCharge;<br />
}<br />
else {<br />
charge = quantity * summerRate;<br />
}<br />
<br />
<br />
</syntaxhighlight><br />
<br />
==== الشيفرة بعد التصميم ====<br />
<syntaxhighlight lang="java"><br />
if (notSummer(date)) {<br />
charge = winterCharge(quantity);<br />
}<br />
else {<br />
charge = summerCharge(quantity);<br />
}<br />
<br />
<br />
</syntaxhighlight><br />
<br />
والفرق واضحٌ ما بين الشيفرتين من ناحية التنظيم (organization) وسهولة كشف الأخطاء (bug detects) وقابليّة القراءة (readability) والصيانة (maintenance).<br />
<br />
== [[Refactoring/smells|مشاكل الشيفرات]] ==<br />
قد تعاني الشيفرات الكثير من الأمراض والعلل الشكلية؛ فبمجرد اكتشاف تلك العلل الظاهرية، يسهل علينا معرفة العلاج (التقنيات) وتطبيقه (إعادة التصميم) للحصول على شيفرة سليمة نظيفة. من هذه العلل:<br />
<br />
=== [[Refactoring/smells/bloaters|المبالغة والإطالة]] ===<br />
قد يزداد حجم الشيفرة ازديادًا كبيرًا ليصل لمرحلةٍ يصعُب التعامل معها، ويبدو هذا التضخم واضحًا.<br />
=== [[Refactoring/smells/oo abusers|الاستخدام الخطأ لمبادئ البرمجة كائنية التوجه (OOP)]] ===<br />
من مشاكل الشيفرات أيضًا التطبيقُ الخطأ وغير المكتمل لمبادئ البرمجة كائنية التوجّه (Object-Oriented).<br />
=== [[Refactoring/smells/change preventers|عرقلة التغيير]] ===<br />
قد يكون تطوير بعض الشيفرات مشكلةً حقيقيةً إذ عند إحداث أيّ تغييرٍ في جزءٍ منها لا بُدَّ وأن تتبعه عدّة تغييراتٍ أخرى في أجزاء متفرِّقة، وبالتالي سيصبح تطوير البرنامج شائكًا ومعقّدًا وبتكلفةٍ غير زهيدةٍ.<br />
<br />
=== [[Refactoring/smells/dispensables|الأجزاء الفائضة]] ===<br />
وهي الأجزاء عديمة النفع في الشيفرة، وسيجعلُ التخلُّصُ منها الشيفرةَ نظيفةً يسيرة الفهم وأكثر فعاليّة.<br />
=== [[Refactoring/smells/couplers|الروابط الازدواجية]] ===<br />
مثل إنشاء رابطٍ شديدٍ ازدواجيّ (ما بين صنفين [classes])، أو التفويض المفرط (excessive delegation).<br />
<br />
=== [[Refactoring/smells/other smells|مشاكل أخرى]] ===<br />
ستجد في هذا القسم الاختلالات والمشكلات التي لا تنحصر في صنف محدَّد.<br />
<br />
== [[Refactoring/techniques|تقنيات إعادة التصميم]] ==<br />
هنالك العديد من تقنيات إعادة التصميم التي يمكن استعمالها في حالات عديدة. تنقسم هذه التقنيات إلى:<br />
<br />
===[[Refactoring/techniques/composing methods|إنشاء التوابع]]===<br />
تستهدف إعادة التصميم بشكل رئيس إنشاء التوابع الصحيحة المناسبة، إذ تكون التوابع الطويلة سببًا للمشاكل في كثيرٍ من الحالات، وتجعل شيفرات بعض التوابع منطق التنفيذ (execution logic) غامضًا ويصبح التابع بهذا عصيَّ الفهم من جهةٍ وصعب التغييرٍ من جهة ثانية.<br />
<br />
يشمل هذا القسم من الحلول كلَّ ما يتعلق بالتوابع وإزالة التكرار (duplicates) في الشيفرة ليسمح بإجراء التطويرات المستقبليّة.<br />
<br />
===[[Refactoring/techniques/moving features between objects|نقل الميزات ما بين الكائنات]]===<br />
تساعد عملية إعادة التصميم في توزيع المهام بشكل مثاليّ على الأصناف المختلفة في الشيفرة، وتضمن تقنيات الحل هذه طريقةً آمنةً لنقل المهام ما بين الأصناف، وإنشاء أصناف جديدة وحماية تفاصيل عملية التنفيذ من الوصول العام.<br />
===[[Refactoring/techniques/organizing data|تنظيم البيانات]]===<br />
تساعد تقنيات إعادة التصميم التعامل مع البيانات، وتبديل أصناف ذات وظائف كثيرة مكان الأنواع الأساسية (primitives). نتيجة لتطبيق هذه التقنيات يمكن فك ارتباطات صنف مما يجعله قابلًا للنقل وإعادة الاستعمال.<br />
<br />
===[[Refactoring/techniques/simplifying conditional expressions|تسهيل التعابير الشرطية]]===<br />
تزداد البنية المنطقية للشروط تعقيدًا مع مرور الوقت، لذا هنالك الكثير من التقنيات لمواجهة هذا التعقيد وتسهيله.<br />
<br />
===[[Refactoring/techniques/simplifying method calls|تسهيل استدعاءات التوابع]]===<br />
تجعل التقنيات التي سيشار إليها في هذا القسم استدعاءات التوابع أسهل للفهم والاستيعاب. سيؤدي ذلك بدوره إلى تسهيل الواجهات للتفاعل بين الأصناف.<br />
<br />
===[[Refactoring/techniques/dealing with generalization|التعامل مع التعميم]]===<br />
للتجريد (Abstraction) تقنيات إعادة التصميم الخاصة به وهي المرتبطة بشكل أساسي بوظيفة النقل على طول التسلسل الهرمي لوراثة الصنف (class inheritance hierarchy)، وبإنشاء أصناف وواجهات جديدة، وبتبديل التفويض مكان الوراثة أو العكس.<br />
<br />
== مصادر ==<br />
* [https://refactoring.guru/ صفحة توثيق إعادة التصميم في موقع refactoring.guru]<br />
[[تصنيف:Refactoring]]</div>عاطف-بن-عليhttps://wiki.hsoub.com/index.php?title=Refactoring&diff=28686Refactoring2019-06-23T12:45:55Z<p>عاطف-بن-علي: /* تنظيم البيانات */</p>
<hr />
<div><noinclude>{{DISPLAYTITLE:إعادة التصميم (Refactoring)}}</noinclude><br />
تهدف عملية إعادة التصميم (refactoring) للحصول على شيفرة جيّدة سهلة القراءة يسهل تطويرها والتخلُّص من المتطلَّبات التقنيّة الزائدة فيها، وهذا ما يُعرَف بالشيفرة النظيفة (clean code) لأنّ الشيفرة الرديئة لا بُدَّ من انعكاسها سلبًا على نجاح المشروع البرمجيّ.<br />
<br />
== [[Refactoring/what is refactoring|كيف تكون الشيفرة نظيفة؟]] ==<br />
هدف عملية إعادة التصميم (refactoring) هو التخلُّص من المتطلَّبات التقنيّة الزائدة، إذ تحوِّل كلَّ الفوضى المنتشرة في الشيفرة إلى شيفرةٍ نظيفةٍ (clean code) ذات تصميمٍ سهل، وهذا -لا بُدَّ- أمرٌ رائعٌ. من مميزات الشيفرة النظيفة:<br />
* واضحة ومقروءة<br />
* لا تكرار فيها<br />
* بأقل عددٍ ممكنٍ من الأصناف<br />
* تجتاز الاختبارات المختلفة بنجاح<br />
* سهلة ولا تحتاج الصيانة المتكرِّرة<br />
<br />
== [[Refactoring/technical debt|فخ الأعباء التقنية]] ==<br />
يقع الكثير من المبرمجين في فخ الأعباء التقنية وهذا مكلفٌ جدًا إن لم يُعالَج في وقت مبكِّر، ومن أسبابه:<br />
* '''ضغط العمل:''' مما يؤدي لنشر بعض الميّزات (features) قبل الانتهاء منها كلِّيَّا.<br />
* '''التغافل عن عواقب الأعباء التقنيّة:''' لأنّ الأعباء التقنيّة ستحدُّ من سرعة التطوير البرمجيّ.<br />
* '''الفشل بمعالجة الترابط الشديد ما بين المكونات البرمجيّة:''' وذلك عندما يبدو المشروع كتلةً واحدةً بدلًا من وحداتٍ مستقلةٍ.<br />
* '''إهمال إجراء الاختبارات:''' وتكون النتائج حينئذٍ كارثيّة!<br />
* '''صياغة توثيقيّة هزيلة:''' تكون سببًا للكثير من المشاكل لدى المبرمجين الجُدد.<br />
* '''غياب التواصل الفعّال بين أعضاء الفريق:''' كأن يتابع المبرمجون والمطورون العمل وفقًا لمعلوماتٍ وعملياتٍ قديمةٍ من المشروع.<br />
* '''التطوير بعيد الأمد لعدّة فروع بوقتٍ واحدٍ:''' وخاصّة عندما يكون هنالك تغييرات إفراديّة.<br />
* '''تسويف عملية إعادة التصميم (refactoring):''' وهذا يعني زيادة عدد الشيفرات التي سيُعاد العمل عليها مستقبلًا.<br />
* '''لا رقابة للالتزام بالنمط المُوحَّد:''' عندما يكتب كلُّ شخصٍ شيفرةً بحسب نظرته وطريقته الخاصّة.<br />
* '''الإلمام غير الكافي:''' عندما لا يعرف المُطوِّر كيفيّة كتابة شيفرة فعّالةً ومناسبة.<br />
<br />
== [[Refactoring/when|متى نحتاج إعادة التصميم؟]] ==<br />
نحتاج إلى إعادة التصميم:<br />
# '''عند إضافة ميّزةٍ (feature) جديدة''': إذ سيصبح التحكُّم بالشيفرة النظيفة (clean code) أكثر سهولةً، وبالتالي فإنّ إجراء التغييرات سيكون أسهل بكثيرٍ مما كان عليه قبل إعادة التصميم.<br />
# '''عند إصلاح الأخطاء (bugs)''': إذ ستتَّضح الأخطاء بجهدٍ ووقتٍ أقل، وستغني إعادة التصميم المبكِّرة عن الحاجةَ لإعادة التصميم المُخصَّص لاحقًا.<br />
# '''أثناء مراجعة الشيفرة (code review)''': إذ هي الفرصةُ الأخيرة لتوضيب الشيفرة قبل نشرها للعامّة.<br />
<br />
== [[Refactoring/how to|خطوات إعادة التصميم]] ==<br />
تجري عملية إعادة التصميم عبر عدّة خطواتٍ تُحدِث تغييرًا طفيفا تدريجيًّا يجعل الشيفرة (مع كلِّ تغييرٍ) أفضل بقليلٍ، ولكنها لا تؤثر على أداء وفعاليّة البرنامج وتحافظ على استمرار عمله بشكلٍ سليمٍ، وتتلخص إعادة التصميم بالخطوات الآتية:<br />
* '''الحصول على شيفرةٍ نظيفة'''<br />
* ''' لا مهام وظيفيّة جديدة أثناء إعادة التصميم'''<br />
* '''اجتياز كافة الاختبارات السابقة'''<br />
<br />
=== مثال ===<br />
تفيد عملية إعادة التصميم في تسهيل التعليمات الشرطيّة المعقَّدة وذلك عبر عزل عملياتها في توابع مستقلَّة كما في المثال الآتي.<br />
<br />
==== الشيفرة قبل إعادة التصميم ====<br />
<syntaxhighlight lang="java"><br />
if (date.before(SUMMER_START) || date.after(SUMMER_END)) {<br />
charge = quantity * winterRate + winterServiceCharge;<br />
}<br />
else {<br />
charge = quantity * summerRate;<br />
}<br />
<br />
<br />
</syntaxhighlight><br />
<br />
==== الشيفرة بعد التصميم ====<br />
<syntaxhighlight lang="java"><br />
if (notSummer(date)) {<br />
charge = winterCharge(quantity);<br />
}<br />
else {<br />
charge = summerCharge(quantity);<br />
}<br />
<br />
<br />
</syntaxhighlight><br />
<br />
والفرق واضحٌ ما بين الشيفرتين من ناحية التنظيم (organization) وسهولة كشف الأخطاء (bug detects) وقابليّة القراءة (readability) والصيانة (maintenance).<br />
<br />
== [[Refactoring/smells|مشاكل الشيفرات]] ==<br />
قد تعاني الشيفرات الكثير من الأمراض والعلل الشكلية؛ فبمجرد اكتشاف تلك العلل الظاهرية، يسهل علينا معرفة العلاج (التقنيات) وتطبيقه (إعادة التصميم) للحصول على شيفرة سليمة نظيفة. من هذه العلل:<br />
<br />
=== [[Refactoring/smells/bloaters|المبالغة والإطالة]] ===<br />
قد يزداد حجم الشيفرة ازديادًا كبيرًا ليصل لمرحلةٍ يصعُب التعامل معها، ويبدو هذا التضخم واضحًا.<br />
=== [[Refactoring/smells/oo abusers|الاستخدام الخطأ لمبادئ البرمجة كائنية التوجه (OOP)]] ===<br />
من مشاكل الشيفرات أيضًا التطبيقُ الخطأ وغير المكتمل لمبادئ البرمجة كائنية التوجّه (Object-Oriented).<br />
=== [[Refactoring/smells/change preventers|عرقلة التغيير]] ===<br />
قد يكون تطوير بعض الشيفرات مشكلةً حقيقيةً إذ عند إحداث أيّ تغييرٍ في جزءٍ منها لا بُدَّ وأن تتبعه عدّة تغييراتٍ أخرى في أجزاء متفرِّقة، وبالتالي سيصبح تطوير البرنامج شائكًا ومعقّدًا وبتكلفةٍ غير زهيدةٍ.<br />
<br />
=== [[Refactoring/smells/dispensables|الأجزاء الفائضة]] ===<br />
وهي الأجزاء عديمة النفع في الشيفرة، وسيجعلُ التخلُّصُ منها الشيفرةَ نظيفةً يسيرة الفهم وأكثر فعاليّة.<br />
=== [[Refactoring/smells/couplers|الروابط الازدواجية]] ===<br />
مثل إنشاء رابطٍ شديدٍ ازدواجيّ (ما بين صنفين [classes])، أو التفويض المفرط (excessive delegation).<br />
<br />
=== [[Refactoring/smells/other smells|مشاكل أخرى]] ===<br />
ستجد في هذا القسم الاختلالات والمشكلات التي لا تنحصر في صنف محدَّد.<br />
<br />
== [[Refactoring/techniques|تقنيات إعادة التصميم]] ==<br />
هنالك العديد من تقنيات إعادة التصميم التي يمكن استعمالها في حالات عديدة. تنقسم هذه التقنيات إلى:<br />
<br />
===[[Refactoring/techniques/composing methods|إنشاء التوابع]]===<br />
تستهدف إعادة التصميم بشكل رئيس إنشاء التوابع الصحيحة المناسبة، إذ تكون التوابع الطويلة سببًا للمشاكل في كثيرٍ من الحالات، وتجعل شيفرات بعض التوابع منطق التنفيذ (execution logic) غامضًا ويصبح التابع بهذا عصيَّ الفهم من جهةٍ وصعب التغييرٍ من جهة ثانية.<br />
<br />
يشمل هذا القسم من الحلول كلَّ ما يتعلق بالتوابع وإزالة التكرار (duplicates) في الشيفرة ليسمح بإجراء التطويرات المستقبليّة.<br />
<br />
===[[Refactoring/techniques/moving features between objects|نقل الميزات ما بين الكائنات]]===<br />
تساعد عملية إعادة التصميم في توزيع المهام بشكل مثاليّ على الأصناف المختلفة في الشيفرة، وتضمن تقنيات الحل هذه طريقةً آمنةً لنقل المهام ما بين الأصناف، وإنشاء أصناف جديدة وحماية تفاصيل عملية التنفيذ من الوصول العام.<br />
===[[Refactoring/techniques/organizing data|تنظيم البيانات]]===<br />
تساعد تقنيات إعادة التصميم التعامل مع البيانات، وتبديل أصناف ذات وظائف كثيرة مكان الأنواع الأساسية (primitives). نتيجة لتطبيق هذه التقنيات يمكن فك ارتباطات صنف مما يجعله قابلًا للنقل وإعادة الاستعمال.<br />
<br />
===[[Refactoring/techniques/simplifying conditional expressions|تسهيل التعابير الشرطية]]===<br />
تزداد البنية المنطقية للشروط تعقيدًا مع مرور الوقت، لذا هنالك الكثير من التقنيات لمواجهة هذا التعقيد وتسهيله.<br />
<br />
===[[Refactoring/techniques/simplifying method calls|تسهيل استدعاءات التوابع]]===<br />
تجعل التقنيات التي سيشار إليها في هذا القسم استدعاءات التوابع أسهل للفهم والاستيعاب. سيؤدي ذلك بدوره إلى تسهيل الواجهات للتفاعل بين الأصناف.<br />
<br />
===[[Refactoring/techniques/dealing with generalization|التعامل مع التعميم]]===<br />
يملك التجريد (Abstraction) تقنيات إعادة التصميم الخاصة به والمرتبطة بشكل أساسي بوظيفة النقل على طول التسلسل الهرمي لوراثة الصنف (class inheritance hierarchy)، وبإنشاء أصناف وواجهات جديدة، وبتبديل التفويض مكان الوراثة أو العكس. <br />
<br />
== مصادر ==<br />
* [https://refactoring.guru/ صفحة توثيق إعادة التصميم في موقع refactoring.guru]<br />
[[تصنيف:Refactoring]]</div>عاطف-بن-عليhttps://wiki.hsoub.com/index.php?title=Refactoring&diff=28685Refactoring2019-06-23T12:45:19Z<p>عاطف-بن-علي: اقتراح تعديل صياغة الجملة</p>
<hr />
<div><noinclude>{{DISPLAYTITLE:إعادة التصميم (Refactoring)}}</noinclude><br />
تهدف عملية إعادة التصميم (refactoring) للحصول على شيفرة جيّدة سهلة القراءة يسهل تطويرها والتخلُّص من المتطلَّبات التقنيّة الزائدة فيها، وهذا ما يُعرَف بالشيفرة النظيفة (clean code) لأنّ الشيفرة الرديئة لا بُدَّ من انعكاسها سلبًا على نجاح المشروع البرمجيّ.<br />
<br />
== [[Refactoring/what is refactoring|كيف تكون الشيفرة نظيفة؟]] ==<br />
هدف عملية إعادة التصميم (refactoring) هو التخلُّص من المتطلَّبات التقنيّة الزائدة، إذ تحوِّل كلَّ الفوضى المنتشرة في الشيفرة إلى شيفرةٍ نظيفةٍ (clean code) ذات تصميمٍ سهل، وهذا -لا بُدَّ- أمرٌ رائعٌ. من مميزات الشيفرة النظيفة:<br />
* واضحة ومقروءة<br />
* لا تكرار فيها<br />
* بأقل عددٍ ممكنٍ من الأصناف<br />
* تجتاز الاختبارات المختلفة بنجاح<br />
* سهلة ولا تحتاج الصيانة المتكرِّرة<br />
<br />
== [[Refactoring/technical debt|فخ الأعباء التقنية]] ==<br />
يقع الكثير من المبرمجين في فخ الأعباء التقنية وهذا مكلفٌ جدًا إن لم يُعالَج في وقت مبكِّر، ومن أسبابه:<br />
* '''ضغط العمل:''' مما يؤدي لنشر بعض الميّزات (features) قبل الانتهاء منها كلِّيَّا.<br />
* '''التغافل عن عواقب الأعباء التقنيّة:''' لأنّ الأعباء التقنيّة ستحدُّ من سرعة التطوير البرمجيّ.<br />
* '''الفشل بمعالجة الترابط الشديد ما بين المكونات البرمجيّة:''' وذلك عندما يبدو المشروع كتلةً واحدةً بدلًا من وحداتٍ مستقلةٍ.<br />
* '''إهمال إجراء الاختبارات:''' وتكون النتائج حينئذٍ كارثيّة!<br />
* '''صياغة توثيقيّة هزيلة:''' تكون سببًا للكثير من المشاكل لدى المبرمجين الجُدد.<br />
* '''غياب التواصل الفعّال بين أعضاء الفريق:''' كأن يتابع المبرمجون والمطورون العمل وفقًا لمعلوماتٍ وعملياتٍ قديمةٍ من المشروع.<br />
* '''التطوير بعيد الأمد لعدّة فروع بوقتٍ واحدٍ:''' وخاصّة عندما يكون هنالك تغييرات إفراديّة.<br />
* '''تسويف عملية إعادة التصميم (refactoring):''' وهذا يعني زيادة عدد الشيفرات التي سيُعاد العمل عليها مستقبلًا.<br />
* '''لا رقابة للالتزام بالنمط المُوحَّد:''' عندما يكتب كلُّ شخصٍ شيفرةً بحسب نظرته وطريقته الخاصّة.<br />
* '''الإلمام غير الكافي:''' عندما لا يعرف المُطوِّر كيفيّة كتابة شيفرة فعّالةً ومناسبة.<br />
<br />
== [[Refactoring/when|متى نحتاج إعادة التصميم؟]] ==<br />
نحتاج إلى إعادة التصميم:<br />
# '''عند إضافة ميّزةٍ (feature) جديدة''': إذ سيصبح التحكُّم بالشيفرة النظيفة (clean code) أكثر سهولةً، وبالتالي فإنّ إجراء التغييرات سيكون أسهل بكثيرٍ مما كان عليه قبل إعادة التصميم.<br />
# '''عند إصلاح الأخطاء (bugs)''': إذ ستتَّضح الأخطاء بجهدٍ ووقتٍ أقل، وستغني إعادة التصميم المبكِّرة عن الحاجةَ لإعادة التصميم المُخصَّص لاحقًا.<br />
# '''أثناء مراجعة الشيفرة (code review)''': إذ هي الفرصةُ الأخيرة لتوضيب الشيفرة قبل نشرها للعامّة.<br />
<br />
== [[Refactoring/how to|خطوات إعادة التصميم]] ==<br />
تجري عملية إعادة التصميم عبر عدّة خطواتٍ تُحدِث تغييرًا طفيفا تدريجيًّا يجعل الشيفرة (مع كلِّ تغييرٍ) أفضل بقليلٍ، ولكنها لا تؤثر على أداء وفعاليّة البرنامج وتحافظ على استمرار عمله بشكلٍ سليمٍ، وتتلخص إعادة التصميم بالخطوات الآتية:<br />
* '''الحصول على شيفرةٍ نظيفة'''<br />
* ''' لا مهام وظيفيّة جديدة أثناء إعادة التصميم'''<br />
* '''اجتياز كافة الاختبارات السابقة'''<br />
<br />
=== مثال ===<br />
تفيد عملية إعادة التصميم في تسهيل التعليمات الشرطيّة المعقَّدة وذلك عبر عزل عملياتها في توابع مستقلَّة كما في المثال الآتي.<br />
<br />
==== الشيفرة قبل إعادة التصميم ====<br />
<syntaxhighlight lang="java"><br />
if (date.before(SUMMER_START) || date.after(SUMMER_END)) {<br />
charge = quantity * winterRate + winterServiceCharge;<br />
}<br />
else {<br />
charge = quantity * summerRate;<br />
}<br />
<br />
<br />
</syntaxhighlight><br />
<br />
==== الشيفرة بعد التصميم ====<br />
<syntaxhighlight lang="java"><br />
if (notSummer(date)) {<br />
charge = winterCharge(quantity);<br />
}<br />
else {<br />
charge = summerCharge(quantity);<br />
}<br />
<br />
<br />
</syntaxhighlight><br />
<br />
والفرق واضحٌ ما بين الشيفرتين من ناحية التنظيم (organization) وسهولة كشف الأخطاء (bug detects) وقابليّة القراءة (readability) والصيانة (maintenance).<br />
<br />
== [[Refactoring/smells|مشاكل الشيفرات]] ==<br />
قد تعاني الشيفرات الكثير من الأمراض والعلل الشكلية؛ فبمجرد اكتشاف تلك العلل الظاهرية، يسهل علينا معرفة العلاج (التقنيات) وتطبيقه (إعادة التصميم) للحصول على شيفرة سليمة نظيفة. من هذه العلل:<br />
<br />
=== [[Refactoring/smells/bloaters|المبالغة والإطالة]] ===<br />
قد يزداد حجم الشيفرة ازديادًا كبيرًا ليصل لمرحلةٍ يصعُب التعامل معها، ويبدو هذا التضخم واضحًا.<br />
=== [[Refactoring/smells/oo abusers|الاستخدام الخطأ لمبادئ البرمجة كائنية التوجه (OOP)]] ===<br />
من مشاكل الشيفرات أيضًا التطبيقُ الخطأ وغير المكتمل لمبادئ البرمجة كائنية التوجّه (Object-Oriented).<br />
=== [[Refactoring/smells/change preventers|عرقلة التغيير]] ===<br />
قد يكون تطوير بعض الشيفرات مشكلةً حقيقيةً إذ عند إحداث أيّ تغييرٍ في جزءٍ منها لا بُدَّ وأن تتبعه عدّة تغييراتٍ أخرى في أجزاء متفرِّقة، وبالتالي سيصبح تطوير البرنامج شائكًا ومعقّدًا وبتكلفةٍ غير زهيدةٍ.<br />
<br />
=== [[Refactoring/smells/dispensables|الأجزاء الفائضة]] ===<br />
وهي الأجزاء عديمة النفع في الشيفرة، وسيجعلُ التخلُّصُ منها الشيفرةَ نظيفةً يسيرة الفهم وأكثر فعاليّة.<br />
=== [[Refactoring/smells/couplers|الروابط الازدواجية]] ===<br />
مثل إنشاء رابطٍ شديدٍ ازدواجيّ (ما بين صنفين [classes])، أو التفويض المفرط (excessive delegation).<br />
<br />
=== [[Refactoring/smells/other smells|مشاكل أخرى]] ===<br />
ستجد في هذا القسم الاختلالات والمشكلات التي لا تنحصر في صنف محدَّد.<br />
<br />
== [[Refactoring/techniques|تقنيات إعادة التصميم]] ==<br />
هنالك العديد من تقنيات إعادة التصميم التي يمكن استعمالها في حالات عديدة. تنقسم هذه التقنيات إلى:<br />
<br />
===[[Refactoring/techniques/composing methods|إنشاء التوابع]]===<br />
تستهدف إعادة التصميم بشكل رئيس إنشاء التوابع الصحيحة المناسبة، إذ تكون التوابع الطويلة سببًا للمشاكل في كثيرٍ من الحالات، وتجعل شيفرات بعض التوابع منطق التنفيذ (execution logic) غامضًا ويصبح التابع بهذا عصيَّ الفهم من جهةٍ وصعب التغييرٍ من جهة ثانية.<br />
<br />
يشمل هذا القسم من الحلول كلَّ ما يتعلق بالتوابع وإزالة التكرار (duplicates) في الشيفرة ليسمح بإجراء التطويرات المستقبليّة.<br />
<br />
===[[Refactoring/techniques/moving features between objects|نقل الميزات ما بين الكائنات]]===<br />
تساعد عملية إعادة التصميم في توزيع المهام بشكل مثاليّ على الأصناف المختلفة في الشيفرة، وتضمن تقنيات الحل هذه طريقةً آمنةً لنقل المهام ما بين الأصناف، وإنشاء أصناف جديدة وحماية تفاصيل عملية التنفيذ من الوصول العام.<br />
===[[Refactoring/techniques/organizing data|تنظيم البيانات]]===<br />
تساعد تقنيات إعادة التصميم التعامل مع البيانات، وتبديل أصناف ذات وظائف كثيرة مكان الأنواع الأساسية (primitives). نتيجة لتطبيق هذه التقنيات يمكن فك ارتباطات صنف مما يجعل الصنف قابلًا للنقل وإعادة الاستعمال.<br />
<br />
===[[Refactoring/techniques/simplifying conditional expressions|تسهيل التعابير الشرطية]]===<br />
تزداد البنية المنطقية للشروط تعقيدًا مع مرور الوقت، لذا هنالك الكثير من التقنيات لمواجهة هذا التعقيد وتسهيله.<br />
<br />
===[[Refactoring/techniques/simplifying method calls|تسهيل استدعاءات التوابع]]===<br />
تجعل التقنيات التي سيشار إليها في هذا القسم استدعاءات التوابع أسهل للفهم والاستيعاب. سيؤدي ذلك بدوره إلى تسهيل الواجهات للتفاعل بين الأصناف.<br />
<br />
===[[Refactoring/techniques/dealing with generalization|التعامل مع التعميم]]===<br />
يملك التجريد (Abstraction) تقنيات إعادة التصميم الخاصة به والمرتبطة بشكل أساسي بوظيفة النقل على طول التسلسل الهرمي لوراثة الصنف (class inheritance hierarchy)، وبإنشاء أصناف وواجهات جديدة، وبتبديل التفويض مكان الوراثة أو العكس. <br />
<br />
== مصادر ==<br />
* [https://refactoring.guru/ صفحة توثيق إعادة التصميم في موقع refactoring.guru]<br />
[[تصنيف:Refactoring]]</div>عاطف-بن-عليhttps://wiki.hsoub.com/index.php?title=Refactoring&diff=28684Refactoring2019-06-23T12:41:44Z<p>عاطف-بن-علي: /* إنشاء التوابع */</p>
<hr />
<div><noinclude>{{DISPLAYTITLE:إعادة التصميم (Refactoring)}}</noinclude><br />
تهدف عملية إعادة التصميم (refactoring) للحصول على شيفرة جيّدة سهلة القراءة يسهل تطويرها والتخلُّص من المتطلَّبات التقنيّة الزائدة فيها، وهذا ما يُعرَف بالشيفرة النظيفة (clean code) لأنّ الشيفرة الرديئة لا بُدَّ من انعكاسها سلبًا على نجاح المشروع البرمجيّ.<br />
<br />
== [[Refactoring/what is refactoring|كيف تكون الشيفرة نظيفة؟]] ==<br />
هدف عملية إعادة التصميم (refactoring) هو التخلُّص من المتطلَّبات التقنيّة الزائدة، إذ تحوِّل كلَّ الفوضى المنتشرة في الشيفرة إلى شيفرةٍ نظيفةٍ (clean code) ذات تصميمٍ سهل، وهذا -لا بُدَّ- أمرٌ رائعٌ. من مميزات الشيفرة النظيفة:<br />
* واضحة ومقروءة<br />
* لا تكرار فيها<br />
* بأقل عددٍ ممكنٍ من الأصناف<br />
* تجتاز الاختبارات المختلفة بنجاح<br />
* سهلة ولا تحتاج الصيانة المتكرِّرة<br />
<br />
== [[Refactoring/technical debt|فخ الأعباء التقنية]] ==<br />
يقع الكثير من المبرمجين في فخ الأعباء التقنية وهذا مكلفٌ جدًا إن لم يُعالَج في وقت مبكِّر، ومن أسبابه:<br />
* '''ضغط العمل:''' مما يؤدي لنشر بعض الميّزات (features) قبل الانتهاء منها كلِّيَّا.<br />
* '''التغافل عن عواقب الأعباء التقنيّة:''' لأنّ الأعباء التقنيّة ستحدُّ من سرعة التطوير البرمجيّ.<br />
* '''الفشل بمعالجة الترابط الشديد ما بين المكونات البرمجيّة:''' وذلك عندما يبدو المشروع كتلةً واحدةً بدلًا من وحداتٍ مستقلةٍ.<br />
* '''إهمال إجراء الاختبارات:''' وتكون النتائج حينئذٍ كارثيّة!<br />
* '''صياغة توثيقيّة هزيلة:''' تكون سببًا للكثير من المشاكل لدى المبرمجين الجُدد.<br />
* '''غياب التواصل الفعّال بين أعضاء الفريق:''' كأن يتابع المبرمجون والمطورون العمل وفقًا لمعلوماتٍ وعملياتٍ قديمةٍ من المشروع.<br />
* '''التطوير بعيد الأمد لعدّة فروع بوقتٍ واحدٍ:''' وخاصّة عندما يكون هنالك تغييرات إفراديّة.<br />
* '''تسويف عملية إعادة التصميم (refactoring):''' وهذا يعني زيادة عدد الشيفرات التي سيُعاد العمل عليها مستقبلًا.<br />
* '''لا رقابة للالتزام بالنمط المُوحَّد:''' عندما يكتب كلُّ شخصٍ شيفرةً بحسب نظرته وطريقته الخاصّة.<br />
* '''الإلمام غير الكافي:''' عندما لا يعرف المُطوِّر كيفيّة كتابة شيفرة فعّالةً ومناسبة.<br />
<br />
== [[Refactoring/when|متى نحتاج إعادة التصميم؟]] ==<br />
نحتاج إلى إعادة التصميم:<br />
# '''عند إضافة ميّزةٍ (feature) جديدة''': إذ سيصبح التحكُّم بالشيفرة النظيفة (clean code) أكثر سهولةً، وبالتالي فإنّ إجراء التغييرات سيكون أسهل بكثيرٍ مما كان عليه قبل إعادة التصميم.<br />
# '''عند إصلاح الأخطاء (bugs)''': إذ ستتَّضح الأخطاء بجهدٍ ووقتٍ أقل، وستغني إعادة التصميم المبكِّرة عن الحاجةَ لإعادة التصميم المُخصَّص لاحقًا.<br />
# '''أثناء مراجعة الشيفرة (code review)''': إذ هي الفرصةُ الأخيرة لتوضيب الشيفرة قبل نشرها للعامّة.<br />
<br />
== [[Refactoring/how to|خطوات إعادة التصميم]] ==<br />
تجري عملية إعادة التصميم عبر عدّة خطواتٍ تُحدِث تغييرًا طفيفا تدريجيًّا يجعل الشيفرة (مع كلِّ تغييرٍ) أفضل بقليلٍ، ولكنها لا تؤثر على أداء وفعاليّة البرنامج وتحافظ على استمرار عمله بشكلٍ سليمٍ، وتتلخص إعادة التصميم بالخطوات الآتية:<br />
* '''الحصول على شيفرةٍ نظيفة'''<br />
* ''' لا مهام وظيفيّة جديدة أثناء إعادة التصميم'''<br />
* '''اجتياز كافة الاختبارات السابقة'''<br />
<br />
=== مثال ===<br />
تفيد عملية إعادة التصميم في تسهيل التعليمات الشرطيّة المعقَّدة وذلك عبر عزل عملياتها في توابع مستقلَّة كما في المثال الآتي.<br />
<br />
==== الشيفرة قبل إعادة التصميم ====<br />
<syntaxhighlight lang="java"><br />
if (date.before(SUMMER_START) || date.after(SUMMER_END)) {<br />
charge = quantity * winterRate + winterServiceCharge;<br />
}<br />
else {<br />
charge = quantity * summerRate;<br />
}<br />
<br />
<br />
</syntaxhighlight><br />
<br />
==== الشيفرة بعد التصميم ====<br />
<syntaxhighlight lang="java"><br />
if (notSummer(date)) {<br />
charge = winterCharge(quantity);<br />
}<br />
else {<br />
charge = summerCharge(quantity);<br />
}<br />
<br />
<br />
</syntaxhighlight><br />
<br />
والفرق واضحٌ ما بين الشيفرتين من ناحية التنظيم (organization) وسهولة كشف الأخطاء (bug detects) وقابليّة القراءة (readability) والصيانة (maintenance).<br />
<br />
== [[Refactoring/smells|مشاكل الشيفرات]] ==<br />
قد تعاني الشيفرات الكثير من الأمراض والعلل الشكلية؛ فبمجرد اكتشاف تلك العلل الظاهرية، يسهل علينا معرفة العلاج (التقنيات) وتطبيقه (إعادة التصميم) للحصول على شيفرة سليمة نظيفة. من هذه العلل:<br />
<br />
=== [[Refactoring/smells/bloaters|المبالغة والإطالة]] ===<br />
قد يزداد حجم الشيفرة ازديادًا كبيرًا ليصل لمرحلةٍ يصعُب التعامل معها، ويبدو هذا التضخم واضحًا.<br />
=== [[Refactoring/smells/oo abusers|الاستخدام الخطأ لمبادئ البرمجة كائنية التوجه (OOP)]] ===<br />
من مشاكل الشيفرات أيضًا التطبيقُ الخطأ وغير المكتمل لمبادئ البرمجة كائنية التوجّه (Object-Oriented).<br />
=== [[Refactoring/smells/change preventers|عرقلة التغيير]] ===<br />
قد يكون تطوير بعض الشيفرات مشكلةً حقيقيةً إذ عند إحداث أيّ تغييرٍ في جزءٍ منها لا بُدَّ وأن تتبعه عدّة تغييراتٍ أخرى في أجزاء متفرِّقة، وبالتالي سيصبح تطوير البرنامج شائكًا ومعقّدًا وبتكلفةٍ غير زهيدةٍ.<br />
<br />
=== [[Refactoring/smells/dispensables|الأجزاء الفائضة]] ===<br />
وهي الأجزاء عديمة النفع في الشيفرة، وسيجعلُ التخلُّصُ منها الشيفرةَ نظيفةً يسيرة الفهم وأكثر فعاليّة.<br />
=== [[Refactoring/smells/couplers|الروابط الازدواجية]] ===<br />
مثل إنشاء رابطٍ شديدٍ ازدواجيّ (ما بين صنفين [classes])، أو التفويض المفرط (excessive delegation).<br />
<br />
=== [[Refactoring/smells/other smells|مشاكل أخرى]] ===<br />
ستجد في هذا القسم الاختلالات والمشكلات التي لا تنحصر في صنف محدَّد.<br />
<br />
== [[Refactoring/techniques|تقنيات إعادة التصميم]] ==<br />
هنالك العديد من تقنيات إعادة التصميم التي يمكن استعمالها في حالات عديدة. تنقسم هذه التقنيات إلى:<br />
<br />
===[[Refactoring/techniques/composing methods|إنشاء التوابع]]===<br />
تستهدف إعادة التصميم بشكل رئيس إنشاء التوابع الصحيحة المناسبة، إذ تكون التوابع الطويلة سببًا للمشاكل في كثيرٍ من الحالات، وتجعل شيفرات بعض التوابع منطق التنفيذ (execution logic) غامضًا ويصبح التابع بهذا عصيَّ الفهم من جهةٍ وصعب التغييرٍ من جهة ثانية.<br />
<br />
يشمل هذا القسم من الحلول كلَّ ما يتعلق بالتوابع وإزالة التكرار (duplicates) في الشيفرة ليسمح بإجراء التطويرات المستقبليّة.<br />
<br />
===[[Refactoring/techniques/moving features between objects|نقل الميزات ما بين الكائنات]]===<br />
تساعد عملية إعادة التصميم في توزيع المهام بشكل مثاليّ على الأصناف المختلفة في الشيفرة، وتضمن تقنيات الحل هذه طريقةً آمنةً لنقل المهام ما بين الأصناف، وإنشاء أصناف جديدة وحماية تفاصيل عملية التنفيذ من الوصول العام.<br />
===[[Refactoring/techniques/organizing data|تنظيم البيانات]]===<br />
تساعد تقنيات إعادة التصميم هذه بالتعامل مع البيانات، وتبديل أصناف ذات وظائف كثيرة مكان الأنواع الأساسية (primitives). نتيجة أخرى مهمة نحصل عليها بتطبيق هذه التقنيات هي فك ارتباطات صنف مما يجعل الصنف قابلًا للنقل وإعادة الاستعمال.<br />
===[[Refactoring/techniques/simplifying conditional expressions|تسهيل التعابير الشرطية]]===<br />
تزداد البنية المنطقية للشروط تعقيدًا مع مرور الوقت، لذا هنالك الكثير من التقنيات لمواجهة هذا التعقيد وتسهيله.<br />
<br />
===[[Refactoring/techniques/simplifying method calls|تسهيل استدعاءات التوابع]]===<br />
تجعل التقنيات التي سيشار إليها في هذا القسم استدعاءات التوابع أسهل للفهم والاستيعاب. سيؤدي ذلك بدوره إلى تسهيل الواجهات للتفاعل بين الأصناف.<br />
<br />
===[[Refactoring/techniques/dealing with generalization|التعامل مع التعميم]]===<br />
يملك التجريد (Abstraction) تقنيات إعادة التصميم الخاصة به والمرتبطة بشكل أساسي بوظيفة النقل على طول التسلسل الهرمي لوراثة الصنف (class inheritance hierarchy)، وبإنشاء أصناف وواجهات جديدة، وبتبديل التفويض مكان الوراثة أو العكس. <br />
<br />
== مصادر ==<br />
* [https://refactoring.guru/ صفحة توثيق إعادة التصميم في موقع refactoring.guru]<br />
[[تصنيف:Refactoring]]</div>عاطف-بن-عليhttps://wiki.hsoub.com/index.php?title=Refactoring&diff=28683Refactoring2019-06-23T12:40:46Z<p>عاطف-بن-علي: الكاف في العربية تفيد التشبيه، ولا مكان له في الجملة، لذلك الأفضل استعمال لفظ «مثل».</p>
<hr />
<div><noinclude>{{DISPLAYTITLE:إعادة التصميم (Refactoring)}}</noinclude><br />
تهدف عملية إعادة التصميم (refactoring) للحصول على شيفرة جيّدة سهلة القراءة يسهل تطويرها والتخلُّص من المتطلَّبات التقنيّة الزائدة فيها، وهذا ما يُعرَف بالشيفرة النظيفة (clean code) لأنّ الشيفرة الرديئة لا بُدَّ من انعكاسها سلبًا على نجاح المشروع البرمجيّ.<br />
<br />
== [[Refactoring/what is refactoring|كيف تكون الشيفرة نظيفة؟]] ==<br />
هدف عملية إعادة التصميم (refactoring) هو التخلُّص من المتطلَّبات التقنيّة الزائدة، إذ تحوِّل كلَّ الفوضى المنتشرة في الشيفرة إلى شيفرةٍ نظيفةٍ (clean code) ذات تصميمٍ سهل، وهذا -لا بُدَّ- أمرٌ رائعٌ. من مميزات الشيفرة النظيفة:<br />
* واضحة ومقروءة<br />
* لا تكرار فيها<br />
* بأقل عددٍ ممكنٍ من الأصناف<br />
* تجتاز الاختبارات المختلفة بنجاح<br />
* سهلة ولا تحتاج الصيانة المتكرِّرة<br />
<br />
== [[Refactoring/technical debt|فخ الأعباء التقنية]] ==<br />
يقع الكثير من المبرمجين في فخ الأعباء التقنية وهذا مكلفٌ جدًا إن لم يُعالَج في وقت مبكِّر، ومن أسبابه:<br />
* '''ضغط العمل:''' مما يؤدي لنشر بعض الميّزات (features) قبل الانتهاء منها كلِّيَّا.<br />
* '''التغافل عن عواقب الأعباء التقنيّة:''' لأنّ الأعباء التقنيّة ستحدُّ من سرعة التطوير البرمجيّ.<br />
* '''الفشل بمعالجة الترابط الشديد ما بين المكونات البرمجيّة:''' وذلك عندما يبدو المشروع كتلةً واحدةً بدلًا من وحداتٍ مستقلةٍ.<br />
* '''إهمال إجراء الاختبارات:''' وتكون النتائج حينئذٍ كارثيّة!<br />
* '''صياغة توثيقيّة هزيلة:''' تكون سببًا للكثير من المشاكل لدى المبرمجين الجُدد.<br />
* '''غياب التواصل الفعّال بين أعضاء الفريق:''' كأن يتابع المبرمجون والمطورون العمل وفقًا لمعلوماتٍ وعملياتٍ قديمةٍ من المشروع.<br />
* '''التطوير بعيد الأمد لعدّة فروع بوقتٍ واحدٍ:''' وخاصّة عندما يكون هنالك تغييرات إفراديّة.<br />
* '''تسويف عملية إعادة التصميم (refactoring):''' وهذا يعني زيادة عدد الشيفرات التي سيُعاد العمل عليها مستقبلًا.<br />
* '''لا رقابة للالتزام بالنمط المُوحَّد:''' عندما يكتب كلُّ شخصٍ شيفرةً بحسب نظرته وطريقته الخاصّة.<br />
* '''الإلمام غير الكافي:''' عندما لا يعرف المُطوِّر كيفيّة كتابة شيفرة فعّالةً ومناسبة.<br />
<br />
== [[Refactoring/when|متى نحتاج إعادة التصميم؟]] ==<br />
نحتاج إلى إعادة التصميم:<br />
# '''عند إضافة ميّزةٍ (feature) جديدة''': إذ سيصبح التحكُّم بالشيفرة النظيفة (clean code) أكثر سهولةً، وبالتالي فإنّ إجراء التغييرات سيكون أسهل بكثيرٍ مما كان عليه قبل إعادة التصميم.<br />
# '''عند إصلاح الأخطاء (bugs)''': إذ ستتَّضح الأخطاء بجهدٍ ووقتٍ أقل، وستغني إعادة التصميم المبكِّرة عن الحاجةَ لإعادة التصميم المُخصَّص لاحقًا.<br />
# '''أثناء مراجعة الشيفرة (code review)''': إذ هي الفرصةُ الأخيرة لتوضيب الشيفرة قبل نشرها للعامّة.<br />
<br />
== [[Refactoring/how to|خطوات إعادة التصميم]] ==<br />
تجري عملية إعادة التصميم عبر عدّة خطواتٍ تُحدِث تغييرًا طفيفا تدريجيًّا يجعل الشيفرة (مع كلِّ تغييرٍ) أفضل بقليلٍ، ولكنها لا تؤثر على أداء وفعاليّة البرنامج وتحافظ على استمرار عمله بشكلٍ سليمٍ، وتتلخص إعادة التصميم بالخطوات الآتية:<br />
* '''الحصول على شيفرةٍ نظيفة'''<br />
* ''' لا مهام وظيفيّة جديدة أثناء إعادة التصميم'''<br />
* '''اجتياز كافة الاختبارات السابقة'''<br />
<br />
=== مثال ===<br />
تفيد عملية إعادة التصميم في تسهيل التعليمات الشرطيّة المعقَّدة وذلك عبر عزل عملياتها في توابع مستقلَّة كما في المثال الآتي.<br />
<br />
==== الشيفرة قبل إعادة التصميم ====<br />
<syntaxhighlight lang="java"><br />
if (date.before(SUMMER_START) || date.after(SUMMER_END)) {<br />
charge = quantity * winterRate + winterServiceCharge;<br />
}<br />
else {<br />
charge = quantity * summerRate;<br />
}<br />
<br />
<br />
</syntaxhighlight><br />
<br />
==== الشيفرة بعد التصميم ====<br />
<syntaxhighlight lang="java"><br />
if (notSummer(date)) {<br />
charge = winterCharge(quantity);<br />
}<br />
else {<br />
charge = summerCharge(quantity);<br />
}<br />
<br />
<br />
</syntaxhighlight><br />
<br />
والفرق واضحٌ ما بين الشيفرتين من ناحية التنظيم (organization) وسهولة كشف الأخطاء (bug detects) وقابليّة القراءة (readability) والصيانة (maintenance).<br />
<br />
== [[Refactoring/smells|مشاكل الشيفرات]] ==<br />
قد تعاني الشيفرات الكثير من الأمراض والعلل الشكلية؛ فبمجرد اكتشاف تلك العلل الظاهرية، يسهل علينا معرفة العلاج (التقنيات) وتطبيقه (إعادة التصميم) للحصول على شيفرة سليمة نظيفة. من هذه العلل:<br />
<br />
=== [[Refactoring/smells/bloaters|المبالغة والإطالة]] ===<br />
قد يزداد حجم الشيفرة ازديادًا كبيرًا ليصل لمرحلةٍ يصعُب التعامل معها، ويبدو هذا التضخم واضحًا.<br />
=== [[Refactoring/smells/oo abusers|الاستخدام الخطأ لمبادئ البرمجة كائنية التوجه (OOP)]] ===<br />
من مشاكل الشيفرات أيضًا التطبيقُ الخطأ وغير المكتمل لمبادئ البرمجة كائنية التوجّه (Object-Oriented).<br />
=== [[Refactoring/smells/change preventers|عرقلة التغيير]] ===<br />
قد يكون تطوير بعض الشيفرات مشكلةً حقيقيةً إذ عند إحداث أيّ تغييرٍ في جزءٍ منها لا بُدَّ وأن تتبعه عدّة تغييراتٍ أخرى في أجزاء متفرِّقة، وبالتالي سيصبح تطوير البرنامج شائكًا ومعقّدًا وبتكلفةٍ غير زهيدةٍ.<br />
<br />
=== [[Refactoring/smells/dispensables|الأجزاء الفائضة]] ===<br />
وهي الأجزاء عديمة النفع في الشيفرة، وسيجعلُ التخلُّصُ منها الشيفرةَ نظيفةً يسيرة الفهم وأكثر فعاليّة.<br />
=== [[Refactoring/smells/couplers|الروابط الازدواجية]] ===<br />
مثل إنشاء رابطٍ شديدٍ ازدواجيّ (ما بين صنفين [classes])، أو التفويض المفرط (excessive delegation).<br />
<br />
=== [[Refactoring/smells/other smells|مشاكل أخرى]] ===<br />
ستجد في هذا القسم الاختلالات والمشكلات التي لا تنحصر في صنف محدَّد.<br />
<br />
== [[Refactoring/techniques|تقنيات إعادة التصميم]] ==<br />
هنالك العديد من تقنيات إعادة التصميم التي يمكن استعمالها في حالات عديدة. تنقسم هذه التقنيات إلى:<br />
<br />
===[[Refactoring/techniques/composing methods|إنشاء التوابع]]===<br />
تستهدف إعادة التصميم بشكل رئيسيٍّ إنشاء التوابع الصحيحة المناسبة، إذ تكون التوابع الطويلة سببًا للمشاكل في كثيرٍ من الحالات، وتجعل شيفرات بعض التوابع منطق التنفيذ (execution logic) غامضًا ويصبح التابع بهذا عصيَّ الفهم من جهةٍ وصعب التغييرٍ من جهة ثانية.<br />
<br />
يشمل هذا القسم من الحلول كلَّ ما يتعلق بالتوابع وإزالة التكرار (duplicates) في الشيفرة ليسمح بإجراء التطويرات المستقبليّة.<br />
===[[Refactoring/techniques/moving features between objects|نقل الميزات ما بين الكائنات]]===<br />
تساعد عملية إعادة التصميم في توزيع المهام بشكل مثاليّ على الأصناف المختلفة في الشيفرة، وتضمن تقنيات الحل هذه طريقةً آمنةً لنقل المهام ما بين الأصناف، وإنشاء أصناف جديدة وحماية تفاصيل عملية التنفيذ من الوصول العام.<br />
===[[Refactoring/techniques/organizing data|تنظيم البيانات]]===<br />
تساعد تقنيات إعادة التصميم هذه بالتعامل مع البيانات، وتبديل أصناف ذات وظائف كثيرة مكان الأنواع الأساسية (primitives). نتيجة أخرى مهمة نحصل عليها بتطبيق هذه التقنيات هي فك ارتباطات صنف مما يجعل الصنف قابلًا للنقل وإعادة الاستعمال.<br />
===[[Refactoring/techniques/simplifying conditional expressions|تسهيل التعابير الشرطية]]===<br />
تزداد البنية المنطقية للشروط تعقيدًا مع مرور الوقت، لذا هنالك الكثير من التقنيات لمواجهة هذا التعقيد وتسهيله.<br />
<br />
===[[Refactoring/techniques/simplifying method calls|تسهيل استدعاءات التوابع]]===<br />
تجعل التقنيات التي سيشار إليها في هذا القسم استدعاءات التوابع أسهل للفهم والاستيعاب. سيؤدي ذلك بدوره إلى تسهيل الواجهات للتفاعل بين الأصناف.<br />
<br />
===[[Refactoring/techniques/dealing with generalization|التعامل مع التعميم]]===<br />
يملك التجريد (Abstraction) تقنيات إعادة التصميم الخاصة به والمرتبطة بشكل أساسي بوظيفة النقل على طول التسلسل الهرمي لوراثة الصنف (class inheritance hierarchy)، وبإنشاء أصناف وواجهات جديدة، وبتبديل التفويض مكان الوراثة أو العكس. <br />
<br />
== مصادر ==<br />
* [https://refactoring.guru/ صفحة توثيق إعادة التصميم في موقع refactoring.guru]<br />
[[تصنيف:Refactoring]]</div>عاطف-بن-عليhttps://wiki.hsoub.com/index.php?title=Refactoring&diff=28682Refactoring2019-06-23T12:39:00Z<p>عاطف-بن-علي: اضافة حرف «الواو»</p>
<hr />
<div><noinclude>{{DISPLAYTITLE:إعادة التصميم (Refactoring)}}</noinclude><br />
تهدف عملية إعادة التصميم (refactoring) للحصول على شيفرة جيّدة سهلة القراءة يسهل تطويرها والتخلُّص من المتطلَّبات التقنيّة الزائدة فيها، وهذا ما يُعرَف بالشيفرة النظيفة (clean code) لأنّ الشيفرة الرديئة لا بُدَّ من انعكاسها سلبًا على نجاح المشروع البرمجيّ.<br />
<br />
== [[Refactoring/what is refactoring|كيف تكون الشيفرة نظيفة؟]] ==<br />
هدف عملية إعادة التصميم (refactoring) هو التخلُّص من المتطلَّبات التقنيّة الزائدة، إذ تحوِّل كلَّ الفوضى المنتشرة في الشيفرة إلى شيفرةٍ نظيفةٍ (clean code) ذات تصميمٍ سهل، وهذا -لا بُدَّ- أمرٌ رائعٌ. من مميزات الشيفرة النظيفة:<br />
* واضحة ومقروءة<br />
* لا تكرار فيها<br />
* بأقل عددٍ ممكنٍ من الأصناف<br />
* تجتاز الاختبارات المختلفة بنجاح<br />
* سهلة ولا تحتاج الصيانة المتكرِّرة<br />
<br />
== [[Refactoring/technical debt|فخ الأعباء التقنية]] ==<br />
يقع الكثير من المبرمجين في فخ الأعباء التقنية وهذا مكلفٌ جدًا إن لم يُعالَج في وقت مبكِّر، ومن أسبابه:<br />
* '''ضغط العمل:''' مما يؤدي لنشر بعض الميّزات (features) قبل الانتهاء منها كلِّيَّا.<br />
* '''التغافل عن عواقب الأعباء التقنيّة:''' لأنّ الأعباء التقنيّة ستحدُّ من سرعة التطوير البرمجيّ.<br />
* '''الفشل بمعالجة الترابط الشديد ما بين المكونات البرمجيّة:''' وذلك عندما يبدو المشروع كتلةً واحدةً بدلًا من وحداتٍ مستقلةٍ.<br />
* '''إهمال إجراء الاختبارات:''' وتكون النتائج حينئذٍ كارثيّة!<br />
* '''صياغة توثيقيّة هزيلة:''' تكون سببًا للكثير من المشاكل لدى المبرمجين الجُدد.<br />
* '''غياب التواصل الفعّال بين أعضاء الفريق:''' كأن يتابع المبرمجون والمطورون العمل وفقًا لمعلوماتٍ وعملياتٍ قديمةٍ من المشروع.<br />
* '''التطوير بعيد الأمد لعدّة فروع بوقتٍ واحدٍ:''' وخاصّة عندما يكون هنالك تغييرات إفراديّة.<br />
* '''تسويف عملية إعادة التصميم (refactoring):''' وهذا يعني زيادة عدد الشيفرات التي سيُعاد العمل عليها مستقبلًا.<br />
* '''لا رقابة للالتزام بالنمط المُوحَّد:''' عندما يكتب كلُّ شخصٍ شيفرةً بحسب نظرته وطريقته الخاصّة.<br />
* '''الإلمام غير الكافي:''' عندما لا يعرف المُطوِّر كيفيّة كتابة شيفرة فعّالةً ومناسبة.<br />
<br />
== [[Refactoring/when|متى نحتاج إعادة التصميم؟]] ==<br />
نحتاج إلى إعادة التصميم:<br />
# '''عند إضافة ميّزةٍ (feature) جديدة''': إذ سيصبح التحكُّم بالشيفرة النظيفة (clean code) أكثر سهولةً، وبالتالي فإنّ إجراء التغييرات سيكون أسهل بكثيرٍ مما كان عليه قبل إعادة التصميم.<br />
# '''عند إصلاح الأخطاء (bugs)''': إذ ستتَّضح الأخطاء بجهدٍ ووقتٍ أقل، وستغني إعادة التصميم المبكِّرة عن الحاجةَ لإعادة التصميم المُخصَّص لاحقًا.<br />
# '''أثناء مراجعة الشيفرة (code review)''': إذ هي الفرصةُ الأخيرة لتوضيب الشيفرة قبل نشرها للعامّة.<br />
<br />
== [[Refactoring/how to|خطوات إعادة التصميم]] ==<br />
تجري عملية إعادة التصميم عبر عدّة خطواتٍ تُحدِث تغييرًا طفيفا تدريجيًّا يجعل الشيفرة (مع كلِّ تغييرٍ) أفضل بقليلٍ، ولكنها لا تؤثر على أداء وفعاليّة البرنامج وتحافظ على استمرار عمله بشكلٍ سليمٍ، وتتلخص إعادة التصميم بالخطوات الآتية:<br />
* '''الحصول على شيفرةٍ نظيفة'''<br />
* ''' لا مهام وظيفيّة جديدة أثناء إعادة التصميم'''<br />
* '''اجتياز كافة الاختبارات السابقة'''<br />
<br />
=== مثال ===<br />
تفيد عملية إعادة التصميم في تسهيل التعليمات الشرطيّة المعقَّدة وذلك عبر عزل عملياتها في توابع مستقلَّة كما في المثال الآتي.<br />
<br />
==== الشيفرة قبل إعادة التصميم ====<br />
<syntaxhighlight lang="java"><br />
if (date.before(SUMMER_START) || date.after(SUMMER_END)) {<br />
charge = quantity * winterRate + winterServiceCharge;<br />
}<br />
else {<br />
charge = quantity * summerRate;<br />
}<br />
<br />
<br />
</syntaxhighlight><br />
<br />
==== الشيفرة بعد التصميم ====<br />
<syntaxhighlight lang="java"><br />
if (notSummer(date)) {<br />
charge = winterCharge(quantity);<br />
}<br />
else {<br />
charge = summerCharge(quantity);<br />
}<br />
<br />
<br />
</syntaxhighlight><br />
<br />
والفرق واضحٌ ما بين الشيفرتين من ناحية التنظيم (organization) وسهولة كشف الأخطاء (bug detects) وقابليّة القراءة (readability) والصيانة (maintenance).<br />
<br />
== [[Refactoring/smells|مشاكل الشيفرات]] ==<br />
قد تعاني الشيفرات الكثير من الأمراض والعلل الشكلية؛ فبمجرد اكتشاف تلك العلل الظاهرية، يسهل علينا معرفة العلاج (التقنيات) وتطبيقه (إعادة التصميم) للحصول على شيفرة سليمة نظيفة. من هذه العلل:<br />
<br />
=== [[Refactoring/smells/bloaters|المبالغة والإطالة]] ===<br />
قد يزداد حجم الشيفرة ازديادًا كبيرًا ليصل لمرحلةٍ يصعُب التعامل معها، ويبدو هذا التضخم واضحًا.<br />
=== [[Refactoring/smells/oo abusers|الاستخدام الخطأ لمبادئ البرمجة كائنية التوجه (OOP)]] ===<br />
من مشاكل الشيفرات أيضًا التطبيقُ الخطأ وغير المكتمل لمبادئ البرمجة كائنية التوجّه (Object-Oriented).<br />
=== [[Refactoring/smells/change preventers|عرقلة التغيير]] ===<br />
قد يكون تطوير بعض الشيفرات مشكلةً حقيقيةً إذ عند إحداث أيّ تغييرٍ في جزءٍ منها لا بُدَّ وأن تتبعه عدّة تغييراتٍ أخرى في أجزاء متفرِّقة، وبالتالي سيصبح تطوير البرنامج شائكًا ومعقّدًا وبتكلفةٍ غير زهيدةٍ.<br />
<br />
=== [[Refactoring/smells/dispensables|الأجزاء الفائضة]] ===<br />
وهي الأجزاء عديمة النفع في الشيفرة، وسيجعلُ التخلُّصُ منها الشيفرةَ نظيفةً يسيرة الفهم وأكثر فعاليّة.<br />
=== [[Refactoring/smells/couplers|الروابط الازدواجية]] ===<br />
كإنشاء رابطٍ شديدٍ ازدواجيّ (ما بين صنفين [classes])، أو التفويض المفرط (excessive delegation).<br />
<br />
=== [[Refactoring/smells/other smells|مشاكل أخرى]] ===<br />
ستجد في هذا القسم الاختلالات والمشكلات التي لا تنحصر في صنف محدَّد.<br />
<br />
== [[Refactoring/techniques|تقنيات إعادة التصميم]] ==<br />
هنالك العديد من تقنيات إعادة التصميم التي يمكن استعمالها في حالات عديدة. تنقسم هذه التقنيات إلى:<br />
<br />
===[[Refactoring/techniques/composing methods|إنشاء التوابع]]===<br />
تستهدف إعادة التصميم بشكل رئيسيٍّ إنشاء التوابع الصحيحة المناسبة، إذ تكون التوابع الطويلة سببًا للمشاكل في كثيرٍ من الحالات، وتجعل شيفرات بعض التوابع منطق التنفيذ (execution logic) غامضًا ويصبح التابع بهذا عصيَّ الفهم من جهةٍ وصعب التغييرٍ من جهة ثانية.<br />
<br />
يشمل هذا القسم من الحلول كلَّ ما يتعلق بالتوابع وإزالة التكرار (duplicates) في الشيفرة ليسمح بإجراء التطويرات المستقبليّة.<br />
===[[Refactoring/techniques/moving features between objects|نقل الميزات ما بين الكائنات]]===<br />
تساعد عملية إعادة التصميم في توزيع المهام بشكل مثاليّ على الأصناف المختلفة في الشيفرة، وتضمن تقنيات الحل هذه طريقةً آمنةً لنقل المهام ما بين الأصناف، وإنشاء أصناف جديدة وحماية تفاصيل عملية التنفيذ من الوصول العام.<br />
===[[Refactoring/techniques/organizing data|تنظيم البيانات]]===<br />
تساعد تقنيات إعادة التصميم هذه بالتعامل مع البيانات، وتبديل أصناف ذات وظائف كثيرة مكان الأنواع الأساسية (primitives). نتيجة أخرى مهمة نحصل عليها بتطبيق هذه التقنيات هي فك ارتباطات صنف مما يجعل الصنف قابلًا للنقل وإعادة الاستعمال.<br />
===[[Refactoring/techniques/simplifying conditional expressions|تسهيل التعابير الشرطية]]===<br />
تزداد البنية المنطقية للشروط تعقيدًا مع مرور الوقت، لذا هنالك الكثير من التقنيات لمواجهة هذا التعقيد وتسهيله.<br />
<br />
===[[Refactoring/techniques/simplifying method calls|تسهيل استدعاءات التوابع]]===<br />
تجعل التقنيات التي سيشار إليها في هذا القسم استدعاءات التوابع أسهل للفهم والاستيعاب. سيؤدي ذلك بدوره إلى تسهيل الواجهات للتفاعل بين الأصناف.<br />
<br />
===[[Refactoring/techniques/dealing with generalization|التعامل مع التعميم]]===<br />
يملك التجريد (Abstraction) تقنيات إعادة التصميم الخاصة به والمرتبطة بشكل أساسي بوظيفة النقل على طول التسلسل الهرمي لوراثة الصنف (class inheritance hierarchy)، وبإنشاء أصناف وواجهات جديدة، وبتبديل التفويض مكان الوراثة أو العكس. <br />
<br />
== مصادر ==<br />
* [https://refactoring.guru/ صفحة توثيق إعادة التصميم في موقع refactoring.guru]<br />
[[تصنيف:Refactoring]]</div>عاطف-بن-عليhttps://wiki.hsoub.com/index.php?title=Refactoring&diff=28681Refactoring2019-06-23T12:34:51Z<p>عاطف-بن-علي: اصلاح خطأ إملائي</p>
<hr />
<div><noinclude>{{DISPLAYTITLE:إعادة التصميم (Refactoring)}}</noinclude><br />
تهدف عملية إعادة التصميم (refactoring) للحصول على شيفرة جيّدة سهلة القراءة يسهل تطويرها والتخلُّص من المتطلَّبات التقنيّة الزائدة فيها، وهذا ما يُعرَف بالشيفرة النظيفة (clean code) لأنّ الشيفرة الرديئة لا بُدَّ من انعكاسها سلبًا على نجاح المشروع البرمجيّ.<br />
<br />
== [[Refactoring/what is refactoring|كيف تكون الشيفرة نظيفة؟]] ==<br />
هدف عملية إعادة التصميم (refactoring) هو التخلُّص من المتطلَّبات التقنيّة الزائدة، إذ تحوِّل كلَّ الفوضى المنتشرة في الشيفرة إلى شيفرةٍ نظيفةٍ (clean code) ذات تصميمٍ سهل، وهذا -لا بُدَّ- أمرٌ رائعٌ. من مميزات الشيفرة النظيفة:<br />
* واضحة ومقروءة<br />
* لا تكرار فيها<br />
* بأقل عددٍ ممكنٍ من الأصناف<br />
* تجتاز الاختبارات المختلفة بنجاح<br />
* سهلة ولا تحتاج الصيانة المتكرِّرة<br />
<br />
== [[Refactoring/technical debt|فخ الأعباء التقنية]] ==<br />
يقع الكثير من المبرمجين في فخ الأعباء التقنية وهذا مكلفٌ جدًا إن لم يُعالَج في وقت مبكِّر، ومن أسبابه:<br />
* '''ضغط العمل:''' مما يؤدي لنشر بعض الميّزات (features) قبل الانتهاء منها كلِّيَّا.<br />
* '''التغافل عن عواقب الأعباء التقنيّة:''' لأنّ الأعباء التقنيّة ستحدُّ من سرعة التطوير البرمجيّ.<br />
* '''الفشل بمعالجة الترابط الشديد ما بين المكونات البرمجيّة:''' وذلك عندما يبدو المشروع كتلةً واحدةً بدلًا من وحداتٍ مستقلةٍ.<br />
* '''إهمال إجراء الاختبارات:''' وتكون النتائج حينئذٍ كارثيّة!<br />
* '''صياغة توثيقيّة هزيلة:''' تكون سببًا للكثير من المشاكل لدى المبرمجين الجُدد.<br />
* '''غياب التواصل الفعّال بين أعضاء الفريق:''' كأن يتابع المبرمجون والمطورون العمل وفقًا لمعلوماتٍ وعملياتٍ قديمةٍ من المشروع.<br />
* '''التطوير بعيد الأمد لعدّة فروع بوقتٍ واحدٍ:''' وخاصّة عندما يكون هنالك تغييرات إفراديّة.<br />
* '''تسويف عملية إعادة التصميم (refactoring):''' وهذا يعني زيادة عدد الشيفرات التي سيُعاد العمل عليها مستقبلًا.<br />
* '''لا رقابة للالتزام بالنمط المُوحَّد:''' عندما يكتب كلُّ شخصٍ شيفرةً بحسب نظرته وطريقته الخاصّة.<br />
* '''الإلمام غير الكافي:''' عندما لا يعرف المُطوِّر كيفيّة كتابة شيفرة فعّالةً ومناسبة.<br />
<br />
== [[Refactoring/when|متى نحتاج إعادة التصميم؟]] ==<br />
نحتاج إلى إعادة التصميم:<br />
# '''عند إضافة ميّزةٍ (feature) جديدة''': إذ سيصبح التحكُّم بالشيفرة النظيفة (clean code) أكثر سهولةً، وبالتالي فإنّ إجراء التغييرات سيكون أسهل بكثيرٍ مما كان عليه قبل إعادة التصميم.<br />
# '''عند إصلاح الأخطاء (bugs)''': إذ ستتَّضح الأخطاء بجهدٍ ووقتٍ أقل، وستغني إعادة التصميم المبكِّرة عن الحاجةَ لإعادة التصميم المُخصَّص لاحقًا.<br />
# '''أثناء مراجعة الشيفرة (code review)''': إذ هي الفرصةُ الأخيرة لتوضيب الشيفرة قبل نشرها للعامّة.<br />
<br />
== [[Refactoring/how to|خطوات إعادة التصميم]] ==<br />
تجري عملية إعادة التصميم عبر عدّة خطواتٍ تُحدِث تغييرًا طفيفا تدريجيًّا يجعل الشيفرة (مع كلِّ تغييرٍ) أفضل بقليلٍ، ولكنها لا تؤثر على أداء وفعاليّة البرنامج وتحافظ على استمرار عمله بشكلٍ سليمٍ، وتتلخص إعادة التصميم بالخطوات الآتية:<br />
* '''الحصول على شيفرةٍ نظيفة'''<br />
* ''' لا مهام وظيفيّة جديدة أثناء إعادة التصميم'''<br />
* '''اجتياز كافة الاختبارات السابقة'''<br />
<br />
=== مثال ===<br />
تفيد عملية إعادة التصميم في تسهيل التعليمات الشرطيّة المعقَّدة وذلك عبر عزل عملياتها في توابع مستقلَّة كما في المثال الآتي.<br />
<br />
==== الشيفرة قبل إعادة التصميم ====<br />
<syntaxhighlight lang="java"><br />
if (date.before(SUMMER_START) || date.after(SUMMER_END)) {<br />
charge = quantity * winterRate + winterServiceCharge;<br />
}<br />
else {<br />
charge = quantity * summerRate;<br />
}<br />
<br />
<br />
</syntaxhighlight><br />
<br />
==== الشيفرة بعد التصميم ====<br />
<syntaxhighlight lang="java"><br />
if (notSummer(date)) {<br />
charge = winterCharge(quantity);<br />
}<br />
else {<br />
charge = summerCharge(quantity);<br />
}<br />
<br />
<br />
</syntaxhighlight><br />
<br />
والفرق واضحٌ ما بين الشيفرتين من ناحية التنظيم (organization) وسهولة كشف الأخطاء (bug detects) وقابليّة القراءة (readability) والصيانة (maintenance).<br />
<br />
== [[Refactoring/smells|مشاكل الشيفرات]] ==<br />
قد تعاني الشيفرات الكثير من الأمراض والعلل الشكلية؛ فبمجرد اكتشاف تلك العلل الظاهرية، يسهل علينا معرفة العلاج (التقنيات) وتطبيقه (إعادة التصميم) للحصول على شيفرة سليمة نظيفة. من هذه العلل:<br />
<br />
=== [[Refactoring/smells/bloaters|المبالغة والإطالة]] ===<br />
قد يزداد حجم الشيفرة ازديادًا كبيرًا ليصل لمرحلةٍ يصعُب التعامل معها، ويبدو هذا التضخم واضحًا.<br />
=== [[Refactoring/smells/oo abusers|الاستخدام الخطأ لمبادئ البرمجة كائنية التوجه (OOP)]] ===<br />
من مشاكل الشيفرات أيضًا التطبيقُ الخطأ وغير المكتمل لمبادئ البرمجة كائنية التوجّه (Object-Oriented).<br />
=== [[Refactoring/smells/change preventers|عرقلة التغيير]] ===<br />
قد يكون تطوير بعض الشيفرات مشكلةً حقيقيةً إذ عند إحداث أيّ تغييرٍ في جزءٍ منها لا بُدَّ وأن تتبعه عدّة تغييراتٍ أخرى في أجزاء متفرِّقة، وبالتالي سيصبح تطوير البرنامج شائكًا معقّدًا وبتكلفةٍ غير زهيدةٍ.<br />
=== [[Refactoring/smells/dispensables|الأجزاء الفائضة]] ===<br />
وهي الأجزاء عديمة النفع في الشيفرة، وسيجعلُ التخلُّصُ منها الشيفرةَ نظيفةً يسيرة الفهم وأكثر فعاليّة.<br />
=== [[Refactoring/smells/couplers|الروابط الازدواجية]] ===<br />
كإنشاء رابطٍ شديدٍ ازدواجيّ (ما بين صنفين [classes])، أو التفويض المفرط (excessive delegation).<br />
<br />
=== [[Refactoring/smells/other smells|مشاكل أخرى]] ===<br />
ستجد في هذا القسم الاختلالات والمشكلات التي لا تنحصر في صنف محدَّد.<br />
<br />
== [[Refactoring/techniques|تقنيات إعادة التصميم]] ==<br />
هنالك العديد من تقنيات إعادة التصميم التي يمكن استعمالها في حالات عديدة. تنقسم هذه التقنيات إلى:<br />
<br />
===[[Refactoring/techniques/composing methods|إنشاء التوابع]]===<br />
تستهدف إعادة التصميم بشكل رئيسيٍّ إنشاء التوابع الصحيحة المناسبة، إذ تكون التوابع الطويلة سببًا للمشاكل في كثيرٍ من الحالات، وتجعل شيفرات بعض التوابع منطق التنفيذ (execution logic) غامضًا ويصبح التابع بهذا عصيَّ الفهم من جهةٍ وصعب التغييرٍ من جهة ثانية.<br />
<br />
يشمل هذا القسم من الحلول كلَّ ما يتعلق بالتوابع وإزالة التكرار (duplicates) في الشيفرة ليسمح بإجراء التطويرات المستقبليّة.<br />
===[[Refactoring/techniques/moving features between objects|نقل الميزات ما بين الكائنات]]===<br />
تساعد عملية إعادة التصميم في توزيع المهام بشكل مثاليّ على الأصناف المختلفة في الشيفرة، وتضمن تقنيات الحل هذه طريقةً آمنةً لنقل المهام ما بين الأصناف، وإنشاء أصناف جديدة وحماية تفاصيل عملية التنفيذ من الوصول العام.<br />
===[[Refactoring/techniques/organizing data|تنظيم البيانات]]===<br />
تساعد تقنيات إعادة التصميم هذه بالتعامل مع البيانات، وتبديل أصناف ذات وظائف كثيرة مكان الأنواع الأساسية (primitives). نتيجة أخرى مهمة نحصل عليها بتطبيق هذه التقنيات هي فك ارتباطات صنف مما يجعل الصنف قابلًا للنقل وإعادة الاستعمال.<br />
===[[Refactoring/techniques/simplifying conditional expressions|تسهيل التعابير الشرطية]]===<br />
تزداد البنية المنطقية للشروط تعقيدًا مع مرور الوقت، لذا هنالك الكثير من التقنيات لمواجهة هذا التعقيد وتسهيله.<br />
<br />
===[[Refactoring/techniques/simplifying method calls|تسهيل استدعاءات التوابع]]===<br />
تجعل التقنيات التي سيشار إليها في هذا القسم استدعاءات التوابع أسهل للفهم والاستيعاب. سيؤدي ذلك بدوره إلى تسهيل الواجهات للتفاعل بين الأصناف.<br />
<br />
===[[Refactoring/techniques/dealing with generalization|التعامل مع التعميم]]===<br />
يملك التجريد (Abstraction) تقنيات إعادة التصميم الخاصة به والمرتبطة بشكل أساسي بوظيفة النقل على طول التسلسل الهرمي لوراثة الصنف (class inheritance hierarchy)، وبإنشاء أصناف وواجهات جديدة، وبتبديل التفويض مكان الوراثة أو العكس. <br />
<br />
== مصادر ==<br />
* [https://refactoring.guru/ صفحة توثيق إعادة التصميم في موقع refactoring.guru]<br />
[[تصنيف:Refactoring]]</div>عاطف-بن-عليhttps://wiki.hsoub.com/index.php?title=React/Topics&diff=28471React/Topics2019-04-25T21:17:54Z<p>عاطف-بن-علي: /* مثال أهلًا بالعالم في React */</p>
<hr />
<div>== [[React/tutorial|الدليل التطبيقي]] ==<br />
دليل تطبيقي شامل لبناء لعبة إكس-أو باستخدام React. لا يفترض هذا الدليل أي معرفة مسبقة بمكتبة React. هذا الدليل مُصمَّم للأشخاص الذين يُفضّلون التعلّم بالممارسة. إن كنت تُفضّل تعلّم المفاهيم من البداية فارجع إلى <nowiki/>[[React/hello world|توثيق React من البداية خطوة بخطوة]]. قد تجد هذا الدليل متكاملًا مع توثيق React.<br />
== تثبيت React ==<br />
<br />
=== [[React/getting started|البدء مع React]] ===<br />
إلقاء نظرة شاملة على توثيق React والمصادر المرتبطة به.<br />
<br />
=== [[React/add react to a website|إضافة React إلى موقع ويب]] ===<br />
تجريب React عبر إضافتها إلى أجزاء صغيرة من موقع ويب (جديد أو موجود مسبقًا) بالإضافة إلى تجريب React مع JSX.<br />
<br />
=== [[React/create a new react app|إنشاء تطبيق React جديد]] ===<br />
شرح بعض سلاسل الأدوات المشهورة في <nowiki/>React التي تساعد في أداء الكثير من المهام الروتينية.<br />
<br />
=== [[React/cdn links|روابط شبكة توزيع المحتوى CDN]] ===<br />
روابط شبكة توزيع المحتوى الخاصّة بمكتبة React للتطوير والإنتاج.<br />
<br />
== المفاهيم الأساسية ==<br />
<br />
=== [[React/hello world|مثال «أهلًا بالعالم» في React]] ===<br />
طريقة تنفيذ مثال «أهلًا بالعالم» في React، مع الحديث عن درجة المعرفة المفترضة في [[JavaScript]] للمتابعة في التوثيق.<br />
<br />
=== [[React/introducing jsx|مقدمة ل JSX]] ===<br />
أهميّة استخدام صياغة JSX وهي عبارة عن امتداد لصياغة [[JavaScript]] ، تُستخدَم مع React لوصف المظهر الذي ينبغي أن تكون عليه واجهة المستخدم.<br />
<br />
=== [[React/rendering elements|تصيير العناصر]] ===<br />
شرح تصيير العناصر إلى DOM وطريقة تحديثها، مع أخذ مثال عن تطبيق الساعة الموقوتة لفهم ذلك.<br />
<br />
=== [[React/components and props|المكونات والخاصيات]] ===<br />
تُتيح لنا المُكوِّنات (Components) تقسيم واجهة المستخدم إلى قطع مُستقِلَّة قابلة لإعادة الاستخدام، والتفكير بكل قطعة على انفراد. تقبل المكوّنات مُدخَلات المستخدم والتي تُدعى الخاصيّات <code>props</code>. تشرح هذه الصفحة الفرق بين مكوّنات الأصناف والدوال وطريقة استخراج وتركيب المكوّنات.<br />
<br />
=== [[React/state and lifecycle|حالة ودورة حياة المكونات]] ===<br />
تتحدّث هذه الصفحة عن حالة المكوّنات وأهميتها من خلال مثال عملي للساعة الموقوتة. مع شرح طريقة استخدام الحالة بشكل صحيح، ومقدمة إلى توابع دورة حياة المكوّنات.<br />
<br />
=== [[React/handling events|معالجة الأحداث في React]] ===<br />
الفرق بين معالجة الأحداث في React ومعالجتها في DOM، وطريقة تمرير وسائط إلى معالجات الأحداث.<br />
<br />
=== [[React/conditional rendering|التصيير الشرطي]] ===<br />
بإمكانك في React إنشاء مُكوِّنات مميّزة تُغلِّف السلوك الذي تريده، ثم بعد ذلك تُصيِّر فقط أجزاء منها اعتمادًا على حالة تطبيقك. يعمل التصيير الشرطي (Conditional Rendering) في React بنفس الطريقة التي تعمل فيها التعابير الشرطيّة في [[JavaScript]]، حيث تستطيع استخدام مُعامِلات [[JavaScript]] مثل if أو المُعامِل الشرطي لإنشاء عناصر تُمثِّل الحالة الحاليّة، ثمّ تدع React تُحدِّث واجهة المستخدم لمُطابقتها.<br />
<br />
=== [[React/lists and keys|القوائم والمفاتيح]] ===<br />
طريقة تصيير مكوّنات متعددة، وأهميّة المفاتيح في معرفة العناصر التي تغيرت، أو أُضيفت، أو أُزيلت.<br />
<br />
=== [[React/forms|الحقول]] ===<br />
طريقة استخدام الحقول (forms) في React والفرق بين طريقة تعريفها في [[HTML]] وطريقة تعريفها في React، مع الحديث عن مفهوم المكوّنات المضبوطة.<br />
<br />
=== [[React/lifting state up|رفع الحالات المشتركة للمستوى الأعلى]] ===<br />
طريقة رفع الحالة المشتركة بين المُكوِّنات مُتعدِّدة التي تعكس نفس البيانات المتغيّرة إلى أقرب عنصر أب مشترك لها، وذلك بتطبيق مثال عن آلة حاسبة تُحوِّل درجة الحرارة بين سيلزيوس وفهرنهايت.<br />
<br />
=== [[React/composition vs inheritance|الفرق بين التركيب والوراثة في React]] ===<br />
أهمية استخدام التركيب في React وشرح هذا المفهوم وأفضليّة استخدامه على استخدام الوراثة.<br />
<br />
=== [[React/thinking in react|أسلوب التفكير في React]] ===<br />
أسلوب التفكير النموذجي أثناء بناء تطبيقات React وذلك بشرح بناء جدول بيانات منتجات قابل للبحث باستخدام React.<br />
<br />
== الدليل المتقدم ==<br />
<br />
=== [[React/jsx in depth|شرح JSX بالتفصيل]] ===<br />
تشرح هذه الصفحة بالتفصيل صياغة JSX وطريقة التعامل مع الخاصيّات <code>props</code> عند استخدام هذه الصياغة واستخدام العناصر الأبناء في JSX.<br />
<br />
=== [[React/static type checking|التحقق من الأنواع الثابتة]] ===<br />
استخدام أدوات التحقق من الأنواع الثابتة مثل Flow و TypeScript للتعرّف على بعض أنواع المشاكل قبل تنفيذ الشيفرة، وتحسين سير عمل المُطوِّر عن طريق إضافة ميّزات مثل الإكمال التلقائي.<br />
<br />
=== [[React/typechecking with proptypes|التحقق من الأنواع باستخدام PropTypes]] ===<br />
استخدام <code>propTypes</code> والتي هي أداة مُضمَّنة في React للتحقّق من الأنواع واكتشاف الأخطاء.<br />
<br />
=== [[React/refs and the dom|استخدام المراجع مع DOM]] ===<br />
أهميّة استخدام المراجع للوصول إلى عقد DOM وعناصر React خارج تدفّق البيانات النموذجي في React.<br />
<br />
=== [[React/uncontrolled components|المكونات غير المضبوطة]] ===<br />
شرح المكوّنات غير المضبوطة التي تسمح لـ DOM بالتعامل مع بيانات الحقول والفرق بينها وبين المكوّنات المضبوطة.<br />
<br />
=== [[React/optimizing performance|تحسين الأداء]] ===<br />
طرق تسريع تطبيقات React لتحسين الأداء.<br />
<br />
=== [[React/react without es6|React بدون ES6]] ===<br />
طريقة استخدام React بدون أصناف ES6، وذلك عن طريق التابع <code>createReactClass()</code>.<br />
<br />
=== [[React/react without jsx|React بدون JSX]] ===<br />
طريقة استخدام React بدون صياغة JSX، وذلك عن طريق استدعاء التابع <code>React.createElement</code>.<br />
<br />
=== [[React/reconciliation|المطابقة (Reconciliation)]] ===<br />
شرح خوارزمية المقارنة في React لتحديد التغييرات الحاصلة وإعادة التصيير لتحديث واجهة المستخدم بحسب تلك التغييرات.<br />
<br />
=== [[React/context|استخدام السياق (Context) في React]] ===<br />
يُزوِّدنا السياق (Context) بطريقة لتمرير البيانات عبر شجرة المُكوّنات بدون الحاجة لتمرير الخاصيّات <code>props</code> يدويًّا من الأعلى للأسفل في كل مستوى.<br />
<br />
=== [[React/fragments|استخدام الأجزاء (Fragments) في React]] ===<br />
طريقة استخدام الأجزاء لكي يُعيد المكوّن عناصر متعددة في React.<br />
<br />
=== [[React/portals|المداخل (Portals) في React]] ===<br />
استخدام المداخل لتصيير المكونات الأبناء إلى عقدة DOM موجودة خارج تسلسل DOM للمكونات الآباء.<br />
<br />
=== [[React/error boundaries|حدود الأخطاء]] ===<br />
تعريف حدود الأخطاء وطريقة استخدامها لالتقاط الأخطاء والتعامل معها في المكوّنات الأبناء لحد الخطأ.<br />
<br />
=== [[React/web components|مكونات الويب]] ===<br />
شرح مفهوم مكوّنات الويب والفرق بينها وبين مكوّنات React.<br />
<br />
=== [[React/higher order components|المكونات ذات الترتيب الأعلى]] ===<br />
المكوّنات ذات الترتيب الأعلى هي تقنية متقدمة في React لإعادة استخدام منطق المكونات. ففي حين أنّ المكوّن الاعتيادي يُحوّل الخاصيّات إلى واجهة مستخدم، يُحوّل المكوّن ذو الترتيب الأعلى مكوّنًا إلى مكوّن آخر. سنناقش في هذه الصفحة الفائدة من المكوّنات ذات الترتيب الأعلى وكيفية كتابتها.<br />
<br />
=== [[React/forwarding refs|تمرير المراجع]] ===<br />
تمرير المراجع هو تقنية لتمرير مرجع <code>ref</code> تلقائيًّا من مكوّن إلى عناصره الأبناء. لا يكون هذا ضروريًّا بشكل نموذجي لمعظم مكوّنات التطبيق، ولكن قد يكون مفيدًا لبعض أنواع المكوّنات، خاصّة مكتبات المكوّنات القابلة لإعادة الاستخدام. سنتحدث في هذه الصفحة عن أشيع الحالات التي نحتاج فيها تمرير المراجع.<br />
<br />
=== [[React/render props|خاصيات التصيير]] ===<br />
يُشير مصطلح خاصيّة التصيير (render prop) إلى تقنية بسيطة لمشاركة الشيفرة بين مكوّنات React باستخدام خاصية والتي قيمتها هي عبارة عن دالة.يأخذ المكوّن الذي يمتلك خاصيّة تصيير دالة تُعيد عنصر React ويستدعيها بدلًا من تنفيذ منطق التصيير الخاص به. سنناقش في هذه الصفحة فائدة خاصيّات التصيير وكيفية كتابة خاصيّات التصيير الخاصّة بك.<br />
<br />
=== [[React/integrating with other libraries|تكامل React مع المكتبات الأخرى]] ===<br />
يمكن استخدام React وتضمينها مع المكتبات الأخرى. سنتحدث في هذه الصفحة عن بعض أشيع الحالات مع التركيز على التكامل مع [https://jquery.com/ jQuery] و [http://backbonejs.org/ Backbone]، ولكن يمكن تطبيق نفس الأفكار لتكامل المكوّنات مع أي شيفرة موجودة حاليًّا.<br />
<br />
=== [[React/accessibility|سهولة الوصول]] ===<br />
الفائدة من سهولة الوصول، والتي هي تصميم وإنشاء مواقع يُمكِن استخدامها من قبل أي شخص. والأدوات المُستخدَمة لتحقيق سهولة الوصول في تطبيقات React.<br />
<br />
=== [[React/code splitting|تقسيم الشيفرة]] ===<br />
شرح طرق تقسيم الشيفرة باستخدام صياغة <code>import()</code> الديناميكية، والمكتبات، وتقسيم الشيفرة المُعتمِد على الطريق. وأهميّة تقسيم الشيفرة في تحسين زمن تحميل الصفحة.<br />
<br />
=== [[React/strict mode|الوضع الصارم (Strict Mode)]] ===<br />
أهمية استخدام الوضع الصارم في التعرف على المكوّنات التي لا تمتلك توابع دورة حياة آمنة، وكشف استخدام واجهة برمجة التطبيقات (API) القديمة للسياق ومراجع السلاسل النصيّة، وكشف التأثيرات الجانبية غير المتوقعة.<br />
<br />
== مرجع إلى واجهة برمجة التطبيق (API) في React ==<br />
<br />
=== [[React/react api|واجهة برمجة التطبيق (API) ذات المستوى الأعلى في React]] ===<br />
مرجع إلى المكوّنات والفرق بين الصنف <code>React.Component</code> والصنف <code>React.PureComponent</code>. وواجهة برمجة التطبيق المستخدمة لإنشاء عناصر React وتحويلها، وإنشاء الأجزاء والمراجع.<br />
<br />
=== [[React/react component|الصنف <code>React.Component</code>]] ===<br />
مرجع مُفصَّل لواجهة برمجة التطبيقات (API) لتعريف صنف مكوّن React.<br />
<br />
=== [[React/react dom|الكائن <code>ReactDOM</code>]] ===<br />
شرح مفصّل لتابع التصيير <code>render</code> وطريقة استخدامه، وتوابع الكائن ReactDOM الأخرى مثل <code>hydrate()</code> و <code>findDOMNode</code>.<br />
<br />
=== [[React/react dom server|الكائن <code>ReactDOMServer</code>]] ===<br />
مرجّع مُفصّل لتوابع الكائن <code>ReactDOMServer</code> والتي تُستخدَم بشكل نموذجي مع خادم NodeJS مثل <code>renderToString()</code> وتوابع أخرى.<br />
<br />
=== [[React/dom elements|عناصر DOM]] ===<br />
الفوارق بين خاصيّات HTML وخاصيّات React. وخاصيّات HTML المدعومة في React.<br />
<br />
=== [[React/events|الأحداث المصطنعة (Synthetic Events)]] ===<br />
شرح مفهوم مُغلِّف الأحداث المصطنعة <code>SyntheticEvent</code> والذي يُشكِّل جزءًا من نظام أحداث React. وأسماء الأحداث المدعومة في React وخاصيّاتها.<br />
<br />
=== [[React/test utils|أدوات الاختبار]] ===<br />
شرح أدوات الاختبار المختلفة في React لتسهيل اختبار المكوّنات.<br />
<br />
=== [[React/shallow renderer|التصيير السطحي]] ===<br />
يُتيح التصيير السطحي (Shallow Rendering) تصيير مكوّن على عمق مستوى واحد وتوضيح الحقائق حول ما يُعيده تابع التصيير، بدون القلق حول سلوك المكوّنات الأبناء التي لم تُصيَّر أو ينشأ عنها نسخة.<br />
<br />
=== [[React/test renderer|مصير الاختبار]] ===<br />
مرجع إلى مُصيِّر الاختبار (Test Renderer) الذي يُمكِن استخدامه لتصيير مكوّنات React إلى كائنات JavaScript نقيّة بدون الاعتماد على DOM أو بيئة الهاتف المحمول الأصليّة.<br />
<br />
=== [[React/javascript environment requirements|متطلبات بيئة JavaScript]] ===<br />
متطلبات البيئة لكي تعمل React بشكل صحيح واستخدام شيفرات داعمة (polyfills) لدعم الإصدارات القديمة من المتصفحات.<br />
<br />
== الخطافات ==<br />
<br />
=== [[React/hooks intro|مدخل إلى الخطافات]] ===<br />
هذه الصفحة هي مدخل إلى الخطافات، إذ سنشرح فيها سبب إضافة الخطافات إلى React وكيف يمكن للخطافات أن تساعدك في كتابة تطبيقات قوية وضخمة.<br />
<br />
=== [[React/hooks overview|لمحة خاطفة عن الخطافات]] ===<br />
توفر هذه الصفحة نظرةً عامةً وسريعةً حول الخطافات لمستخدمي React ذوي الخبرة، إذ تلقي نظرة سريعة على خطاف الحالة وخطاف التأثير وتتطرق باختصار إلى قواعد الخطافات.<br />
<br />
=== [[React/hooks state|استعمال خطاف الحالة]] ===<br />
الخطاف <code>useState</code> هو أحد الخطافات التي توفرها React. في أغلب الأحيان، سنشير إليه بالاسم "خطاف الحالة" (State Hook). يسمح لنا هذا الخطاف بإضافة حالة محلية إلى مكونات دالة في [[React]] بخطوات بسيطة وشيفرة أقل.<br />
<br />
=== [[React/hooks effect|استعمال خطاف التأثير]] ===<br />
الخطاف <code>useEffect</code> يمكِّننا من إحداث تأثيرات جانبية (side effects) في مكون بعد تصييره. قد تتطلب بعض التأثيرات إجراء عملية تنظيف بينما لا يتطلب بعضها الآخر تنفيذ هذه العملية. أي يوحِّد خطاف التأثير كلا هاتين الحالتين في واجهة برمجية واحدة.<br />
<br />
=== [[React/hooks rules|قواعد استعمال الخطافات]] ===<br />
الخطافات هي دوال [[JavaScript]]، ولكن تحتاج إلى اتباع قاعدتين عند استعمالها لتعمل بشكل صحيح. يشرح هذا القسم هاتين القاعدتين بالتفصيل.<br />
<br />
=== [[React/hooks custom|بناء خطاف خاص بك]] ===<br />
بناء خطافات خاصة بك تمكِّنك من استخراج شيفرة من مكون ما إلى دوال قابلة لإعادة الاستعمال. يشرح هذا القسم كيفية إنشاء خطافات مخصصة واستعمالها في React.<br />
<br />
=== [[React/hooks reference|مرجع إلى الواجهة البرمجية للخطافات]] ===<br />
تشرح هذه الصفحة الواجهات البرمجية للخطافات المضمَّنة في React.<br />
<br />
=== [[React/hooks faq|الأسئلة الشائعة حول الخطافات]] ===<br />
تجيب هذه الصفحة عن بعض الأسئلة التي يتكرر طرحها حول <nowiki/>[[React/hooks overview|الخطافات]].<br />
<br />
== الأسئلة الشائعة في React ==<br />
<br />
=== [[React/glossary|المصطلحات]] ===<br />
شرح مفصّل لأهم المصطلحات المستخدمة في React.<br />
<br />
=== [[React/faq ajax|استخدام AJAX مع React]] ===<br />
أسئلة حول إمكانية إجراء استدعاء AJAX في React والمكان الصحيح لاستدعائها ومثال حول ذلك.<br />
<br />
=== [[React/faq build|أسئلة حول Babel و JSX وخطوات بناء التطبيقات]] ===<br />
أسئلة حول استخدام JSX و ES6 مع React وكيفية كتابة التعليقات في JSX.<br />
<br />
=== [[React/faq functions|تمرير الدوال إلى المكونات]] ===<br />
أسئلة حول طريقة تمرير معالجات الأحداث إلى المكوّنات وربط الدالة إلى نسخة المكوّن وأهميّة هذا الربط. وطرق منع استدعاء الدالة بسرعة كبيرة أو مرات عديدة.<br />
<br />
=== [[React/faq state|حالة المكونات]] ===<br />
أسئلة حول مفهوم حالة المكوّنات والفرق بينها وبين الخاصيّات. والسبب الكامن وراء عدم تحديث React لقيمة <code>this.state</code> بشكل متزامن.<br />
<br />
=== [[React/faq styling|التنسيق واستخدام CSS مع React]] ===<br />
أسئلة حول طريقة إضافة CSS إلى المكوّنات وإمكانية استخدام التنسيقات السطرية وإجراء تحريك في React.<br />
<br />
=== [[React/faq structure|بنية ملفات المشروع]] ===<br />
أسئلة حول أشيع الطرق المفضلة لترتيب بنية ملفات المشروع.<br />
<br />
=== [[React/faq versioning|سياسة الإصدارات المتبعة في React]] ===<br />
شرح مفصل للسياسة المتبعة في ترقيم إصدارات React والفروقات بالإضافة إلى الإجابة عن كل شيء يدور حول التغييرات الجذرية في الإصدارات.<br />
<br />
=== [[React/faq internals|DOM الافتراضي والكائنات الداخلية]] ===<br />
أسئلة حول مفهوم DOM الافتراضي والفرق بينه وبين DOM الخيالي.</div>عاطف-بن-عليhttps://wiki.hsoub.com/index.php?title=React&diff=28470React2019-04-25T21:15:07Z<p>عاطف-بن-علي: تصويب كتابة كلمة «دون» بحذف «الباء».</p>
<hr />
<div>React (والتي تُعرَف أيضًا باسم React.js أو ReactJS) هي مكتبة JavaScript تُستخدَم لبناء واجهات المستخدم. تُدار React من شركة Facebook بالإضافة إلى مجتمع كبير من المطورين، فهي مشروعٌ مفتوح المصدر.<br />
<br />
تُسهِّل React عملية إنشاء واجهات مستخدم تفاعليّة. عليك فقط تصميم عروض (views) لكل حالة في تطبيقك، وستُحدِّث React بكفاءة المكوّنات الصحيحة وتُصيّرها عندما تتغير بياناتك.<br />
<br />
تعتمد React بشكل أساسي على مفهوم المكوّنات (Components). حيث يجب عليك بناء مكوّنات مُغلَّفة تُدير حالتها الخاصّة، ومن ثمّ تُركِّب هذه المكوّنات مع بعضها لإنشاء واجهات مستخدم مُعقّدة. ولمّا كان منطق المكوّنات مكتوب باستخدام JavaScript بدلًا من صيغة القوالب، فبإمكانك تمرير الكثير من البيانات عبر تطبيقك بسهولة وإبقاء الحالة بعيدة عن DOM.<br />
<br />
تسير React على مبدأ «تعلّم مرّة واكتب في أي مكان»، إذ لا تفترض تعاملك مع تقنية مُحدّدة، بل تستطيع تطوير ميزات جديدة فيها دون إعادة كتابة شيفرة جديدة. يُمكِن تصيير React على الخادم باستخدام [[Node.js]]، ويُمكن من خلالها إنشاء تطبيقات الهواتف النقالة عبر React Native.<br />
<br />
{{:React/Topics}}<br />
[[تصنيف:React]]</div>عاطف-بن-عليhttps://wiki.hsoub.com/index.php?title=Refactoring&diff=28402Refactoring2019-03-30T22:35:14Z<p>عاطف-بن-علي: استبدال لفظ بسيط (وما اشتق منه) بلفظ سهل (وما اشتق منه).</p>
<hr />
<div><noinclude>{{DISPLAYTITLE:إعادة التصميم (Refactoring)}}</noinclude><br />
تهدف عملية إعادة التصميم (refactoring) للحصول على شيفرة جيّدة سهلة القراءة يسهل تطويرها والتخلُّص من المتطلَّبات التقنيّة الزائدة فيها، وهذا ما يُعرَف بالشيفرة النظيفة (clean code) لأنّ الشيفرة الرديئة لا بُدَّ من انعكاسها سلبًا على نجاح المشروع البرمجيّ.<br />
<br />
== [[Refactoring/what is refactoring|كيف تكون الشيفرة نظيفة؟]] ==<br />
هدف عملية إعادة التصميم (refactoring) هو التخلُّص من المتطلَّبات التقنيّة الزائدة، إذ تحوِّل كلَّ الفوضى المنتشرة في الشيفرة إلى شيفرةٍ نظيفةٍ (clean code) ذات تصميمٍ سهل، وهذا -لا بُدَّ- أمرٌ رائعٌ. من مميزات الشيفرة النظيفة:<br />
* واضحة ومقروءة<br />
* لا تكرار فيها<br />
* بأقل عددٍ ممكنٍ من الأصناف<br />
* تجتاز الاختبارات المختلفة بنجاح<br />
* سهلة ولا تحتاج الصيانة المتكرِّرة<br />
<br />
== [[Refactoring/technical debt|فخ الأعباء التقنية]] ==<br />
يقع الكثير من المبرمجين في فخ الأعباء التقنية وهذا مكلفٌ جدًا إن لم يُعالَج في وقت مبكِّر، ومن أسبابه:<br />
* '''ضغط العمل:''' مما يؤدي لنشر بعض الميّزات (features) قبل الانتهاء منها كلِّيَّا.<br />
* '''التغافل عن عواقب الأعباء التقنيّة:''' لأنّ الأعباء التقنيّة ستحدُّ من سرعة التطوير البرمجيّ.<br />
* '''الفشل بمعالجة الترابط الشديد ما بين المكونات البرمجيّة:''' وذلك عندما يبدو المشروع كتلةً واحدةً بدلًا من وحداتٍ مستقلةٍ.<br />
* '''إهمال إجراء الاختبارات:''' وتكون النتائج حينئذٍ كارثيّة!<br />
* '''صياغة توثيقيّة هزيلة:''' تكون سببًا للكثير من المشاكل لدى المبرمجين الجُدد.<br />
* '''غياب التواصل الفعّال بين أعضاء الفريق:''' كأن يتابع المبرمجون والمطورون العمل وفقًا لمعلوماتٍ وعملياتٍ قديمةٍ من المشروع.<br />
* '''التطوير بعيد الأمد لعدّة فروع بوقتٍ واحدٍ:''' وخاصّة عندما يكون هنالك تغييرات إفراديّة.<br />
* '''تسويف عملية إعادة التصميم (refactoring):''' وهذا يعني زيادة عدد الشيفرات التي سيُعاد العمل عليها مستقبلًا.<br />
* '''لا رقابة للالتزام بالنمط المُوحَّد:''' عندما يكتب كلُّ شخصٍ شيفرةً بحسب نظرته وطريقته الخاصّة.<br />
* '''الإلمام غير الكافي:''' عندما لا يعرف المُطوِّر كيفيّة كتابة شيفرة فعّالةً ومناسبة.<br />
<br />
== [[Refactoring/when|متى نحتاج إعادة التصميم؟]] ==<br />
نحتاج إلى إعادة التصميم:<br />
# '''عند إضافة ميّزةٍ (feature) جديدة''': إذ سيصبح التحكُّم بالشيفرة النظيفة (clean code) أكثر سهولةً، وبالتالي فإنّ إجراء التغييرات سيكون أسهل بكثيرٍ مما كان عليه قبل إعادة التصميم.<br />
# '''عند إصلاح الأخطاء (bugs)''': إذ ستتَّضح الأخطاء بجهدٍ ووقتٍ أقل، وستغني إعادة التصميم المبكِّرة عن الحاجةَ لإعادة التصميم المُخصَّص لاحقًا.<br />
# '''أثناء مراجعة الشيفرة (code review)''': إذ هي الفرصةُ الأخيرة لتوضيب الشيفرة قبل نشرها للعامّة.<br />
<br />
== [[Refactoring/how to|خطوات إعادة التصميم]] ==<br />
تجري عملية إعادة التصميم عبر عدّة خطواتٍ تُحدِث تغييرًا طفيفا تدريجيًّا يجعل الشيفرة (مع كلِّ تغييرٍ) أفضل بقليلٍ، ولكنها لا توثر على أداء وفعاليّة البرنامج وتحافظ على استمرار عمله بشكلٍ سليمٍ، وتتلخص إعادة التصميم بالخطوات الآتية:<br />
* '''الحصول على شيفرةٍ نظيفة'''<br />
* ''' لا مهام وظيفيّة جديدة أثناء إعادة التصميم'''<br />
* '''اجتياز كافة الاختبارات السابقة'''<br />
<br />
=== مثال ===<br />
تفيد عملية إعادة التصميم في تسهيل التعليمات الشرطيّة المعقَّدة وذلك عبر عزل عملياتها في توابع مستقلَّة كما في المثال الآتي.<br />
<br />
==== الشيفرة قبل إعادة التصميم ====<br />
<syntaxhighlight lang="java"><br />
if (date.before(SUMMER_START) || date.after(SUMMER_END)) {<br />
charge = quantity * winterRate + winterServiceCharge;<br />
}<br />
else {<br />
charge = quantity * summerRate;<br />
}<br />
<br />
<br />
</syntaxhighlight><br />
<br />
==== الشيفرة بعد التصميم ====<br />
<syntaxhighlight lang="java"><br />
if (notSummer(date)) {<br />
charge = winterCharge(quantity);<br />
}<br />
else {<br />
charge = summerCharge(quantity);<br />
}<br />
<br />
<br />
</syntaxhighlight><br />
<br />
والفرق واضحٌ ما بين الشيفرتين من ناحية التنظيم (organization) وسهولة كشف الأخطاء (bug detects) وقابليّة القراءة (readability) والصيانة (maintenance).<br />
<br />
== [[Refactoring/smells|مشاكل الشيفرات]] ==<br />
قد تعاني الشيفرات الكثير من الأمراض والعلل الشكلية؛ فبمجرد اكتشاف تلك العلل الظاهرية، يسهل علينا معرفة العلاج (التقنيات) وتطبيقه (إعادة التصميم) للحصول على شيفرة سليمة نظيفة. من هذه العلل:<br />
<br />
=== [[Refactoring/smells/bloaters|المبالغة والإطالة]] ===<br />
قد يزداد حجم الشيفرة ازديادًا كبيرًا ليصل لمرحلةٍ يصعُب التعامل معها، ويبدو هذا التضخم واضحًا.<br />
=== [[Refactoring/smells/oo abusers|الاستخدام الخطأ لمبادئ البرمجة كائنية التوجه (OOP)]] ===<br />
من مشاكل الشيفرات أيضًا التطبيقُ الخطأ وغير المكتمل لمبادئ البرمجة كائنية التوجّه (Object-Oriented).<br />
=== [[Refactoring/smells/change preventers|عرقلة التغيير]] ===<br />
قد يكون تطوير بعض الشيفرات مشكلةً حقيقيةً إذ عند إحداث أيّ تغييرٍ في جزءٍ منها لا بُدَّ وأن تتبعه عدّة تغييراتٍ أخرى في أجزاء متفرِّقة، وبالتالي سيصبح تطوير البرنامج شائكًا معقّدًا وبتكلفةٍ غير زهيدةٍ.<br />
=== [[Refactoring/smells/dispensables|الأجزاء الفائضة]] ===<br />
وهي الأجزاء عديمة النفع في الشيفرة، وسيجعلُ التخلُّصُ منها الشيفرةَ نظيفةً يسيرة الفهم وأكثر فعاليّة.<br />
=== [[Refactoring/smells/couplers|الروابط الازدواجية]] ===<br />
كإنشاء رابطٍ شديدٍ ازدواجيّ (ما بين صنفين [classes])، أو التفويض المفرط (excessive delegation).<br />
<br />
=== [[Refactoring/smells/other smells|مشاكل أخرى]] ===<br />
ستجد في هذا القسم الاختلالات والمشكلات التي لا تنحصر في صنف محدَّد.<br />
<br />
== [[Refactoring/techniques|تقنيات إعادة التصميم]] ==<br />
هنالك العديد من تقنيات إعادة التصميم التي يمكن استعمالها في حالات عديدة. تنقسم هذه التقنيات إلى:<br />
<br />
===[[Refactoring/techniques/composing methods|إنشاء التوابع]]===<br />
تستهدف إعادة التصميم بشكل رئيسيٍّ إنشاء التوابع الصحيحة المناسبة، إذ تكون التوابع الطويلة سببًا للمشاكل في كثيرٍ من الحالات، وتجعل شيفرات بعض التوابع منطق التنفيذ (execution logic) غامضًا ويصبح التابع بهذا عصيَّ الفهم من جهةٍ وصعب التغييرٍ من جهة ثانية.<br />
<br />
يشمل هذا القسم من الحلول كلَّ ما يتعلق بالتوابع وإزالة التكرار (duplicates) في الشيفرة ليسمح بإجراء التطويرات المستقبليّة.<br />
===[[Refactoring/techniques/moving features between objects|نقل الميزات ما بين الكائنات]]===<br />
تساعد عملية إعادة التصميم في توزيع المهام بشكل مثاليّ على الأصناف المختلفة في الشيفرة، وتضمن تقنيات الحل هذه طريقةً آمنةً لنقل المهام ما بين الأصناف، وإنشاء أصناف جديدة وحماية تفاصيل عملية التنفيذ من الوصول العام.<br />
===[[Refactoring/techniques/organizing data|تنظيم البيانات]]===<br />
تساعد تقنيات إعادة التصميم هذه بالتعامل مع البيانات، وتبديل أصناف ذات وظائف كثيرة مكان الأنواع الأساسية (primitives). نتيجة أخرى مهمة نحصل عليها بتطبيق هذه التقنيات هي فك ارتباطات صنف مما يجعل الصنف قابلًا للنقل وإعادة الاستعمال.<br />
===[[Refactoring/techniques/simplifying conditional expressions|تسهيل التعابير الشرطية]]===<br />
تزداد البنية المنطقية للشروط تعقيدًا مع مرور الوقت، لذا هنالك الكثير من التقنيات لمواجهة هذا التعقيد وتسهيله.<br />
<br />
===[[Refactoring/techniques/simplifying method calls|تسهيل استدعاءات التوابع]]===<br />
تجعل التقنيات التي سيشار إليها في هذا القسم استدعاءات التوابع أسهل للفهم والاستيعاب. سيؤدي ذلك بدوره إلى تسهيل الواجهات للتفاعل بين الأصناف.<br />
<br />
===[[Refactoring/techniques/dealing with generalization|التعامل مع التعميم]]===<br />
يملك التجريد (Abstraction) تقنيات إعادة التصميم الخاصة به والمرتبطة بشكل أساسي بوظيفة النقل على طول التسلسل الهرمي لوراثة الصنف (class inheritance hierarchy)، وبإنشاء أصناف وواجهات جديدة، وبتبديل التفويض مكان الوراثة أو العكس. <br />
<br />
== مصادر ==<br />
* [https://refactoring.guru/ صفحة توثيق إعادة التصميم في موقع refactoring.guru]<br />
[[تصنيف:Refactoring]]</div>عاطف-بن-عليhttps://wiki.hsoub.com/index.php?title=Refactoring&diff=28401Refactoring2019-03-30T22:30:14Z<p>عاطف-بن-علي: استبدال لفظ تبسيط بتسهيل.</p>
<hr />
<div><noinclude>{{DISPLAYTITLE:إعادة التصميم (Refactoring)}}</noinclude><br />
تهدف عملية إعادة التصميم (refactoring) للحصول على شيفرة جيّدة سهلة القراءة يسهل تطويرها والتخلُّص من المتطلَّبات التقنيّة الزائدة فيها، وهذا ما يُعرَف بالشيفرة النظيفة (clean code) لأنّ الشيفرة الرديئة لا بُدَّ من انعكاسها سلبًا على نجاح المشروع البرمجيّ.<br />
<br />
== [[Refactoring/what is refactoring|كيف تكون الشيفرة نظيفة؟]] ==<br />
هدف عملية إعادة التصميم (refactoring) هو التخلُّص من المتطلَّبات التقنيّة الزائدة، إذ تحوِّل كلَّ الفوضى المنتشرة في الشيفرة إلى شيفرةٍ نظيفةٍ (clean code) ذات تصميمٍ سهل، وهذا -لا بُدَّ- أمرٌ رائعٌ. من مميزات الشيفرة النظيفة:<br />
* واضحة ومقروءة<br />
* لا تكرار فيها<br />
* بأقل عددٍ ممكنٍ من الأصناف<br />
* تجتاز الاختبارات المختلفة بنجاح<br />
* سهلة ولا تحتاج الصيانة المتكرِّرة<br />
<br />
== [[Refactoring/technical debt|فخ الأعباء التقنية]] ==<br />
يقع الكثير من المبرمجين في فخ الأعباء التقنية وهذا مكلفٌ جدًا إن لم يُعالَج في وقت مبكِّر، ومن أسبابه:<br />
* '''ضغط العمل:''' مما يؤدي لنشر بعض الميّزات (features) قبل الانتهاء منها كلِّيَّا.<br />
* '''التغافل عن عواقب الأعباء التقنيّة:''' لأنّ الأعباء التقنيّة ستحدُّ من سرعة التطوير البرمجيّ.<br />
* '''الفشل بمعالجة الترابط الشديد ما بين المكونات البرمجيّة:''' وذلك عندما يبدو المشروع كتلةً واحدةً بدلًا من وحداتٍ مستقلةٍ.<br />
* '''إهمال إجراء الاختبارات:''' وتكون النتائج حينئذٍ كارثيّة!<br />
* '''صياغة توثيقيّة هزيلة:''' تكون سببًا للكثير من المشاكل لدى المبرمجين الجُدد.<br />
* '''غياب التواصل الفعّال بين أعضاء الفريق:''' كأن يتابع المبرمجون والمطورون العمل وفقًا لمعلوماتٍ وعملياتٍ قديمةٍ من المشروع.<br />
* '''التطوير بعيد الأمد لعدّة فروع بوقتٍ واحدٍ:''' وخاصّة عندما يكون هنالك تغييرات إفراديّة.<br />
* '''تسويف عملية إعادة التصميم (refactoring):''' وهذا يعني زيادة عدد الشيفرات التي سيُعاد العمل عليها مستقبلًا.<br />
* '''لا رقابة للالتزام بالنمط المُوحَّد:''' عندما يكتب كلُّ شخصٍ شيفرةً بحسب نظرته وطريقته الخاصّة.<br />
* '''الإلمام غير الكافي:''' عندما لا يعرف المُطوِّر كيفيّة كتابة شيفرة فعّالةً ومناسبة.<br />
<br />
== [[Refactoring/when|متى نحتاج إعادة التصميم؟]] ==<br />
نحتاج إلى إعادة التصميم:<br />
# '''عند إضافة ميّزةٍ (feature) جديدة''': إذ سيصبح التحكُّم بالشيفرة النظيفة (clean code) أكثر سهولةً، وبالتالي فإنّ إجراء التغييرات سيكون أسهل بكثيرٍ مما كان عليه قبل إعادة التصميم.<br />
# '''عند إصلاح الأخطاء (bugs)''': إذ ستتَّضح الأخطاء بجهدٍ ووقتٍ أقل، وستغني إعادة التصميم المبكِّرة عن الحاجةَ لإعادة التصميم المُخصَّص لاحقًا.<br />
# '''أثناء مراجعة الشيفرة (code review)''': إذ هي الفرصةُ الأخيرة لتوضيب الشيفرة قبل نشرها للعامّة.<br />
<br />
== [[Refactoring/how to|خطوات إعادة التصميم]] ==<br />
تجري عملية إعادة التصميم عبر عدّة خطواتٍ تُحدِث تغييرًا طفيفا تدريجيًّا يجعل الشيفرة (مع كلِّ تغييرٍ) أفضل بقليلٍ، ولكنها لا توثر على أداء وفعاليّة البرنامج وتحافظ على استمرار عمله بشكلٍ سليمٍ، وتتلخص إعادة التصميم بالخطوات الآتية:<br />
* '''الحصول على شيفرةٍ نظيفة'''<br />
* ''' لا مهام وظيفيّة جديدة أثناء إعادة التصميم'''<br />
* '''اجتياز كافة الاختبارات السابقة'''<br />
<br />
=== مثال ===<br />
تفيد عملية إعادة التصميم في تسهيل التعليمات الشرطيّة المعقَّدة وذلك عبر عزل عملياتها في توابع مستقلَّة كما في المثال الآتي.<br />
<br />
==== الشيفرة قبل إعادة التصميم ====<br />
<syntaxhighlight lang="java"><br />
if (date.before(SUMMER_START) || date.after(SUMMER_END)) {<br />
charge = quantity * winterRate + winterServiceCharge;<br />
}<br />
else {<br />
charge = quantity * summerRate;<br />
}<br />
<br />
<br />
</syntaxhighlight><br />
<br />
==== الشيفرة بعد التصميم ====<br />
<syntaxhighlight lang="java"><br />
if (notSummer(date)) {<br />
charge = winterCharge(quantity);<br />
}<br />
else {<br />
charge = summerCharge(quantity);<br />
}<br />
<br />
<br />
</syntaxhighlight><br />
<br />
والفرق واضحٌ ما بين الشيفرتين من ناحية التنظيم (organization) وسهولة كشف الأخطاء (bug detects) وقابليّة القراءة (readability) والصيانة (maintenance).<br />
<br />
== [[Refactoring/smells|مشاكل الشيفرات]] ==<br />
قد تعاني الشيفرات الكثير من الأمراض والعلل الشكلية؛ فبمجرد اكتشاف تلك العلل الظاهرية، يسهل علينا معرفة العلاج (التقنيات) وتطبيقه (إعادة التصميم) للحصول على شيفرة سليمة نظيفة. من هذه العلل:<br />
<br />
=== [[Refactoring/smells/bloaters|المبالغة والإطالة]] ===<br />
قد يزداد حجم الشيفرة ازديادًا كبيرًا ليصل لمرحلةٍ يصعُب التعامل معها، ويبدو هذا التضخم واضحًا.<br />
=== [[Refactoring/smells/oo abusers|الاستخدام الخطأ لمبادئ البرمجة كائنية التوجه (OOP)]] ===<br />
من مشاكل الشيفرات أيضًا التطبيقُ الخطأ وغير المكتمل لمبادئ البرمجة كائنية التوجّه (Object-Oriented).<br />
=== [[Refactoring/smells/change preventers|عرقلة التغيير]] ===<br />
قد يكون تطوير بعض الشيفرات مشكلةً حقيقيةً إذ عند إحداث أيّ تغييرٍ في جزءٍ منها لا بُدَّ وأن تتبعه عدّة تغييراتٍ أخرى في أجزاء متفرِّقة، وبالتالي سيصبح تطوير البرنامج شائكًا معقّدًا وبتكلفةٍ غير زهيدةٍ.<br />
=== [[Refactoring/smells/dispensables|الأجزاء الفائضة]] ===<br />
وهي الأجزاء عديمة النفع في الشيفرة، وسيجعلُ التخلُّصُ منها الشيفرةَ نظيفةً يسيرة الفهم وأكثر فعاليّة.<br />
=== [[Refactoring/smells/couplers|الروابط الازدواجية]] ===<br />
كإنشاء رابطٍ شديدٍ ازدواجيّ (ما بين صنفين [classes])، أو التفويض المفرط (excessive delegation).<br />
<br />
=== [[Refactoring/smells/other smells|مشاكل أخرى]] ===<br />
ستجد في هذا القسم الاختلالات والمشكلات التي لا تنحصر في صنف محدَّد.<br />
<br />
== [[Refactoring/techniques|تقنيات إعادة التصميم]] ==<br />
هنالك العديد من تقنيات إعادة التصميم التي يمكن استعمالها في حالات عديدة. تنقسم هذه التقنيات إلى:<br />
<br />
===[[Refactoring/techniques/composing methods|إنشاء التوابع]]===<br />
تستهدف إعادة التصميم بشكل رئيسيٍّ إنشاء التوابع الصحيحة المناسبة، إذ تكون التوابع الطويلة سببًا للمشاكل في كثيرٍ من الحالات، وتجعل شيفرات بعض التوابع منطق التنفيذ (execution logic) غامضًا ويصبح التابع بهذا عصيَّ الفهم من جهةٍ وصعب التغييرٍ من جهة ثانية.<br />
<br />
يشمل هذا القسم من الحلول كلَّ ما يتعلق بالتوابع وإزالة التكرار (duplicates) في الشيفرة ليسمح بإجراء التطويرات المستقبليّة.<br />
===[[Refactoring/techniques/moving features between objects|نقل الميزات ما بين الكائنات]]===<br />
تساعد عملية إعادة التصميم في توزيع المهام بشكل مثاليّ على الأصناف المختلفة في الشيفرة، وتضمن تقنيات الحل هذه طريقةً آمنةً لنقل المهام ما بين الأصناف، وإنشاء أصناف جديدة وحماية تفاصيل عملية التنفيذ من الوصول العام.<br />
===[[Refactoring/techniques/organizing data|تنظيم البيانات]]===<br />
تساعد تقنيات إعادة التصميم هذه بالتعامل مع البيانات، وتبديل أصناف ذات وظائف كثيرة مكان الأنواع الأساسية (primitives). نتيجة أخرى مهمة نحصل عليها بتطبيق هذه التقنيات هي فك ارتباطات صنف مما يجعل الصنف قابلًا للنقل وإعادة الاستعمال.<br />
===[[Refactoring/techniques/simplifying conditional expressions|تبسيط التعابير الشرطية]]===<br />
تزداد البنية المنطقية للشروط تعقيدًا مع مرور الوقت، لذا هنالك الكثير من التقنيات لمواجهة هذا التعقيد وتبسيطه.<br />
<br />
===[[Refactoring/techniques/simplifying method calls|تبسيط استدعاءات التوابع]]===<br />
تجعل التقنيات التي سيشار إليها في هذا القسم استدعاءات التوابع أبسط وأسهل للفهم والاستيعاب. سيؤدي ذلك بدوره إلى تبسيط الواجهات للتفاعل بين الأصناف.<br />
<br />
===[[Refactoring/techniques/dealing with generalization|التعامل مع التعميم]]===<br />
يملك التجريد (Abstraction) تقنيات إعادة التصميم الخاصة به والمرتبطة بشكل أساسي بوظيفة النقل على طول التسلسل الهرمي لوراثة الصنف (class inheritance hierarchy)، وبإنشاء أصناف وواجهات جديدة، وبتبديل التفويض مكان الوراثة أو العكس. <br />
<br />
== مصادر ==<br />
* [https://refactoring.guru/ صفحة توثيق إعادة التصميم في موقع refactoring.guru]<br />
[[تصنيف:Refactoring]]</div>عاطف-بن-عليhttps://wiki.hsoub.com/index.php?title=Refactoring&diff=28400Refactoring2019-03-30T22:28:54Z<p>عاطف-بن-علي: استبدال لفظة بسيط بطفيف، لأن البساطة في اللغة العربية هي الامتداد (ومنه يقال للأرض الممتدة بسيطة).</p>
<hr />
<div><noinclude>{{DISPLAYTITLE:إعادة التصميم (Refactoring)}}</noinclude><br />
تهدف عملية إعادة التصميم (refactoring) للحصول على شيفرة جيّدة سهلة القراءة يسهل تطويرها والتخلُّص من المتطلَّبات التقنيّة الزائدة فيها، وهذا ما يُعرَف بالشيفرة النظيفة (clean code) لأنّ الشيفرة الرديئة لا بُدَّ من انعكاسها سلبًا على نجاح المشروع البرمجيّ.<br />
<br />
== [[Refactoring/what is refactoring|كيف تكون الشيفرة نظيفة؟]] ==<br />
هدف عملية إعادة التصميم (refactoring) هو التخلُّص من المتطلَّبات التقنيّة الزائدة، إذ تحوِّل كلَّ الفوضى المنتشرة في الشيفرة إلى شيفرةٍ نظيفةٍ (clean code) ذات تصميمٍ سهل، وهذا -لا بُدَّ- أمرٌ رائعٌ. من مميزات الشيفرة النظيفة:<br />
* واضحة ومقروءة<br />
* لا تكرار فيها<br />
* بأقل عددٍ ممكنٍ من الأصناف<br />
* تجتاز الاختبارات المختلفة بنجاح<br />
* سهلة ولا تحتاج الصيانة المتكرِّرة<br />
<br />
== [[Refactoring/technical debt|فخ الأعباء التقنية]] ==<br />
يقع الكثير من المبرمجين في فخ الأعباء التقنية وهذا مكلفٌ جدًا إن لم يُعالَج في وقت مبكِّر، ومن أسبابه:<br />
* '''ضغط العمل:''' مما يؤدي لنشر بعض الميّزات (features) قبل الانتهاء منها كلِّيَّا.<br />
* '''التغافل عن عواقب الأعباء التقنيّة:''' لأنّ الأعباء التقنيّة ستحدُّ من سرعة التطوير البرمجيّ.<br />
* '''الفشل بمعالجة الترابط الشديد ما بين المكونات البرمجيّة:''' وذلك عندما يبدو المشروع كتلةً واحدةً بدلًا من وحداتٍ مستقلةٍ.<br />
* '''إهمال إجراء الاختبارات:''' وتكون النتائج حينئذٍ كارثيّة!<br />
* '''صياغة توثيقيّة هزيلة:''' تكون سببًا للكثير من المشاكل لدى المبرمجين الجُدد.<br />
* '''غياب التواصل الفعّال بين أعضاء الفريق:''' كأن يتابع المبرمجون والمطورون العمل وفقًا لمعلوماتٍ وعملياتٍ قديمةٍ من المشروع.<br />
* '''التطوير بعيد الأمد لعدّة فروع بوقتٍ واحدٍ:''' وخاصّة عندما يكون هنالك تغييرات إفراديّة.<br />
* '''تسويف عملية إعادة التصميم (refactoring):''' وهذا يعني زيادة عدد الشيفرات التي سيُعاد العمل عليها مستقبلًا.<br />
* '''لا رقابة للالتزام بالنمط المُوحَّد:''' عندما يكتب كلُّ شخصٍ شيفرةً بحسب نظرته وطريقته الخاصّة.<br />
* '''الإلمام غير الكافي:''' عندما لا يعرف المُطوِّر كيفيّة كتابة شيفرة فعّالةً ومناسبة.<br />
<br />
== [[Refactoring/when|متى نحتاج إعادة التصميم؟]] ==<br />
نحتاج إلى إعادة التصميم:<br />
# '''عند إضافة ميّزةٍ (feature) جديدة''': إذ سيصبح التحكُّم بالشيفرة النظيفة (clean code) أكثر سهولةً، وبالتالي فإنّ إجراء التغييرات سيكون أسهل بكثيرٍ مما كان عليه قبل إعادة التصميم.<br />
# '''عند إصلاح الأخطاء (bugs)''': إذ ستتَّضح الأخطاء بجهدٍ ووقتٍ أقل، وستغني إعادة التصميم المبكِّرة عن الحاجةَ لإعادة التصميم المُخصَّص لاحقًا.<br />
# '''أثناء مراجعة الشيفرة (code review)''': إذ هي الفرصةُ الأخيرة لتوضيب الشيفرة قبل نشرها للعامّة.<br />
<br />
== [[Refactoring/how to|خطوات إعادة التصميم]] ==<br />
تجري عملية إعادة التصميم عبر عدّة خطواتٍ تُحدِث تغييرًا طفيفا تدريجيًّا يجعل الشيفرة (مع كلِّ تغييرٍ) أفضل بقليلٍ، ولكنها لا توثر على أداء وفعاليّة البرنامج وتحافظ على استمرار عمله بشكلٍ سليمٍ، وتتلخص إعادة التصميم بالخطوات الآتية:<br />
* '''الحصول على شيفرةٍ نظيفة'''<br />
* ''' لا مهام وظيفيّة جديدة أثناء إعادة التصميم'''<br />
* '''اجتياز كافة الاختبارات السابقة'''<br />
<br />
=== مثال ===<br />
تفيد عملية إعادة التصميم في تبسيط التعليمات الشرطيّة المعقَّدة وذلك عبر عزل عملياتها في توابع مستقلَّة كما في المثال الآتي.<br />
<br />
==== الشيفرة قبل إعادة التصميم ====<br />
<syntaxhighlight lang="java"><br />
if (date.before(SUMMER_START) || date.after(SUMMER_END)) {<br />
charge = quantity * winterRate + winterServiceCharge;<br />
}<br />
else {<br />
charge = quantity * summerRate;<br />
}<br />
<br />
<br />
</syntaxhighlight><br />
<br />
==== الشيفرة بعد التصميم ====<br />
<syntaxhighlight lang="java"><br />
if (notSummer(date)) {<br />
charge = winterCharge(quantity);<br />
}<br />
else {<br />
charge = summerCharge(quantity);<br />
}<br />
<br />
<br />
</syntaxhighlight><br />
<br />
والفرق واضحٌ ما بين الشيفرتين من ناحية التنظيم (organization) وسهولة كشف الأخطاء (bug detects) وقابليّة القراءة (readability) والصيانة (maintenance).<br />
<br />
== [[Refactoring/smells|مشاكل الشيفرات]] ==<br />
قد تعاني الشيفرات الكثير من الأمراض والعلل الشكلية؛ فبمجرد اكتشاف تلك العلل الظاهرية، يسهل علينا معرفة العلاج (التقنيات) وتطبيقه (إعادة التصميم) للحصول على شيفرة سليمة نظيفة. من هذه العلل:<br />
<br />
=== [[Refactoring/smells/bloaters|المبالغة والإطالة]] ===<br />
قد يزداد حجم الشيفرة ازديادًا كبيرًا ليصل لمرحلةٍ يصعُب التعامل معها، ويبدو هذا التضخم واضحًا.<br />
=== [[Refactoring/smells/oo abusers|الاستخدام الخطأ لمبادئ البرمجة كائنية التوجه (OOP)]] ===<br />
من مشاكل الشيفرات أيضًا التطبيقُ الخطأ وغير المكتمل لمبادئ البرمجة كائنية التوجّه (Object-Oriented).<br />
=== [[Refactoring/smells/change preventers|عرقلة التغيير]] ===<br />
قد يكون تطوير بعض الشيفرات مشكلةً حقيقيةً إذ عند إحداث أيّ تغييرٍ في جزءٍ منها لا بُدَّ وأن تتبعه عدّة تغييراتٍ أخرى في أجزاء متفرِّقة، وبالتالي سيصبح تطوير البرنامج شائكًا معقّدًا وبتكلفةٍ غير زهيدةٍ.<br />
=== [[Refactoring/smells/dispensables|الأجزاء الفائضة]] ===<br />
وهي الأجزاء عديمة النفع في الشيفرة، وسيجعلُ التخلُّصُ منها الشيفرةَ نظيفةً يسيرة الفهم وأكثر فعاليّة.<br />
=== [[Refactoring/smells/couplers|الروابط الازدواجية]] ===<br />
كإنشاء رابطٍ شديدٍ ازدواجيّ (ما بين صنفين [classes])، أو التفويض المفرط (excessive delegation).<br />
<br />
=== [[Refactoring/smells/other smells|مشاكل أخرى]] ===<br />
ستجد في هذا القسم الاختلالات والمشكلات التي لا تنحصر في صنف محدَّد.<br />
<br />
== [[Refactoring/techniques|تقنيات إعادة التصميم]] ==<br />
هنالك العديد من تقنيات إعادة التصميم التي يمكن استعمالها في حالات عديدة. تنقسم هذه التقنيات إلى:<br />
<br />
===[[Refactoring/techniques/composing methods|إنشاء التوابع]]===<br />
تستهدف إعادة التصميم بشكل رئيسيٍّ إنشاء التوابع الصحيحة المناسبة، إذ تكون التوابع الطويلة سببًا للمشاكل في كثيرٍ من الحالات، وتجعل شيفرات بعض التوابع منطق التنفيذ (execution logic) غامضًا ويصبح التابع بهذا عصيَّ الفهم من جهةٍ وصعب التغييرٍ من جهة ثانية.<br />
<br />
يشمل هذا القسم من الحلول كلَّ ما يتعلق بالتوابع وإزالة التكرار (duplicates) في الشيفرة ليسمح بإجراء التطويرات المستقبليّة.<br />
===[[Refactoring/techniques/moving features between objects|نقل الميزات ما بين الكائنات]]===<br />
تساعد عملية إعادة التصميم في توزيع المهام بشكل مثاليّ على الأصناف المختلفة في الشيفرة، وتضمن تقنيات الحل هذه طريقةً آمنةً لنقل المهام ما بين الأصناف، وإنشاء أصناف جديدة وحماية تفاصيل عملية التنفيذ من الوصول العام.<br />
===[[Refactoring/techniques/organizing data|تنظيم البيانات]]===<br />
تساعد تقنيات إعادة التصميم هذه بالتعامل مع البيانات، وتبديل أصناف ذات وظائف كثيرة مكان الأنواع الأساسية (primitives). نتيجة أخرى مهمة نحصل عليها بتطبيق هذه التقنيات هي فك ارتباطات صنف مما يجعل الصنف قابلًا للنقل وإعادة الاستعمال.<br />
===[[Refactoring/techniques/simplifying conditional expressions|تبسيط التعابير الشرطية]]===<br />
تزداد البنية المنطقية للشروط تعقيدًا مع مرور الوقت، لذا هنالك الكثير من التقنيات لمواجهة هذا التعقيد وتبسيطه.<br />
<br />
===[[Refactoring/techniques/simplifying method calls|تبسيط استدعاءات التوابع]]===<br />
تجعل التقنيات التي سيشار إليها في هذا القسم استدعاءات التوابع أبسط وأسهل للفهم والاستيعاب. سيؤدي ذلك بدوره إلى تبسيط الواجهات للتفاعل بين الأصناف.<br />
<br />
===[[Refactoring/techniques/dealing with generalization|التعامل مع التعميم]]===<br />
يملك التجريد (Abstraction) تقنيات إعادة التصميم الخاصة به والمرتبطة بشكل أساسي بوظيفة النقل على طول التسلسل الهرمي لوراثة الصنف (class inheritance hierarchy)، وبإنشاء أصناف وواجهات جديدة، وبتبديل التفويض مكان الوراثة أو العكس. <br />
<br />
== مصادر ==<br />
* [https://refactoring.guru/ صفحة توثيق إعادة التصميم في موقع refactoring.guru]<br />
[[تصنيف:Refactoring]]</div>عاطف-بن-عليhttps://wiki.hsoub.com/index.php?title=Refactoring&diff=28399Refactoring2019-03-30T22:25:04Z<p>عاطف-بن-علي: /* كيف تكون الشيفرة نظيفة؟ */</p>
<hr />
<div><noinclude>{{DISPLAYTITLE:إعادة التصميم (Refactoring)}}</noinclude><br />
تهدف عملية إعادة التصميم (refactoring) للحصول على شيفرة جيّدة سهلة القراءة يسهل تطويرها والتخلُّص من المتطلَّبات التقنيّة الزائدة فيها، وهذا ما يُعرَف بالشيفرة النظيفة (clean code) لأنّ الشيفرة الرديئة لا بُدَّ من انعكاسها سلبًا على نجاح المشروع البرمجيّ.<br />
<br />
== [[Refactoring/what is refactoring|كيف تكون الشيفرة نظيفة؟]] ==<br />
هدف عملية إعادة التصميم (refactoring) هو التخلُّص من المتطلَّبات التقنيّة الزائدة، إذ تحوِّل كلَّ الفوضى المنتشرة في الشيفرة إلى شيفرةٍ نظيفةٍ (clean code) ذات تصميمٍ سهل، وهذا -لا بُدَّ- أمرٌ رائعٌ. من مميزات الشيفرة النظيفة:<br />
* واضحة ومقروءة<br />
* لا تكرار فيها<br />
* بأقل عددٍ ممكنٍ من الأصناف<br />
* تجتاز الاختبارات المختلفة بنجاح<br />
* سهلة ولا تحتاج الصيانة المتكرِّرة<br />
<br />
== [[Refactoring/technical debt|فخ الأعباء التقنية]] ==<br />
يقع الكثير من المبرمجين في فخ الأعباء التقنية وهذا مكلفٌ جدًا إن لم يُعالَج في وقت مبكِّر، ومن أسبابه:<br />
* '''ضغط العمل:''' مما يؤدي لنشر بعض الميّزات (features) قبل الانتهاء منها كلِّيَّا.<br />
* '''التغافل عن عواقب الأعباء التقنيّة:''' لأنّ الأعباء التقنيّة ستحدُّ من سرعة التطوير البرمجيّ.<br />
* '''الفشل بمعالجة الترابط الشديد ما بين المكونات البرمجيّة:''' وذلك عندما يبدو المشروع كتلةً واحدةً بدلًا من وحداتٍ مستقلةٍ.<br />
* '''إهمال إجراء الاختبارات:''' وتكون النتائج حينئذٍ كارثيّة!<br />
* '''صياغة توثيقيّة هزيلة:''' تكون سببًا للكثير من المشاكل لدى المبرمجين الجُدد.<br />
* '''غياب التواصل الفعّال بين أعضاء الفريق:''' كأن يتابع المبرمجون والمطورون العمل وفقًا لمعلوماتٍ وعملياتٍ قديمةٍ من المشروع.<br />
* '''التطوير بعيد الأمد لعدّة فروع بوقتٍ واحدٍ:''' وخاصّة عندما يكون هنالك تغييرات إفراديّة.<br />
* '''تسويف عملية إعادة التصميم (refactoring):''' وهذا يعني زيادة عدد الشيفرات التي سيُعاد العمل عليها مستقبلًا.<br />
* '''لا رقابة للالتزام بالنمط المُوحَّد:''' عندما يكتب كلُّ شخصٍ شيفرةً بحسب نظرته وطريقته الخاصّة.<br />
* '''الإلمام غير الكافي:''' عندما لا يعرف المُطوِّر كيفيّة كتابة شيفرة فعّالةً ومناسبة.<br />
<br />
== [[Refactoring/when|متى نحتاج إعادة التصميم؟]] ==<br />
نحتاج إلى إعادة التصميم:<br />
# '''عند إضافة ميّزةٍ (feature) جديدة''': إذ سيصبح التحكُّم بالشيفرة النظيفة (clean code) أكثر سهولةً، وبالتالي فإنّ إجراء التغييرات سيكون أسهل بكثيرٍ مما كان عليه قبل إعادة التصميم.<br />
# '''عند إصلاح الأخطاء (bugs)''': إذ ستتَّضح الأخطاء بجهدٍ ووقتٍ أقل، وستغني إعادة التصميم المبكِّرة عن الحاجةَ لإعادة التصميم المُخصَّص لاحقًا.<br />
# '''أثناء مراجعة الشيفرة (code review)''': إذ هي الفرصةُ الأخيرة لتوضيب الشيفرة قبل نشرها للعامّة.<br />
<br />
== [[Refactoring/how to|خطوات إعادة التصميم]] ==<br />
تجري عملية إعادة التصميم عبر عدّة خطواتٍ تُحدِث تغييرًا بسيطًا تدريجيًّا يجعل الشيفرة (مع كلِّ تغييرٍ) أفضل بقليلٍ، ولكنها لا توثر على أداء وفعاليّة البرنامج وتحافظ على استمرار عمله بشكلٍ سليمٍ، وتتلخص إعادة التصميم بالخطوات الآتية:<br />
* '''الحصول على شيفرةٍ نظيفة'''<br />
* ''' لا مهام وظيفيّة جديدة أثناء إعادة التصميم'''<br />
* '''اجتياز كافة الاختبارات السابقة'''<br />
<br />
=== مثال ===<br />
تفيد عملية إعادة التصميم في تبسيط التعليمات الشرطيّة المعقَّدة وذلك عبر عزل عملياتها في توابع مستقلَّة كما في المثال الآتي.<br />
<br />
==== الشيفرة قبل إعادة التصميم ====<br />
<syntaxhighlight lang="java"><br />
if (date.before(SUMMER_START) || date.after(SUMMER_END)) {<br />
charge = quantity * winterRate + winterServiceCharge;<br />
}<br />
else {<br />
charge = quantity * summerRate;<br />
}<br />
<br />
<br />
</syntaxhighlight><br />
<br />
==== الشيفرة بعد التصميم ====<br />
<syntaxhighlight lang="java"><br />
if (notSummer(date)) {<br />
charge = winterCharge(quantity);<br />
}<br />
else {<br />
charge = summerCharge(quantity);<br />
}<br />
<br />
<br />
</syntaxhighlight><br />
<br />
والفرق واضحٌ ما بين الشيفرتين من ناحية التنظيم (organization) وسهولة كشف الأخطاء (bug detects) وقابليّة القراءة (readability) والصيانة (maintenance).<br />
<br />
== [[Refactoring/smells|مشاكل الشيفرات]] ==<br />
قد تعاني الشيفرات الكثير من الأمراض والعلل الشكلية؛ فبمجرد اكتشاف تلك العلل الظاهرية، يسهل علينا معرفة العلاج (التقنيات) وتطبيقه (إعادة التصميم) للحصول على شيفرة سليمة نظيفة. من هذه العلل:<br />
<br />
=== [[Refactoring/smells/bloaters|المبالغة والإطالة]] ===<br />
قد يزداد حجم الشيفرة ازديادًا كبيرًا ليصل لمرحلةٍ يصعُب التعامل معها، ويبدو هذا التضخم واضحًا.<br />
=== [[Refactoring/smells/oo abusers|الاستخدام الخطأ لمبادئ البرمجة كائنية التوجه (OOP)]] ===<br />
من مشاكل الشيفرات أيضًا التطبيقُ الخطأ وغير المكتمل لمبادئ البرمجة كائنية التوجّه (Object-Oriented).<br />
=== [[Refactoring/smells/change preventers|عرقلة التغيير]] ===<br />
قد يكون تطوير بعض الشيفرات مشكلةً حقيقيةً إذ عند إحداث أيّ تغييرٍ في جزءٍ منها لا بُدَّ وأن تتبعه عدّة تغييراتٍ أخرى في أجزاء متفرِّقة، وبالتالي سيصبح تطوير البرنامج شائكًا معقّدًا وبتكلفةٍ غير زهيدةٍ.<br />
=== [[Refactoring/smells/dispensables|الأجزاء الفائضة]] ===<br />
وهي الأجزاء عديمة النفع في الشيفرة، وسيجعلُ التخلُّصُ منها الشيفرةَ نظيفةً يسيرة الفهم وأكثر فعاليّة.<br />
=== [[Refactoring/smells/couplers|الروابط الازدواجية]] ===<br />
كإنشاء رابطٍ شديدٍ ازدواجيّ (ما بين صنفين [classes])، أو التفويض المفرط (excessive delegation).<br />
<br />
=== [[Refactoring/smells/other smells|مشاكل أخرى]] ===<br />
ستجد في هذا القسم الاختلالات والمشكلات التي لا تنحصر في صنف محدَّد.<br />
<br />
== [[Refactoring/techniques|تقنيات إعادة التصميم]] ==<br />
هنالك العديد من تقنيات إعادة التصميم التي يمكن استعمالها في حالات عديدة. تنقسم هذه التقنيات إلى:<br />
<br />
===[[Refactoring/techniques/composing methods|إنشاء التوابع]]===<br />
تستهدف إعادة التصميم بشكل رئيسيٍّ إنشاء التوابع الصحيحة المناسبة، إذ تكون التوابع الطويلة سببًا للمشاكل في كثيرٍ من الحالات، وتجعل شيفرات بعض التوابع منطق التنفيذ (execution logic) غامضًا ويصبح التابع بهذا عصيَّ الفهم من جهةٍ وصعب التغييرٍ من جهة ثانية.<br />
<br />
يشمل هذا القسم من الحلول كلَّ ما يتعلق بالتوابع وإزالة التكرار (duplicates) في الشيفرة ليسمح بإجراء التطويرات المستقبليّة.<br />
===[[Refactoring/techniques/moving features between objects|نقل الميزات ما بين الكائنات]]===<br />
تساعد عملية إعادة التصميم في توزيع المهام بشكل مثاليّ على الأصناف المختلفة في الشيفرة، وتضمن تقنيات الحل هذه طريقةً آمنةً لنقل المهام ما بين الأصناف، وإنشاء أصناف جديدة وحماية تفاصيل عملية التنفيذ من الوصول العام.<br />
===[[Refactoring/techniques/organizing data|تنظيم البيانات]]===<br />
تساعد تقنيات إعادة التصميم هذه بالتعامل مع البيانات، وتبديل أصناف ذات وظائف كثيرة مكان الأنواع الأساسية (primitives). نتيجة أخرى مهمة نحصل عليها بتطبيق هذه التقنيات هي فك ارتباطات صنف مما يجعل الصنف قابلًا للنقل وإعادة الاستعمال.<br />
===[[Refactoring/techniques/simplifying conditional expressions|تبسيط التعابير الشرطية]]===<br />
تزداد البنية المنطقية للشروط تعقيدًا مع مرور الوقت، لذا هنالك الكثير من التقنيات لمواجهة هذا التعقيد وتبسيطه.<br />
<br />
===[[Refactoring/techniques/simplifying method calls|تبسيط استدعاءات التوابع]]===<br />
تجعل التقنيات التي سيشار إليها في هذا القسم استدعاءات التوابع أبسط وأسهل للفهم والاستيعاب. سيؤدي ذلك بدوره إلى تبسيط الواجهات للتفاعل بين الأصناف.<br />
<br />
===[[Refactoring/techniques/dealing with generalization|التعامل مع التعميم]]===<br />
يملك التجريد (Abstraction) تقنيات إعادة التصميم الخاصة به والمرتبطة بشكل أساسي بوظيفة النقل على طول التسلسل الهرمي لوراثة الصنف (class inheritance hierarchy)، وبإنشاء أصناف وواجهات جديدة، وبتبديل التفويض مكان الوراثة أو العكس. <br />
<br />
== مصادر ==<br />
* [https://refactoring.guru/ صفحة توثيق إعادة التصميم في موقع refactoring.guru]<br />
[[تصنيف:Refactoring]]</div>عاطف-بن-عليhttps://wiki.hsoub.com/index.php?title=Refactoring&diff=28398Refactoring2019-03-30T22:24:17Z<p>عاطف-بن-علي: اقتراح تعديل صياغة الجملة.</p>
<hr />
<div><noinclude>{{DISPLAYTITLE:إعادة التصميم (Refactoring)}}</noinclude><br />
تهدف عملية إعادة التصميم (refactoring) للحصول على شيفرة جيّدة سهلة القراءة يسهل تطويرها والتخلُّص من المتطلَّبات التقنيّة الزائدة فيها، وهذا ما يُعرَف بالشيفرة النظيفة (clean code) لأنّ الشيفرة الرديئة لا بُدَّ من انعكاسها سلبًا على نجاح المشروع البرمجيّ.<br />
<br />
== [[Refactoring/what is refactoring|كيف تكون الشيفرة نظيفة؟]] ==<br />
هدف عملية إعادة التصميم (refactoring) هو التخلُّص من المتطلَّبات التقنيّة الزائدة، إذ تحوِّل كلَّ الفوضى المنتشرة في الشيفرة إلى شيفرةٍ نظيفةٍ (clean code) ذات تصميمٍ سهل، وهذا -لا بُدَّ- أمرٌ رائعٌ. من مميزات الشيفرة النظيفة:<br />
* واضحة مقروءة<br />
* لا تكرار فيها<br />
* بأقل عددٍ ممكنٍ من الأصناف<br />
* تجتاز الاختبارات المختلفة بنجاح<br />
* سهلة ولا تحتاج الصيانة المتكرِّرة<br />
<br />
== [[Refactoring/technical debt|فخ الأعباء التقنية]] ==<br />
يقع الكثير من المبرمجين في فخ الأعباء التقنية وهذا مكلفٌ جدًا إن لم يُعالَج في وقت مبكِّر، ومن أسبابه:<br />
* '''ضغط العمل:''' مما يؤدي لنشر بعض الميّزات (features) قبل الانتهاء منها كلِّيَّا.<br />
* '''التغافل عن عواقب الأعباء التقنيّة:''' لأنّ الأعباء التقنيّة ستحدُّ من سرعة التطوير البرمجيّ.<br />
* '''الفشل بمعالجة الترابط الشديد ما بين المكونات البرمجيّة:''' وذلك عندما يبدو المشروع كتلةً واحدةً بدلًا من وحداتٍ مستقلةٍ.<br />
* '''إهمال إجراء الاختبارات:''' وتكون النتائج حينئذٍ كارثيّة!<br />
* '''صياغة توثيقيّة هزيلة:''' تكون سببًا للكثير من المشاكل لدى المبرمجين الجُدد.<br />
* '''غياب التواصل الفعّال بين أعضاء الفريق:''' كأن يتابع المبرمجون والمطورون العمل وفقًا لمعلوماتٍ وعملياتٍ قديمةٍ من المشروع.<br />
* '''التطوير بعيد الأمد لعدّة فروع بوقتٍ واحدٍ:''' وخاصّة عندما يكون هنالك تغييرات إفراديّة.<br />
* '''تسويف عملية إعادة التصميم (refactoring):''' وهذا يعني زيادة عدد الشيفرات التي سيُعاد العمل عليها مستقبلًا.<br />
* '''لا رقابة للالتزام بالنمط المُوحَّد:''' عندما يكتب كلُّ شخصٍ شيفرةً بحسب نظرته وطريقته الخاصّة.<br />
* '''الإلمام غير الكافي:''' عندما لا يعرف المُطوِّر كيفيّة كتابة شيفرة فعّالةً ومناسبة.<br />
<br />
== [[Refactoring/when|متى نحتاج إعادة التصميم؟]] ==<br />
نحتاج إلى إعادة التصميم:<br />
# '''عند إضافة ميّزةٍ (feature) جديدة''': إذ سيصبح التحكُّم بالشيفرة النظيفة (clean code) أكثر سهولةً، وبالتالي فإنّ إجراء التغييرات سيكون أسهل بكثيرٍ مما كان عليه قبل إعادة التصميم.<br />
# '''عند إصلاح الأخطاء (bugs)''': إذ ستتَّضح الأخطاء بجهدٍ ووقتٍ أقل، وستغني إعادة التصميم المبكِّرة عن الحاجةَ لإعادة التصميم المُخصَّص لاحقًا.<br />
# '''أثناء مراجعة الشيفرة (code review)''': إذ هي الفرصةُ الأخيرة لتوضيب الشيفرة قبل نشرها للعامّة.<br />
<br />
== [[Refactoring/how to|خطوات إعادة التصميم]] ==<br />
تجري عملية إعادة التصميم عبر عدّة خطواتٍ تُحدِث تغييرًا بسيطًا تدريجيًّا يجعل الشيفرة (مع كلِّ تغييرٍ) أفضل بقليلٍ، ولكنها لا توثر على أداء وفعاليّة البرنامج وتحافظ على استمرار عمله بشكلٍ سليمٍ، وتتلخص إعادة التصميم بالخطوات الآتية:<br />
* '''الحصول على شيفرةٍ نظيفة'''<br />
* ''' لا مهام وظيفيّة جديدة أثناء إعادة التصميم'''<br />
* '''اجتياز كافة الاختبارات السابقة'''<br />
<br />
=== مثال ===<br />
تفيد عملية إعادة التصميم في تبسيط التعليمات الشرطيّة المعقَّدة وذلك عبر عزل عملياتها في توابع مستقلَّة كما في المثال الآتي.<br />
<br />
==== الشيفرة قبل إعادة التصميم ====<br />
<syntaxhighlight lang="java"><br />
if (date.before(SUMMER_START) || date.after(SUMMER_END)) {<br />
charge = quantity * winterRate + winterServiceCharge;<br />
}<br />
else {<br />
charge = quantity * summerRate;<br />
}<br />
<br />
<br />
</syntaxhighlight><br />
<br />
==== الشيفرة بعد التصميم ====<br />
<syntaxhighlight lang="java"><br />
if (notSummer(date)) {<br />
charge = winterCharge(quantity);<br />
}<br />
else {<br />
charge = summerCharge(quantity);<br />
}<br />
<br />
<br />
</syntaxhighlight><br />
<br />
والفرق واضحٌ ما بين الشيفرتين من ناحية التنظيم (organization) وسهولة كشف الأخطاء (bug detects) وقابليّة القراءة (readability) والصيانة (maintenance).<br />
<br />
== [[Refactoring/smells|مشاكل الشيفرات]] ==<br />
قد تعاني الشيفرات الكثير من الأمراض والعلل الشكلية؛ فبمجرد اكتشاف تلك العلل الظاهرية، يسهل علينا معرفة العلاج (التقنيات) وتطبيقه (إعادة التصميم) للحصول على شيفرة سليمة نظيفة. من هذه العلل:<br />
<br />
=== [[Refactoring/smells/bloaters|المبالغة والإطالة]] ===<br />
قد يزداد حجم الشيفرة ازديادًا كبيرًا ليصل لمرحلةٍ يصعُب التعامل معها، ويبدو هذا التضخم واضحًا.<br />
=== [[Refactoring/smells/oo abusers|الاستخدام الخطأ لمبادئ البرمجة كائنية التوجه (OOP)]] ===<br />
من مشاكل الشيفرات أيضًا التطبيقُ الخطأ وغير المكتمل لمبادئ البرمجة كائنية التوجّه (Object-Oriented).<br />
=== [[Refactoring/smells/change preventers|عرقلة التغيير]] ===<br />
قد يكون تطوير بعض الشيفرات مشكلةً حقيقيةً إذ عند إحداث أيّ تغييرٍ في جزءٍ منها لا بُدَّ وأن تتبعه عدّة تغييراتٍ أخرى في أجزاء متفرِّقة، وبالتالي سيصبح تطوير البرنامج شائكًا معقّدًا وبتكلفةٍ غير زهيدةٍ.<br />
=== [[Refactoring/smells/dispensables|الأجزاء الفائضة]] ===<br />
وهي الأجزاء عديمة النفع في الشيفرة، وسيجعلُ التخلُّصُ منها الشيفرةَ نظيفةً يسيرة الفهم وأكثر فعاليّة.<br />
=== [[Refactoring/smells/couplers|الروابط الازدواجية]] ===<br />
كإنشاء رابطٍ شديدٍ ازدواجيّ (ما بين صنفين [classes])، أو التفويض المفرط (excessive delegation).<br />
<br />
=== [[Refactoring/smells/other smells|مشاكل أخرى]] ===<br />
ستجد في هذا القسم الاختلالات والمشكلات التي لا تنحصر في صنف محدَّد.<br />
<br />
== [[Refactoring/techniques|تقنيات إعادة التصميم]] ==<br />
هنالك العديد من تقنيات إعادة التصميم التي يمكن استعمالها في حالات عديدة. تنقسم هذه التقنيات إلى:<br />
<br />
===[[Refactoring/techniques/composing methods|إنشاء التوابع]]===<br />
تستهدف إعادة التصميم بشكل رئيسيٍّ إنشاء التوابع الصحيحة المناسبة، إذ تكون التوابع الطويلة سببًا للمشاكل في كثيرٍ من الحالات، وتجعل شيفرات بعض التوابع منطق التنفيذ (execution logic) غامضًا ويصبح التابع بهذا عصيَّ الفهم من جهةٍ وصعب التغييرٍ من جهة ثانية.<br />
<br />
يشمل هذا القسم من الحلول كلَّ ما يتعلق بالتوابع وإزالة التكرار (duplicates) في الشيفرة ليسمح بإجراء التطويرات المستقبليّة.<br />
===[[Refactoring/techniques/moving features between objects|نقل الميزات ما بين الكائنات]]===<br />
تساعد عملية إعادة التصميم في توزيع المهام بشكل مثاليّ على الأصناف المختلفة في الشيفرة، وتضمن تقنيات الحل هذه طريقةً آمنةً لنقل المهام ما بين الأصناف، وإنشاء أصناف جديدة وحماية تفاصيل عملية التنفيذ من الوصول العام.<br />
===[[Refactoring/techniques/organizing data|تنظيم البيانات]]===<br />
تساعد تقنيات إعادة التصميم هذه بالتعامل مع البيانات، وتبديل أصناف ذات وظائف كثيرة مكان الأنواع الأساسية (primitives). نتيجة أخرى مهمة نحصل عليها بتطبيق هذه التقنيات هي فك ارتباطات صنف مما يجعل الصنف قابلًا للنقل وإعادة الاستعمال.<br />
===[[Refactoring/techniques/simplifying conditional expressions|تبسيط التعابير الشرطية]]===<br />
تزداد البنية المنطقية للشروط تعقيدًا مع مرور الوقت، لذا هنالك الكثير من التقنيات لمواجهة هذا التعقيد وتبسيطه.<br />
<br />
===[[Refactoring/techniques/simplifying method calls|تبسيط استدعاءات التوابع]]===<br />
تجعل التقنيات التي سيشار إليها في هذا القسم استدعاءات التوابع أبسط وأسهل للفهم والاستيعاب. سيؤدي ذلك بدوره إلى تبسيط الواجهات للتفاعل بين الأصناف.<br />
<br />
===[[Refactoring/techniques/dealing with generalization|التعامل مع التعميم]]===<br />
يملك التجريد (Abstraction) تقنيات إعادة التصميم الخاصة به والمرتبطة بشكل أساسي بوظيفة النقل على طول التسلسل الهرمي لوراثة الصنف (class inheritance hierarchy)، وبإنشاء أصناف وواجهات جديدة، وبتبديل التفويض مكان الوراثة أو العكس. <br />
<br />
== مصادر ==<br />
* [https://refactoring.guru/ صفحة توثيق إعادة التصميم في موقع refactoring.guru]<br />
[[تصنيف:Refactoring]]</div>عاطف-بن-عليhttps://wiki.hsoub.com/index.php?title=Refactoring&diff=28397Refactoring2019-03-30T22:23:11Z<p>عاطف-بن-علي: اقتراح تعديل صياغة الجملة.</p>
<hr />
<div><noinclude>{{DISPLAYTITLE:إعادة التصميم (Refactoring)}}</noinclude><br />
تهدف عملية إعادة التصميم (refactoring) للحصول على شيفرة جيّدة سهلة القراءة يسهل تطويرها والتخلُّص من المتطلَّبات التقنيّة الزائدة فيها، وهذا ما يُعرَف بالشيفرة النظيفة (clean code) لأنّ الشيفرة الرديئة لا بُدَّ من انعكاسها سلبًا على نجاح المشروع البرمجيّ.<br />
<br />
== [[Refactoring/what is refactoring|كيف تكون الشيفرة نظيفة؟]] ==<br />
تهدف عملية إعادة التصميم (refactoring) للتخلُّص من المتطلَّبات التقنيّة الزائدة، إذ تحوِّل كلَّ الفوضى المنتشرة في الشيفرة إلى شيفرةٍ نظيفةٍ (clean code) ذات تصميمٍ سهل، وهذا -لا بُدَّ- أمرٌ رائعٌ. من مميزات الشيفرة النظيفة:<br />
* واضحة مقروءة<br />
* لا تكرار فيها<br />
* بأقل عددٍ ممكنٍ من الأصناف<br />
* تجتاز الاختبارات المختلفة بنجاح<br />
* سهلة ولا تحتاج الصيانة المتكرِّرة<br />
<br />
== [[Refactoring/technical debt|فخ الأعباء التقنية]] ==<br />
يقع الكثير من المبرمجين في فخ الأعباء التقنية وهذا مكلفٌ جدًا إن لم يُعالَج في وقت مبكِّر، ومن أسبابه:<br />
* '''ضغط العمل:''' مما يؤدي لنشر بعض الميّزات (features) قبل الانتهاء منها كلِّيَّا.<br />
* '''التغافل عن عواقب الأعباء التقنيّة:''' لأنّ الأعباء التقنيّة ستحدُّ من سرعة التطوير البرمجيّ.<br />
* '''الفشل بمعالجة الترابط الشديد ما بين المكونات البرمجيّة:''' وذلك عندما يبدو المشروع كتلةً واحدةً بدلًا من وحداتٍ مستقلةٍ.<br />
* '''إهمال إجراء الاختبارات:''' وتكون النتائج حينئذٍ كارثيّة!<br />
* '''صياغة توثيقيّة هزيلة:''' تكون سببًا للكثير من المشاكل لدى المبرمجين الجُدد.<br />
* '''غياب التواصل الفعّال بين أعضاء الفريق:''' كأن يتابع المبرمجون والمطورون العمل وفقًا لمعلوماتٍ وعملياتٍ قديمةٍ من المشروع.<br />
* '''التطوير بعيد الأمد لعدّة فروع بوقتٍ واحدٍ:''' وخاصّة عندما يكون هنالك تغييرات إفراديّة.<br />
* '''تسويف عملية إعادة التصميم (refactoring):''' وهذا يعني زيادة عدد الشيفرات التي سيُعاد العمل عليها مستقبلًا.<br />
* '''لا رقابة للالتزام بالنمط المُوحَّد:''' عندما يكتب كلُّ شخصٍ شيفرةً بحسب نظرته وطريقته الخاصّة.<br />
* '''الإلمام غير الكافي:''' عندما لا يعرف المُطوِّر كيفيّة كتابة شيفرة فعّالةً ومناسبة.<br />
<br />
== [[Refactoring/when|متى نحتاج إعادة التصميم؟]] ==<br />
نحتاج إلى إعادة التصميم:<br />
# '''عند إضافة ميّزةٍ (feature) جديدة''': إذ سيصبح التحكُّم بالشيفرة النظيفة (clean code) أكثر سهولةً، وبالتالي فإنّ إجراء التغييرات سيكون أسهل بكثيرٍ مما كان عليه قبل إعادة التصميم.<br />
# '''عند إصلاح الأخطاء (bugs)''': إذ ستتَّضح الأخطاء بجهدٍ ووقتٍ أقل، وستغني إعادة التصميم المبكِّرة عن الحاجةَ لإعادة التصميم المُخصَّص لاحقًا.<br />
# '''أثناء مراجعة الشيفرة (code review)''': إذ هي الفرصةُ الأخيرة لتوضيب الشيفرة قبل نشرها للعامّة.<br />
<br />
== [[Refactoring/how to|خطوات إعادة التصميم]] ==<br />
تجري عملية إعادة التصميم عبر عدّة خطواتٍ تُحدِث تغييرًا بسيطًا تدريجيًّا يجعل الشيفرة (مع كلِّ تغييرٍ) أفضل بقليلٍ، ولكنها لا توثر على أداء وفعاليّة البرنامج وتحافظ على استمرار عمله بشكلٍ سليمٍ، وتتلخص إعادة التصميم بالخطوات الآتية:<br />
* '''الحصول على شيفرةٍ نظيفة'''<br />
* ''' لا مهام وظيفيّة جديدة أثناء إعادة التصميم'''<br />
* '''اجتياز كافة الاختبارات السابقة'''<br />
<br />
=== مثال ===<br />
تفيد عملية إعادة التصميم في تبسيط التعليمات الشرطيّة المعقَّدة وذلك عبر عزل عملياتها في توابع مستقلَّة كما في المثال الآتي.<br />
<br />
==== الشيفرة قبل إعادة التصميم ====<br />
<syntaxhighlight lang="java"><br />
if (date.before(SUMMER_START) || date.after(SUMMER_END)) {<br />
charge = quantity * winterRate + winterServiceCharge;<br />
}<br />
else {<br />
charge = quantity * summerRate;<br />
}<br />
<br />
<br />
</syntaxhighlight><br />
<br />
==== الشيفرة بعد التصميم ====<br />
<syntaxhighlight lang="java"><br />
if (notSummer(date)) {<br />
charge = winterCharge(quantity);<br />
}<br />
else {<br />
charge = summerCharge(quantity);<br />
}<br />
<br />
<br />
</syntaxhighlight><br />
<br />
والفرق واضحٌ ما بين الشيفرتين من ناحية التنظيم (organization) وسهولة كشف الأخطاء (bug detects) وقابليّة القراءة (readability) والصيانة (maintenance).<br />
<br />
== [[Refactoring/smells|مشاكل الشيفرات]] ==<br />
قد تعاني الشيفرات الكثير من الأمراض والعلل الشكلية؛ فبمجرد اكتشاف تلك العلل الظاهرية، يسهل علينا معرفة العلاج (التقنيات) وتطبيقه (إعادة التصميم) للحصول على شيفرة سليمة نظيفة. من هذه العلل:<br />
<br />
=== [[Refactoring/smells/bloaters|المبالغة والإطالة]] ===<br />
قد يزداد حجم الشيفرة ازديادًا كبيرًا ليصل لمرحلةٍ يصعُب التعامل معها، ويبدو هذا التضخم واضحًا.<br />
=== [[Refactoring/smells/oo abusers|الاستخدام الخطأ لمبادئ البرمجة كائنية التوجه (OOP)]] ===<br />
من مشاكل الشيفرات أيضًا التطبيقُ الخطأ وغير المكتمل لمبادئ البرمجة كائنية التوجّه (Object-Oriented).<br />
=== [[Refactoring/smells/change preventers|عرقلة التغيير]] ===<br />
قد يكون تطوير بعض الشيفرات مشكلةً حقيقيةً إذ عند إحداث أيّ تغييرٍ في جزءٍ منها لا بُدَّ وأن تتبعه عدّة تغييراتٍ أخرى في أجزاء متفرِّقة، وبالتالي سيصبح تطوير البرنامج شائكًا معقّدًا وبتكلفةٍ غير زهيدةٍ.<br />
=== [[Refactoring/smells/dispensables|الأجزاء الفائضة]] ===<br />
وهي الأجزاء عديمة النفع في الشيفرة، وسيجعلُ التخلُّصُ منها الشيفرةَ نظيفةً يسيرة الفهم وأكثر فعاليّة.<br />
=== [[Refactoring/smells/couplers|الروابط الازدواجية]] ===<br />
كإنشاء رابطٍ شديدٍ ازدواجيّ (ما بين صنفين [classes])، أو التفويض المفرط (excessive delegation).<br />
<br />
=== [[Refactoring/smells/other smells|مشاكل أخرى]] ===<br />
ستجد في هذا القسم الاختلالات والمشكلات التي لا تنحصر في صنف محدَّد.<br />
<br />
== [[Refactoring/techniques|تقنيات إعادة التصميم]] ==<br />
هنالك العديد من تقنيات إعادة التصميم التي يمكن استعمالها في حالات عديدة. تنقسم هذه التقنيات إلى:<br />
<br />
===[[Refactoring/techniques/composing methods|إنشاء التوابع]]===<br />
تستهدف إعادة التصميم بشكل رئيسيٍّ إنشاء التوابع الصحيحة المناسبة، إذ تكون التوابع الطويلة سببًا للمشاكل في كثيرٍ من الحالات، وتجعل شيفرات بعض التوابع منطق التنفيذ (execution logic) غامضًا ويصبح التابع بهذا عصيَّ الفهم من جهةٍ وصعب التغييرٍ من جهة ثانية.<br />
<br />
يشمل هذا القسم من الحلول كلَّ ما يتعلق بالتوابع وإزالة التكرار (duplicates) في الشيفرة ليسمح بإجراء التطويرات المستقبليّة.<br />
===[[Refactoring/techniques/moving features between objects|نقل الميزات ما بين الكائنات]]===<br />
تساعد عملية إعادة التصميم في توزيع المهام بشكل مثاليّ على الأصناف المختلفة في الشيفرة، وتضمن تقنيات الحل هذه طريقةً آمنةً لنقل المهام ما بين الأصناف، وإنشاء أصناف جديدة وحماية تفاصيل عملية التنفيذ من الوصول العام.<br />
===[[Refactoring/techniques/organizing data|تنظيم البيانات]]===<br />
تساعد تقنيات إعادة التصميم هذه بالتعامل مع البيانات، وتبديل أصناف ذات وظائف كثيرة مكان الأنواع الأساسية (primitives). نتيجة أخرى مهمة نحصل عليها بتطبيق هذه التقنيات هي فك ارتباطات صنف مما يجعل الصنف قابلًا للنقل وإعادة الاستعمال.<br />
===[[Refactoring/techniques/simplifying conditional expressions|تبسيط التعابير الشرطية]]===<br />
تزداد البنية المنطقية للشروط تعقيدًا مع مرور الوقت، لذا هنالك الكثير من التقنيات لمواجهة هذا التعقيد وتبسيطه.<br />
<br />
===[[Refactoring/techniques/simplifying method calls|تبسيط استدعاءات التوابع]]===<br />
تجعل التقنيات التي سيشار إليها في هذا القسم استدعاءات التوابع أبسط وأسهل للفهم والاستيعاب. سيؤدي ذلك بدوره إلى تبسيط الواجهات للتفاعل بين الأصناف.<br />
<br />
===[[Refactoring/techniques/dealing with generalization|التعامل مع التعميم]]===<br />
يملك التجريد (Abstraction) تقنيات إعادة التصميم الخاصة به والمرتبطة بشكل أساسي بوظيفة النقل على طول التسلسل الهرمي لوراثة الصنف (class inheritance hierarchy)، وبإنشاء أصناف وواجهات جديدة، وبتبديل التفويض مكان الوراثة أو العكس. <br />
<br />
== مصادر ==<br />
* [https://refactoring.guru/ صفحة توثيق إعادة التصميم في موقع refactoring.guru]<br />
[[تصنيف:Refactoring]]</div>عاطف-بن-عليhttps://wiki.hsoub.com/index.php?title=Refactoring&diff=28396Refactoring2019-03-30T22:21:58Z<p>عاطف-بن-علي: /* كيف تكون الشيفرة نظيفة؟ */</p>
<hr />
<div><noinclude>{{DISPLAYTITLE:إعادة التصميم (Refactoring)}}</noinclude><br />
تهدف عملية إعادة التصميم (refactoring) للحصول على شيفرة جيّدة سهلة القراءة يسهل تطويرها والتخلُّص من المتطلَّبات التقنيّة الزائدة فيها، وهذا ما يُعرَف بالشيفرة النظيفة (clean code) لأنّ الشيفرة الرديئة لا بُدَّ من انعكاسها سلبًا على نجاح المشروع البرمجيّ.<br />
<br />
== [[Refactoring/what is refactoring|كيف تكون الشيفرة نظيفة؟]] ==<br />
تهدف عملية إعادة التصميم (refactoring) للتخلُّص من المتطلَّبات التقنيّة الزائدة، إذ تحوِّل كلَّ الفوضى المنتشرة في الشيفرة إلى شيفرةٍ نظيفةٍ (clean code) ذات تصميمٍ سهل، وهذا -لا بُدَّ- أمرٌ رائعٌ. من مميزات الشيفرة النظيفة:<br />
* واضحة مقروءة<br />
* لا تكرار فيها<br />
* بأقل عددٍ ممكنٍ من الأصناف<br />
* تجتاز الاختبارات المختلفة بنجاح<br />
* سهلة ولا تحتاج الصيانة المتكرِّرة<br />
<br />
== [[Refactoring/technical debt|فخ الأعباء التقنية]] ==<br />
يقع الكثير من المبرمجين في فخ الأعباء التقنية وهذا مكلفٌ جدًا إن لم يُعالَج بفترة مبكِّرة، ومن أسبابه:<br />
* '''ضغط العمل:''' مما يؤدي لنشر بعض الميّزات (features) قبل الانتهاء منها كلِّيَّا.<br />
* '''التغافل عن عواقب الأعباء التقنيّة:''' لأنّ الأعباء التقنيّة ستحدُّ من سرعة التطوير البرمجيّ.<br />
* '''الفشل بمعالجة الترابط الشديد ما بين المكونات البرمجيّة:''' وذلك عندما يبدو المشروع كتلةً واحدةً بدلًا من وحداتٍ مستقلةٍ.<br />
* '''إهمال إجراء الاختبارات:''' وتكون النتائج حينئذٍ كارثيّة!<br />
* '''صياغة توثيقيّة هزيلة:''' تكون سببًا للكثير من المشاكل لدى المبرمجين الجُدد.<br />
* '''غياب التواصل الفعّال بين أعضاء الفريق:''' كأن يتابع المبرمجون والمطورون العمل وفقًا لمعلوماتٍ وعملياتٍ قديمةٍ من المشروع.<br />
* '''التطوير بعيد الأمد لعدّة فروع بوقتٍ واحدٍ:''' وخاصّة عندما يكون هنالك تغييرات إفراديّة.<br />
* '''تسويف عملية إعادة التصميم (refactoring):''' وهذا يعني زيادة عدد الشيفرات التي سيُعاد العمل عليها مستقبلًا.<br />
* '''لا رقابة للالتزام بالنمط المُوحَّد:''' عندما يكتب كلُّ شخصٍ شيفرةً بحسب نظرته وطريقته الخاصّة.<br />
* '''الإلمام غير الكافي:''' عندما لا يعرف المُطوِّر كيفيّة كتابة شيفرة فعّالةً ومناسبة.<br />
<br />
== [[Refactoring/when|متى نحتاج إعادة التصميم؟]] ==<br />
نحتاج إلى إعادة التصميم:<br />
# '''عند إضافة ميّزةٍ (feature) جديدة''': إذ سيصبح التحكُّم بالشيفرة النظيفة (clean code) أكثر سهولةً، وبالتالي فإنّ إجراء التغييرات سيكون أسهل بكثيرٍ مما كان عليه قبل إعادة التصميم.<br />
# '''عند إصلاح الأخطاء (bugs)''': إذ ستتَّضح الأخطاء بجهدٍ ووقتٍ أقل، وستغني إعادة التصميم المبكِّرة عن الحاجةَ لإعادة التصميم المُخصَّص لاحقًا.<br />
# '''أثناء مراجعة الشيفرة (code review)''': إذ هي الفرصةُ الأخيرة لتوضيب الشيفرة قبل نشرها للعامّة.<br />
<br />
== [[Refactoring/how to|خطوات إعادة التصميم]] ==<br />
تجري عملية إعادة التصميم عبر عدّة خطواتٍ تُحدِث تغييرًا بسيطًا تدريجيًّا يجعل الشيفرة (مع كلِّ تغييرٍ) أفضل بقليلٍ، ولكنها لا توثر على أداء وفعاليّة البرنامج وتحافظ على استمرار عمله بشكلٍ سليمٍ، وتتلخص إعادة التصميم بالخطوات الآتية:<br />
* '''الحصول على شيفرةٍ نظيفة'''<br />
* ''' لا مهام وظيفيّة جديدة أثناء إعادة التصميم'''<br />
* '''اجتياز كافة الاختبارات السابقة'''<br />
<br />
=== مثال ===<br />
تفيد عملية إعادة التصميم في تبسيط التعليمات الشرطيّة المعقَّدة وذلك عبر عزل عملياتها في توابع مستقلَّة كما في المثال الآتي.<br />
<br />
==== الشيفرة قبل إعادة التصميم ====<br />
<syntaxhighlight lang="java"><br />
if (date.before(SUMMER_START) || date.after(SUMMER_END)) {<br />
charge = quantity * winterRate + winterServiceCharge;<br />
}<br />
else {<br />
charge = quantity * summerRate;<br />
}<br />
<br />
<br />
</syntaxhighlight><br />
<br />
==== الشيفرة بعد التصميم ====<br />
<syntaxhighlight lang="java"><br />
if (notSummer(date)) {<br />
charge = winterCharge(quantity);<br />
}<br />
else {<br />
charge = summerCharge(quantity);<br />
}<br />
<br />
<br />
</syntaxhighlight><br />
<br />
والفرق واضحٌ ما بين الشيفرتين من ناحية التنظيم (organization) وسهولة كشف الأخطاء (bug detects) وقابليّة القراءة (readability) والصيانة (maintenance).<br />
<br />
== [[Refactoring/smells|مشاكل الشيفرات]] ==<br />
قد تعاني الشيفرات الكثير من الأمراض والعلل الشكلية؛ فبمجرد اكتشاف تلك العلل الظاهرية، يسهل علينا معرفة العلاج (التقنيات) وتطبيقه (إعادة التصميم) للحصول على شيفرة سليمة نظيفة. من هذه العلل:<br />
<br />
=== [[Refactoring/smells/bloaters|المبالغة والإطالة]] ===<br />
قد يزداد حجم الشيفرة ازديادًا كبيرًا ليصل لمرحلةٍ يصعُب التعامل معها، ويبدو هذا التضخم واضحًا.<br />
=== [[Refactoring/smells/oo abusers|الاستخدام الخطأ لمبادئ البرمجة كائنية التوجه (OOP)]] ===<br />
من مشاكل الشيفرات أيضًا التطبيقُ الخطأ وغير المكتمل لمبادئ البرمجة كائنية التوجّه (Object-Oriented).<br />
=== [[Refactoring/smells/change preventers|عرقلة التغيير]] ===<br />
قد يكون تطوير بعض الشيفرات مشكلةً حقيقيةً إذ عند إحداث أيّ تغييرٍ في جزءٍ منها لا بُدَّ وأن تتبعه عدّة تغييراتٍ أخرى في أجزاء متفرِّقة، وبالتالي سيصبح تطوير البرنامج شائكًا معقّدًا وبتكلفةٍ غير زهيدةٍ.<br />
=== [[Refactoring/smells/dispensables|الأجزاء الفائضة]] ===<br />
وهي الأجزاء عديمة النفع في الشيفرة، وسيجعلُ التخلُّصُ منها الشيفرةَ نظيفةً يسيرة الفهم وأكثر فعاليّة.<br />
=== [[Refactoring/smells/couplers|الروابط الازدواجية]] ===<br />
كإنشاء رابطٍ شديدٍ ازدواجيّ (ما بين صنفين [classes])، أو التفويض المفرط (excessive delegation).<br />
<br />
=== [[Refactoring/smells/other smells|مشاكل أخرى]] ===<br />
ستجد في هذا القسم الاختلالات والمشكلات التي لا تنحصر في صنف محدَّد.<br />
<br />
== [[Refactoring/techniques|تقنيات إعادة التصميم]] ==<br />
هنالك العديد من تقنيات إعادة التصميم التي يمكن استعمالها في حالات عديدة. تنقسم هذه التقنيات إلى:<br />
<br />
===[[Refactoring/techniques/composing methods|إنشاء التوابع]]===<br />
تستهدف إعادة التصميم بشكل رئيسيٍّ إنشاء التوابع الصحيحة المناسبة، إذ تكون التوابع الطويلة سببًا للمشاكل في كثيرٍ من الحالات، وتجعل شيفرات بعض التوابع منطق التنفيذ (execution logic) غامضًا ويصبح التابع بهذا عصيَّ الفهم من جهةٍ وصعب التغييرٍ من جهة ثانية.<br />
<br />
يشمل هذا القسم من الحلول كلَّ ما يتعلق بالتوابع وإزالة التكرار (duplicates) في الشيفرة ليسمح بإجراء التطويرات المستقبليّة.<br />
===[[Refactoring/techniques/moving features between objects|نقل الميزات ما بين الكائنات]]===<br />
تساعد عملية إعادة التصميم في توزيع المهام بشكل مثاليّ على الأصناف المختلفة في الشيفرة، وتضمن تقنيات الحل هذه طريقةً آمنةً لنقل المهام ما بين الأصناف، وإنشاء أصناف جديدة وحماية تفاصيل عملية التنفيذ من الوصول العام.<br />
===[[Refactoring/techniques/organizing data|تنظيم البيانات]]===<br />
تساعد تقنيات إعادة التصميم هذه بالتعامل مع البيانات، وتبديل أصناف ذات وظائف كثيرة مكان الأنواع الأساسية (primitives). نتيجة أخرى مهمة نحصل عليها بتطبيق هذه التقنيات هي فك ارتباطات صنف مما يجعل الصنف قابلًا للنقل وإعادة الاستعمال.<br />
===[[Refactoring/techniques/simplifying conditional expressions|تبسيط التعابير الشرطية]]===<br />
تزداد البنية المنطقية للشروط تعقيدًا مع مرور الوقت، لذا هنالك الكثير من التقنيات لمواجهة هذا التعقيد وتبسيطه.<br />
<br />
===[[Refactoring/techniques/simplifying method calls|تبسيط استدعاءات التوابع]]===<br />
تجعل التقنيات التي سيشار إليها في هذا القسم استدعاءات التوابع أبسط وأسهل للفهم والاستيعاب. سيؤدي ذلك بدوره إلى تبسيط الواجهات للتفاعل بين الأصناف.<br />
<br />
===[[Refactoring/techniques/dealing with generalization|التعامل مع التعميم]]===<br />
يملك التجريد (Abstraction) تقنيات إعادة التصميم الخاصة به والمرتبطة بشكل أساسي بوظيفة النقل على طول التسلسل الهرمي لوراثة الصنف (class inheritance hierarchy)، وبإنشاء أصناف وواجهات جديدة، وبتبديل التفويض مكان الوراثة أو العكس. <br />
<br />
== مصادر ==<br />
* [https://refactoring.guru/ صفحة توثيق إعادة التصميم في موقع refactoring.guru]<br />
[[تصنيف:Refactoring]]</div>عاطف-بن-عليhttps://wiki.hsoub.com/index.php?title=Refactoring&diff=28395Refactoring2019-03-30T22:19:19Z<p>عاطف-بن-علي: .الجملة صياغة تعديل</p>
<hr />
<div><noinclude>{{DISPLAYTITLE:إعادة التصميم (Refactoring)}}</noinclude><br />
تهدف عملية إعادة التصميم (refactoring) للحصول على شيفرة جيّدة سهلة القراءة يسهل تطويرها والتخلُّص من المتطلَّبات التقنيّة الزائدة فيها، وهذا ما يُعرَف بالشيفرة النظيفة (clean code) لأنّ الشيفرة الرديئة لا بُدَّ من انعكاسها سلبًا على نجاح المشروع البرمجيّ.<br />
<br />
== [[Refactoring/what is refactoring|كيف تكون الشيفرة نظيفة؟]] ==<br />
تهدف عملية إعادة التصميم (refactoring) للتخلُّص من المتطلَّبات التقنيّة الزائدة، إذ تحوِّل كلَّ الفوضى المنتشرة في الشيفرة إلى شيفرةٍ نظيفةٍ (clean code) ذات تصميمٍ مُبسَّط، وهذا -لا بُدَّ- أمرٌ رائعٌ. من مميزات الشيفرة النظيفة:<br />
* واضحة مقروءة<br />
* لا تكرار فيها<br />
* بأقل عددٍ ممكنٍ من الأصناف<br />
* تجتاز الاختبارات المختلفة بنجاح<br />
* سهلة ولا تحتاج الصيانة المتكرِّرة<br />
<br />
== [[Refactoring/technical debt|فخ الأعباء التقنية]] ==<br />
يقع الكثير من المبرمجين في فخ الأعباء التقنية وهذا مكلفٌ جدًا إن لم يُعالَج بفترة مبكِّرة، ومن أسبابه:<br />
* '''ضغط العمل:''' مما يؤدي لنشر بعض الميّزات (features) قبل الانتهاء منها كلِّيَّا.<br />
* '''التغافل عن عواقب الأعباء التقنيّة:''' لأنّ الأعباء التقنيّة ستحدُّ من سرعة التطوير البرمجيّ.<br />
* '''الفشل بمعالجة الترابط الشديد ما بين المكونات البرمجيّة:''' وذلك عندما يبدو المشروع كتلةً واحدةً بدلًا من وحداتٍ مستقلةٍ.<br />
* '''إهمال إجراء الاختبارات:''' وتكون النتائج حينئذٍ كارثيّة!<br />
* '''صياغة توثيقيّة هزيلة:''' تكون سببًا للكثير من المشاكل لدى المبرمجين الجُدد.<br />
* '''غياب التواصل الفعّال بين أعضاء الفريق:''' كأن يتابع المبرمجون والمطورون العمل وفقًا لمعلوماتٍ وعملياتٍ قديمةٍ من المشروع.<br />
* '''التطوير بعيد الأمد لعدّة فروع بوقتٍ واحدٍ:''' وخاصّة عندما يكون هنالك تغييرات إفراديّة.<br />
* '''تسويف عملية إعادة التصميم (refactoring):''' وهذا يعني زيادة عدد الشيفرات التي سيُعاد العمل عليها مستقبلًا.<br />
* '''لا رقابة للالتزام بالنمط المُوحَّد:''' عندما يكتب كلُّ شخصٍ شيفرةً بحسب نظرته وطريقته الخاصّة.<br />
* '''الإلمام غير الكافي:''' عندما لا يعرف المُطوِّر كيفيّة كتابة شيفرة فعّالةً ومناسبة.<br />
<br />
== [[Refactoring/when|متى نحتاج إعادة التصميم؟]] ==<br />
نحتاج إلى إعادة التصميم:<br />
# '''عند إضافة ميّزةٍ (feature) جديدة''': إذ سيصبح التحكُّم بالشيفرة النظيفة (clean code) أكثر سهولةً، وبالتالي فإنّ إجراء التغييرات سيكون أسهل بكثيرٍ مما كان عليه قبل إعادة التصميم.<br />
# '''عند إصلاح الأخطاء (bugs)''': إذ ستتَّضح الأخطاء بجهدٍ ووقتٍ أقل، وستغني إعادة التصميم المبكِّرة عن الحاجةَ لإعادة التصميم المُخصَّص لاحقًا.<br />
# '''أثناء مراجعة الشيفرة (code review)''': إذ هي الفرصةُ الأخيرة لتوضيب الشيفرة قبل نشرها للعامّة.<br />
<br />
== [[Refactoring/how to|خطوات إعادة التصميم]] ==<br />
تجري عملية إعادة التصميم عبر عدّة خطواتٍ تُحدِث تغييرًا بسيطًا تدريجيًّا يجعل الشيفرة (مع كلِّ تغييرٍ) أفضل بقليلٍ، ولكنها لا توثر على أداء وفعاليّة البرنامج وتحافظ على استمرار عمله بشكلٍ سليمٍ، وتتلخص إعادة التصميم بالخطوات الآتية:<br />
* '''الحصول على شيفرةٍ نظيفة'''<br />
* ''' لا مهام وظيفيّة جديدة أثناء إعادة التصميم'''<br />
* '''اجتياز كافة الاختبارات السابقة'''<br />
<br />
=== مثال ===<br />
تفيد عملية إعادة التصميم في تبسيط التعليمات الشرطيّة المعقَّدة وذلك عبر عزل عملياتها في توابع مستقلَّة كما في المثال الآتي.<br />
<br />
==== الشيفرة قبل إعادة التصميم ====<br />
<syntaxhighlight lang="java"><br />
if (date.before(SUMMER_START) || date.after(SUMMER_END)) {<br />
charge = quantity * winterRate + winterServiceCharge;<br />
}<br />
else {<br />
charge = quantity * summerRate;<br />
}<br />
<br />
<br />
</syntaxhighlight><br />
<br />
==== الشيفرة بعد التصميم ====<br />
<syntaxhighlight lang="java"><br />
if (notSummer(date)) {<br />
charge = winterCharge(quantity);<br />
}<br />
else {<br />
charge = summerCharge(quantity);<br />
}<br />
<br />
<br />
</syntaxhighlight><br />
<br />
والفرق واضحٌ ما بين الشيفرتين من ناحية التنظيم (organization) وسهولة كشف الأخطاء (bug detects) وقابليّة القراءة (readability) والصيانة (maintenance).<br />
<br />
== [[Refactoring/smells|مشاكل الشيفرات]] ==<br />
قد تعاني الشيفرات الكثير من الأمراض والعلل الشكلية؛ فبمجرد اكتشاف تلك العلل الظاهرية، يسهل علينا معرفة العلاج (التقنيات) وتطبيقه (إعادة التصميم) للحصول على شيفرة سليمة نظيفة. من هذه العلل:<br />
<br />
=== [[Refactoring/smells/bloaters|المبالغة والإطالة]] ===<br />
قد يزداد حجم الشيفرة ازديادًا كبيرًا ليصل لمرحلةٍ يصعُب التعامل معها، ويبدو هذا التضخم واضحًا.<br />
=== [[Refactoring/smells/oo abusers|الاستخدام الخطأ لمبادئ البرمجة كائنية التوجه (OOP)]] ===<br />
من مشاكل الشيفرات أيضًا التطبيقُ الخطأ وغير المكتمل لمبادئ البرمجة كائنية التوجّه (Object-Oriented).<br />
=== [[Refactoring/smells/change preventers|عرقلة التغيير]] ===<br />
قد يكون تطوير بعض الشيفرات مشكلةً حقيقيةً إذ عند إحداث أيّ تغييرٍ في جزءٍ منها لا بُدَّ وأن تتبعه عدّة تغييراتٍ أخرى في أجزاء متفرِّقة، وبالتالي سيصبح تطوير البرنامج شائكًا معقّدًا وبتكلفةٍ غير زهيدةٍ.<br />
=== [[Refactoring/smells/dispensables|الأجزاء الفائضة]] ===<br />
وهي الأجزاء عديمة النفع في الشيفرة، وسيجعلُ التخلُّصُ منها الشيفرةَ نظيفةً يسيرة الفهم وأكثر فعاليّة.<br />
=== [[Refactoring/smells/couplers|الروابط الازدواجية]] ===<br />
كإنشاء رابطٍ شديدٍ ازدواجيّ (ما بين صنفين [classes])، أو التفويض المفرط (excessive delegation).<br />
<br />
=== [[Refactoring/smells/other smells|مشاكل أخرى]] ===<br />
ستجد في هذا القسم الاختلالات والمشكلات التي لا تنحصر في صنف محدَّد.<br />
<br />
== [[Refactoring/techniques|تقنيات إعادة التصميم]] ==<br />
هنالك العديد من تقنيات إعادة التصميم التي يمكن استعمالها في حالات عديدة. تنقسم هذه التقنيات إلى:<br />
<br />
===[[Refactoring/techniques/composing methods|إنشاء التوابع]]===<br />
تستهدف إعادة التصميم بشكل رئيسيٍّ إنشاء التوابع الصحيحة المناسبة، إذ تكون التوابع الطويلة سببًا للمشاكل في كثيرٍ من الحالات، وتجعل شيفرات بعض التوابع منطق التنفيذ (execution logic) غامضًا ويصبح التابع بهذا عصيَّ الفهم من جهةٍ وصعب التغييرٍ من جهة ثانية.<br />
<br />
يشمل هذا القسم من الحلول كلَّ ما يتعلق بالتوابع وإزالة التكرار (duplicates) في الشيفرة ليسمح بإجراء التطويرات المستقبليّة.<br />
===[[Refactoring/techniques/moving features between objects|نقل الميزات ما بين الكائنات]]===<br />
تساعد عملية إعادة التصميم في توزيع المهام بشكل مثاليّ على الأصناف المختلفة في الشيفرة، وتضمن تقنيات الحل هذه طريقةً آمنةً لنقل المهام ما بين الأصناف، وإنشاء أصناف جديدة وحماية تفاصيل عملية التنفيذ من الوصول العام.<br />
===[[Refactoring/techniques/organizing data|تنظيم البيانات]]===<br />
تساعد تقنيات إعادة التصميم هذه بالتعامل مع البيانات، وتبديل أصناف ذات وظائف كثيرة مكان الأنواع الأساسية (primitives). نتيجة أخرى مهمة نحصل عليها بتطبيق هذه التقنيات هي فك ارتباطات صنف مما يجعل الصنف قابلًا للنقل وإعادة الاستعمال.<br />
===[[Refactoring/techniques/simplifying conditional expressions|تبسيط التعابير الشرطية]]===<br />
تزداد البنية المنطقية للشروط تعقيدًا مع مرور الوقت، لذا هنالك الكثير من التقنيات لمواجهة هذا التعقيد وتبسيطه.<br />
<br />
===[[Refactoring/techniques/simplifying method calls|تبسيط استدعاءات التوابع]]===<br />
تجعل التقنيات التي سيشار إليها في هذا القسم استدعاءات التوابع أبسط وأسهل للفهم والاستيعاب. سيؤدي ذلك بدوره إلى تبسيط الواجهات للتفاعل بين الأصناف.<br />
<br />
===[[Refactoring/techniques/dealing with generalization|التعامل مع التعميم]]===<br />
يملك التجريد (Abstraction) تقنيات إعادة التصميم الخاصة به والمرتبطة بشكل أساسي بوظيفة النقل على طول التسلسل الهرمي لوراثة الصنف (class inheritance hierarchy)، وبإنشاء أصناف وواجهات جديدة، وبتبديل التفويض مكان الوراثة أو العكس. <br />
<br />
== مصادر ==<br />
* [https://refactoring.guru/ صفحة توثيق إعادة التصميم في موقع refactoring.guru]<br />
[[تصنيف:Refactoring]]</div>عاطف-بن-عليhttps://wiki.hsoub.com/index.php?title=Python/Topics&diff=28288Python/Topics2019-03-22T05:18:24Z<p>عاطف-بن-علي: /* القيمة المنطقية (boolean) */ فسخ كلمة بوليتين.</p>
<hr />
<div>== [[Python/Basic Syntax|بنية اللغة]] ==<br />
بيان للبنية العامة للغة بايثون وبعض الأمور العامة مثل التعليقات وتسمية المعرّفات وغيرها.<br />
<br />
== [[Python/interpreter|مفسر بايثون]] ==<br />
يستخدم مفسر بايثون لمعالجة الشيفرات المكتوبة بها، وهو يقبل عددًا من الخيارات، ويمكن تشغيله في الوضع التفاعلي.<br />
<br />
== أنواع البيانات ==<br />
<br />
=== [[Python/boolean|القيمة المنطقية (boolean)]] ===<br />
القيمتان المنطقيتان اللتان تدعمهما بايثون هما <code>True</code> و <code>False</code> وهما كائنان ثابتان (Constant objects) يعبران عن صحّة تعبير ما، فإمّا أن يكون صحيحًا True أو خطأً False.<br />
<br />
=== [[Python/int|الأعداد الصحيحة (int)]] ===<br />
العدد الصحيح integer هو أي عدد موجب أو سالب لا يتضمن فاصلة عشرية، ويمكن تمثيله بالنظام العشري (decimal، الأساس 10) والست عشري (hexadecimal، الأساس 16) والثماني (octal، الأساس 8) والثنائي (binary، الأساس 2).<br />
<br />
=== [[Python/float|الأعداد العشرية (float)]] ===<br />
الأعداد العشرية (ذات الفاصلة العائمة floating point) هي الأعداد التي تتضمن فاصلة عشرية أو علامة أسية<br />
<br />
=== [[Python/decimal|الأعداد العشرية (decimal)]] ===<br />
تتيح وحدة decimal إجراء حسابات سريعة على الأعداد العشرية مع ضمان التقريب الصحيح.<br />
<br />
=== [[Python/fraction|الأعداد الكسرية (fraction)]] ===<br />
تتيح وحدة fractions التعامل مع الأعداد الكسرية مثل (⅓) أو (4/18) وإجراء العمليات الحسابية المختلفة عليها.<br />
<br />
=== [[Python/complex|الأعداد المركبة (complex)]] ===<br />
تتكوّن الأعداد المركبّة من جزأين حقيقي وتخيّلي وكلاهما من [[Python/Types/float|الأعداد العشرية ذات الفاصلة العائمة]] float، ويستخدم الحرفان <code>'j'</code> أو <code>'J'</code> للتعبير عن الأعداد المركبة.<br />
<br />
=== [[Python/str|السلاسل النصية (str)]] ===<br />
السلسلة النصية هي تسلسل من الحروف وهي غير قابلة للتغيير (immutable).<br />
<br />
=== [[Python/tuples|الصفوف (tuples)]] ===<br />
يتكوّن الصفّ من عدد من القيم المفصولة عن بعضها بفاصلة.<br />
<br />
=== [[Python/list|القوائم (lists)]] ===<br />
قائمة من القيم (العناصر) المفصولة عن بعضها البعض بفواصل (<code>,</code>) ومحاطة بأقواس مربعة. يمكن للقوائم أن تتضمّن أنواعًا مختلفة، ولكن عادة ما تكون العناصر كلها من النوع نفسه.<br />
<br />
=== [[Python/set|المجموعات (set)]] ===<br />
مجموعة من الكائنات غير المرتّبة وغير المكرّرة وغير القابلة للتعديل (immutable).<br />
<br />
=== [[Python/dict|القواميس (dict)]] ===<br />
القواميس هي مجاميع غير مرتّبة من أزواج (مفتاح: قيمة) <code>(key: value)</code>.<br />
<br />
=== [[Python/bytes|البايتات (bytes)]] ===<br />
البايتات هي تسلسلات لبايتات مفردة غير قابلة للتغيير (immutable)، وهي مشابهة إلى حدّ كبير للسلاسل النصية.<br />
<br />
=== [[Python/bytearray|مصفوفات البايتات (bytesarray)]] ===<br />
مصفوفات البايتات bytearray هي الكائنات القابلة للتغيير والتي تقابل كائنات [[Python/bytes|البايتات bytes]].<br />
<br />
== العمليات Operations ==<br />
<br />
=== [[Python/bool-operators|العمليات المنطقية (Boolean Operations)]] ===<br />
تقدّم بايثون ثلاث عمليات منطقية هي <code>or</code> و <code>and</code> و <code>not</code>.<br />
<br />
=== [[Python/comparisons|عمليات المقارنة (Comparison Operations)]] ===<br />
تقدّم بايثون ثمان عمليات للمقارنة، وتمتلك جميعها نفس الأولوية (وهي أعلى من العمليات المنطقية).<br />
<br />
=== [[Python/numeric_operations|العمليات العددية (Numeric Operations)]] ===<br />
تدعم بايثون شأنها في ذلك شأن بقية اللغات البرمجية جميع العمليات الحسابية المعروفة، وتدعم جميع الأنواع العددية (باستثناء [[Python/complex|الأعداد المركبة]])<br />
<br />
=== [[Python/bitwise_operations|عمليات الأعداد الثنائية (Bitwise Operations)]] ===<br />
يمكن إجراء عمليات الأعداد الثنائية Bitwise على <nowiki/>[[Python/int|الأعداد الصحيحة]] فقط.<br />
<br />
=== [[Python/sequence_operations|عمليات التسلسلات (Sequence Operations)]] ===<br />
تدعم بايثون مجموعة من العمليات الخاصة بالتسلسلات ([[Python/list|القوائم]]، <nowiki/>[[Python/tuples|الصفوف]]، <nowiki/>[[Python/str|السلاسل النصية]]، <nowiki/>[[Python/bytes|والبايتات]] و<nowiki/>[[Python/bytearray|مصفوفات البايتات]]).<br />
<br />
=== [[Python/byte_bytearray_operations|عوامل البايتات ومصفوفات البايتات (Byte and Bytesarray Operations)]] ===<br />
تدعم كائنات <nowiki/>[[Python/bytes|البايتات]] و<nowiki/>[[Python/bytearray|مصفوفات البايتات]] <nowiki/>[[Python/sequence_operations|عمليات التسلسلات]] الشائعة، وتتوافق هذه الكائنات مع العوامل من النوع ذاته إضافة إلى أي كائن شبيه بالبايتات.<br />
<br />
=== [[Python/set_operations|عمليات المجموعات (Sets operations)]] ===<br />
تقدّم بايثون مجموعة من العمليات الخاصة [[Python/set|بالمجموعات]] و<nowiki/>[[Python/set#.D8.A7.D9.84.D9.85.D8.AC.D9.85.D9.88.D8.B9.D8.A7.D8.AA .D8.A7.D9.84.D8.AC.D8.A7.D9.85.D8.AF.D8.A9 .28frozenset.29|المجموعات الجامدة]].<br />
<br />
== بنى التحكم ==<br />
<br />
=== [[Python/if|If]] ===<br />
تقدّم بايثون عبارة <code>if</code> للتحكم المشروط بتدفق الشيفرة.<br />
<br />
=== [[Python/for|for]] ===<br />
عبارة <code>for</code> في بايثون تمرّ على عناصر أي تسلسل (قائمة أو سلسلة نصية) معتمدة في ذلك على ترتيب تلك العناصر في ذلك التسلسل.<br />
<br />
=== [[Python/while|while]] ===<br />
تستمر عبارة <code>while</code> في العمل ما دام الشرط الذي تعمل على أساسه صحيحًا.<br />
<br />
=== [[Python/pass|pass]] ===<br />
لا تؤدي عبارة <code>pass</code> أي عمل على الإطلاق، ويمكن استخدام هذه العبارة عند الحاجة إلى استخدام عبارة معينة ولكن دون الحاجة إلى أداء أي وظيفة.<br />
<br />
=== [[Python/looping techniques|طرق استخدام الحلقات التكرارية]] ===<br />
تقدّم بايثون مجموعة من الدوال والتوابع التي تسهّل عملية إنشاء الحلقات التكرارية والاستفادة منها بصورة فعّالة في <nowiki/>[[Python/dict|القواميس]] و<nowiki/>[[Python/list|القوائم]] وغيرها.<br />
<br />
== الدوال ==<br />
<br />
=== [[Python/defining_functions|تعريف الدوال]] ===<br />
تُعرَّف الدوال باستخدام الكلمة المفتاحية <code>def</code> يتبعها اسم الدالة ثم قائمة بالمعاملات محاطة بالأقواس. أما الكتلة الرئيسية للدالة فتبدأ في السطر التالي لسطر التعريف، ويجب أن تزاح بمقدار إزاحة واحدة.<br />
<br />
=== [[Python/arguments|معاملات الدوال]] ===<br />
يمكن تعريف الدوال مع عدد غير محدّد من المعاملات.<br />
<br />
=== [[Python/lambda_expressions|تعابير lambda]] ===<br />
يمكن إنشاء دوال لا تحمل أسماء باستخدام الكلمة المفتاحية lambda.<br />
<br />
=== [[Python/documentation_strings|سلاسل التوثيق النصية]] ===<br />
يمكن أن تكون العبارة الأولى في كتلة الدالة سلسلة نصّية، وتمثّل سلسلة التوثيق النصية الخاصة بتلك الدالة ويطلق عليها أيضًا تسمية docstring، ستخدم سلاسل التوثيق النصية لإنتاج توثيق عبر شبكة الإنترنت، أو تسمح للمستخدم بتصفح الشيفرة بصورة تفاعلية.<br />
<br />
== الأصناف ==<br />
<br />
=== [[Python/class|مقدمة]] ===<br />
تعدّ الأصناف وسيلة لجمع البيانات والعمليات في بوتقة واحدة، ويؤدي إنشاء صنف جديد إلى تكوين نوع جديد من الكائنات، ما يتيح إنشاء نسخ (instances) من ذلك النوع. يمكن أن ترتبط بكلّ صنف مجموعة من الخاصيات (attributes) التي تساعد في متابعة حالة الصنف، إضافة إلى مجموعة من التوابع (methods) التي تساعد في تعديل حالة ذلك الصنف.<br />
<br />
=== [[Python/scopes-and-namespaces|النطاقات ومجالات الأسماء]] ===<br />
مجال الأسماء هو رابط بين الأسماء والكائنات، ومن الأمثلة على مجالات الأسماء: مجموعة الأسماء الداخلية، الأسماء العامة (global) في وحدة معينة، والأسماء المحلية (local) في بنية دالّة ما. أما النطاق فهو جزء من شيفرة بايثون يمكن فيه الوصول إلى مجال الأسماء بصورة مباشرة.<br />
<br />
=== [[Python/class_definition|تعريف الأصناف]] ===<br />
تستخدم الكلمة المفتاحية <code>class</code> لتعريف الأصناف الجديدة في بايثون.<br />
<br />
=== [[Python/inhertance|الوراثة]] ===<br />
تدعم بايثون شأنها في ذلك شأن أي لغة برمجية كائنية التوجه مفهوم الوراثة، وتدعم كذلك إعادة تعريف (override) التوابع الموروثة من الأصناف الأساسية إضافة إلى الوراثة المتعددة.<br />
<br />
=== [[Python/private_variables|المتغيرات الخاصّة private variables]] ===<br />
متغيرات الأصناف الخاصة (Private) والتي لا يمكن الوصول إليها من خارج الكائن غير موجودة في بايثون. ولكن يتفق معظم المبرمجين على أنّ الاسم المسبوق بشرطة سفلية (مثل: <code>_spam</code>) يجب أن يُعامل كجزء غير عام من الواجهة البرمجية (سواء أكان ذلك الجزء دالة أو تابعًا أو خاصية). <br />
<br />
=== [[Python/iterators|المكررات iterators]] ===<br />
المكرّرات هي أساس عمل حلقات <code>[[Python/for|for]]</code> التكرارية، ويمكن تخصيص عمل هذه الحلقات التكرارية عن طريق تعريف مكررات جديدة.<br />
<br />
=== [[Python/generators|المولّدات generators]] ===<br />
المولّدات هي أداة بسيطة وقوية لإنشاء المكرِّرات. تأخذ المولِّدات صيغة الدوال العادية ولكنّها تستخدم عبارة <code>yield</code> عند إعادة البيانات.<br />
<br />
== الوحدات modules ==<br />
<br />
=== [[Python/modules|الوحدات]] ===<br />
تقدّم بايثون طريقة لإضافة التعريفات في ملف مستقل واستخدامها في شيفرة مستقلّة أو في <nowiki/>[[Python/interpreter|مفسّر بايثون]] التفاعلي. تسمى هذه الملفات بالوحدات Modules.<br />
<br />
=== [[Python/dir|الدالة <code>()dir</code>]] ===<br />
تستخدم الدالة الداخلية <code>dir()</code> لمعرفة الأسماء التي تعرّفها الوحدة، وتعيد هذه الداة <nowiki/>[[Python/list|قائمة]] مرتّبة من <nowiki/>[[Python/str|السلاسل النصية]].<br />
<br />
=== [[Python/packages|الحزم packages]] ===<br />
تعدّ الحزم طريقة لهيكلة <nowiki/>[[Python/scopes-and-namespaces|مجالات أسماء]] الحزم في بايثون، وتساعد في تجنب حدوث أي تضارب بين أسماء الوحدات في الحزم متعدّدة الوحدات مثل: [http://www.numpy.org/ NumPy] أو مكتبة بايثون لمعالجة الصور [https://pillow.readthedocs.io/ Python Imaging Library].<br />
<br />
== [[Python/standard_modules|الوحدات القياسية في بايثون]] ==<br />
تقدّم بايثون مكتبة تضمّ مجموعة من الوحدات القياسية (standard modules) وبعضها مدمج مع [[Python/interpreter|مفسّر بايثون]] وتتيح الوصول إلى عمليات هي ليست في الأصل جزءًا من اللغة، ولكن الهدف منها هو إما زيادة كفاءة عمل المفسّر أو لإتاحة الوصول إلى العمليات الأساسية في نظام التشغير مثل استدعاءات النظام (system calls).<br />
<br />
=== [[Python/re|الوحدة <code>re</code> في بايثون]] ===<br />
تقّدم الوحدة مجموعة من العمليات الخاصة بمطابقة التعابير النمطية Regular Expressions وهي مشابهة إلى حدّ كبير للعمليات الموجودة في لغة Perl.<br />
<br />
=== [[Python/string|الوحدة <code>string</code> في بايثون]] ===<br />
<br />
تضمّ الوحدة عددًا من الثوابت والأصناف المفيدة في معالجة السلاسل النصية.<br />
<br />
=== [[Python/datetime|الوحدة <code>datetime</code> في بايثون]] ===<br />
تقدّم هذه الوحدة عددًا من الأصناف التي تعالج التاريخ والوقت بطرق مبسّطة وأخرى معقدة، وتدعم بايثون إجراء العمليات الحسابية على التواريخ والأوقات.<br />
<br />
=== [[Python/calendar|الوحدة <code>calendar</code> في بايثون]] ===<br />
تتيح هذه الوحدة الحصول على تقاويم مشابهة لمخرجات البرنامج cal في أنظمة يونكس، إلى جانب أنّها تقدّم عددًا من التوابع المفيدة والخاصة بالتقاويم.<br />
<br />
=== [[Python/bisect|الوحدة <code>bisect</code> في بايثون]] ===<br />
تقدّم هذه الوحدة وسيلة للتعامل مع القوائم وفرزها بصورة تلقائية، وبذلك يمكن تجنب إعادة فرز القائمة بعد كل عملية إدراج للعناصر فيها. <br />
<br />
=== [[Python/heapq|الوحدة <code>heapq</code> في بايثون]] ===<br />
تقدّم هذه الوحدة وسيلة لاستخدام خوارزمية طابور الكومة heap queue والتي تعرف كذلك بخوارزمية طابور الأولوية priority queue.<br />
<br />
=== [[Python/enum|الوحدة <code>enum</code> في بايثون]] ===<br />
enumeration هو مجموعة من الأسماء الرمزية (العناصر) المرتبطة بقيم ثابتة وفريدة. يمكن مقارنة عناصر enumeration عن طريق هويتها، ويمكن المرور على عناصره بواسطة حلقة تكرارية.<br />
<br />
=== [[Python/itertools|الوحدة <code>itertools</code> في بايثون]] ===<br />
تقّدم مجموعة من الأدوات المُساعدة على بناء مُكرّرات مُشابهة لتلك المتوفّرة في لغات مثل APL، وHaskell وSML. بُني كلّ منها بطريقة تُناسب لغة بايثون. <br />
<br />
=== [[Python/functools|الوحدة <code>functools</code> في بايثون]] ===<br />
تُقدّم دوال عاليّة الرّتبة (higher-order functions)، وهي دوال تستقبل دوالا أخرى، تُغيّرها، أو تُعيد دوال أخرى. وعلى العموم، يُمكن لأيّ كائن قابل للاستدعاء أن يُعامل مُعاملة الدّالة عند استخدام هذه الوحدة. <br />
<br />
=== [[Python/operator|الوحدة <code>operator</code> في بايثون]] ===<br />
تُقدّم مجموعة من الدوال الفعالّة سرعةً وأداءً، والتي تُماثل العوامل الأساسيّة في بايثون.<br />
<br />
=== [[Python/collections|الوحدة <code>collections</code> في بايثون]] ===<br />
تتضمّن هذه الوحدة أنواع بيانات متخصّصة بالحاويات containers وتقدّم بدائل للحاويات الداخلية <nowiki/>[[Python/dict|<code>dict</code>]] و <nowiki/>[[Python/list|<code>list</code>]] و <nowiki/>[[Python/set|<code>set</code>]] و <nowiki/>[[Python/tuple|<code>tuple</code>]].<br />
<br />
=== [[Python/collections.abc|الوحدة <code>collections.abc</code> في بايثون]] ===<br />
تقدّم هذه الوحدة مجموعة من الأصناف الأساسية المجرّدة abstract base calsses (يرمز لها ABC اختصارًا) والتي يمكن استخدامها للتأكد ممّا إذا كان صنف معيّن يقدّم واجهة interface معينة، كأن يكون الصنف قابلًا للتقطيع hashable أو أنّه صنف ربط mapping.<br />
<br />
=== [[Python/pprint|الوحدة <code>pprint</code> في بايثون]] ===<br />
تتيح وحدة <code>pprint</code> إمكانية طباعة بنى البيانات في بايثون بصورة جميلة pretty-print بطريقة تسمح باستخدام هذه البيانات كمدخلات في مفسّر بايثون.<br />
<br />
=== [[Python/copy|الوحدة <code>copy</code> في بايثون]] ===<br />
تقدّم هذه الوحدة مجموعة من عمليات النسخ السطحية والعميقة.<br />
<br />
=== [[Python/types|الوحدة <code>types</code> في بايثون]] ===<br />
تقدّم هذه الوحدة عددًا من الدوال المساعدة لإنشاء أنواع بيانات جديدة بصورة ديناميكية.<br />
<br />
=== [[Python/weakref|الوحدة <code>weakref</code> في بايثون]] ===<br />
تتيح الوحدة إنشاء إشارات ضعيفة weak references للكائنات.<br />
<br />
=== [[Python/reprlib|الوحدة <code>reprlib</code> في بايثون]] ===<br />
تقدّم الوحدة وسيلة لإنتاج تمثيلات للكائنات مع إمكانية تحديد حجم السلسلة النصية الناتجة.<br />
<br />
=== [[Python/array|الوحدة <code>array</code> في بايثون]] ===<br />
تعرف هذه الوحدة كائنًا يمكن عن طريقه تمثيل مصفوفة من القيم الأساسية مثل الحروف والأعداد الصحيحة والأعداد ذات الفاصلة العائمة بشكل مضغوط.<br />
<br />
=== [[Python/sqlite3|الوحدة <code>sqlite3</code> في بايثون]] ===<br />
تقدّم هذه الوحدة واجهة برمجية للتعامل مع قواعد بيانات SQLite3.<br />
<br />
=== [[Python/copyreg|الوحدة <code>copyreg</code> في بايثون]] ===<br />
تقدّم الوحدة طريقة لتعريف دوال تستخدم أثناء سلسلة كائنات معيّنة في بايثون. <br />
<br />
=== [[Python/marshal|الوحدة <code>marshal</code> في بايثون]] ===<br />
تضمّ هذه الوحدة مجموعة من الدوال التي يمكنها قراءة وكتابة قيم بايثون بالصيغة الثنائية binary format.<br />
<br />
=== [[Python/zlib|الوحدة <code>zlib</code> في بايثون]] ===<br />
تتيح الدوال المتوفّرة في هذه الوحدة إجراء عمليات الضغط وفك الضغط على البيانات باستخدام مكتبة zlib.<br />
<br />
=== [[Python/gzip|الوحدة <code>gzip</code> في بايثون]] ===<br />
تقدّم هذه الوحدة واجهة بسيطة لضغط الملفات وفك ضغطها بنفس الأسلوب المتّبع في برنامجي gzip و gunzip في GNU. وتجري عملية ضغط البيانات بواسطة [[Python/zlib|وحدة <code>zlib</code>]].<br />
<br />
=== [[Python/bz2|الوحدة <code>bz2</code> في بايثون]] ===<br />
تقدّم هذه الوحدة واجهة متكاملة لضغط البيانات وفك الضغط عنها باستخدام خوارزمية الضغط bzip2.<br />
<br />
=== [[Python/lzma|الوحدة <code>lzma</code> في بايثون]] ===<br />
تقدّم هذه الوحدة مجموعة من الأصناف والدوال المساعدة لإجراء عمليات ضغط البيانات وفك الضغط عنها باستخدام خوارزمية الضغط LZMA.<br />
<br />
=== [[Python/zipfile|الوحدة <code>zipfile</code> في بايثون]] ===<br />
تقدّم هذه الوحدة أدواة لإنشاء ملفات ZIP والقراءة منها والكتابة فيها وإلحاق الملفات بها وعرض محتوياتها. <br />
<br />
=== [[Python/tarfile|الوحدة <code>tarfile</code> في بايثون]] ===<br />
تتيح وحدة tarfile قراءة ملف أرشيف من نوع tar والكتابة فيه إلى جانب ملفات الأرشيف التي تستخدم تقنية الضغط gzip و bz2 و lzma.<br />
<br />
=== [[Python/csv|الوحدة <code>csv</code> في بايثون]] ===<br />
تقدّم وحدة <code>csv</code> عددًا من الأصناف التي تساعد في قراءة البيانات المجدولة وكتابتها بصيغة CSV.<br />
<br />
=== [[Python/configparser|الوحدة <code>configparser</code> في بايثون]] ===<br />
تقدّم هذه الوحدة صنفًا يستخدم لغة إعدادات بسيطة تقدّم بنية مشابهة للبنية التي تقدّمها ملفات INI في نظام Microsoft Windows. ويمكن استخدام هذا الصنف لكتابة برامج وتطبيقات يمكن للمستخدمين تخصيصها بكل سهولة.<br />
<br />
=== [[Python/webbrowser|الوحدة <code>webbrowser</code> في بايثون]] ===<br />
تقدّم وحدة <code>webbrowser</code> واجهة متطوّرة تسمح بعرض مستندات الويب على المستخدمين.<br />
<br />
=== [[Python/cgi|الوحدة <code>cgi</code> في بايثون]] ===<br />
تقدّم هذه الوحدة عددًا من الأدوات التي تستخدم بواسطة سكربتات CGI المكتوبة في بايثون.<br />
<br />
=== [[Python/cgitb|الوحدة <code>cgitb</code> في بايثون]] ===<br />
تقدم وحدة <code>cgitb</code> أداة خاصة للتعامل مع الاستثناءات في سكربتات بايثون.<br />
<br />
=== [[Python/wsgiref|الوحدة <code>wsgiref</code> في بايثون]] ===<br />
تعدّ الوحدة <code>wsgiref</code> وسيلة لتطبيق معايير WSGI ويمكن استخدامها لإضافة دعم WSGI إلى مخدّمات الويب وأطر العمل البرمجية.<br />
<br />
== المدخلات والمخرجات Inputs and Outputs ==<br />
<br />
=== [[Python/formatting_output|تنسيق المخرجات]] ===<br />
تقدّم بايثون عددًا من الطرائق التي تساعد في تنسيق مخرجات البرامج، فيمكن طباعة البيانات بصيغة سهلة القراءة، أو يمكن كتابة البيانات في ملف لاستخدامه في المستقبل. <br />
<br />
=== [[Python/reading_writing_files|قراءة الملفات والكتابة فيها]] ===<br />
تتيح بايثون قراءة الملفات والكتابة فيها بنمطين مختلفين هما النصي والثنائي. <br />
<br />
=== [[Python/saving_json|حفظ البيانات المهيكلة بصيغة json]] ===<br />
تتيح بايثون استخدام صيغة تبادل البيانات المعروفة JSON (اختصار JavaScript Object Notation)، باستخدام الوحدة القياسية <code>json</code> .<br />
<br />
== [[Python/constants|الثوابت]] ==<br />
تقدم بايثون مجموعة من الثوابت، بعضها في <nowiki/>[[Python/scopes-and-namespaces|مجال الأسماء]] الداخلي، أما البعض الآخر فيضاف من قبل الوحدة <code>site</code> إلى <nowiki/>[[Python/interpreter|مفسّر بايثون]] التفاعلي.<br />
<br />
== الأخطاء والاستثناءات ==<br />
<br />
=== [[Python/syntax_errors|أخطاء الصيغة]] ===<br />
قد تكون أخطاء الصيغة (Syntax errors) أو ما يعرف أيضًا بأخطاء الإعراب (Parsing errors) هي أكثر نوع من الأخطاء التي يواجهها المبتدئون عند تعلّم بايثون.<br />
<br />
=== [[Python/exceptions|الاستثناءات]] ===<br />
قد تكون التعابير البرمجية في الشيفرة صحيحة من ناحية الصيغة، إلا أنّها قد تتسبب في حدوث أخطاء عند محاولة تنفيذها. تسمّى الأخطاء المُكتشفة أثناء تنفيذ الشيفرة بالاستثناءات (exceptions) وقد تتسبب في إيقاف عمل البرنامج (fatal) في بعض الأحيان.<br />
<br />
=== [[Python/user-defined_exceptions|الاستثناءات المعرفة من طرف المستخدم]] ===<br />
يمكن للمستخدم إنشاء صنف استثناء جديد (راجع قسم <nowiki/>[[Python/class|الأصناف في بايثون]] للمزيد من المعلومات)، ويجب أن تكون <nowiki/>[[Python/exceptions|الاستثناءات]] <nowiki/>[[Python/inhertance|مشتقّة من الصنف]] <code>Exception</code> سواء أكان ذلك بصورة مباشرة أو غير مباشرة.<br />
<br />
=== [[Python/defining_clean-up_actions|تعريف أحداث التنظيف clean-up actions]] ===<br />
تمتلك عبارة <code>try</code> جزءًا اختياريًا آخر، والهدف منه هو تعريف أحداث تنظيف (clean-up actions) يجب تنفيذها في جميع الظروف، وتعرّف بعض الكائنات أحداث تنظيف قياسية يجري تنفيذها عند انتفاء الحاجة لذلك الكائن، وبغض النظر عمّا إذا كانت العملية التي تستخدم ذلك الكائن ناجحة أم فاشلة.<br />
<br />
== [[Python/coding-style|تنسيق الشيفرة البرمجية]] ==<br />
تتّبع معظم المشاريع المكتوبة بلغة بايثون دليل التنسيق [https://www.python.org/dev/peps/pep-0008 PEP8] والذي يشجّع على اعتماد تنسيق يمتاز بالمقروئية العالية والمظهر الجميل.</div>عاطف-بن-عليhttps://wiki.hsoub.com/index.php?title=Python&diff=28287Python2019-03-22T05:15:11Z<p>عاطف-بن-علي: اقتراح تعديلات واصلاح بعض الأخطاء الإملائية.</p>
<hr />
<div>لغة Python هي لغة عالية المستوى مُفسَّرة ذات مجالٍ عام، وهي مرنةٌ وتحاول التعبير عن المفاهيم البرمجية بأقل قدر ممكن من الشيفرات. تدعم لغة Python البرمجة الكائنية والبرمجة الإجرائية، وفيها مكتبة قياسية كبيرة.<br />
<br />
لغة Python هي لغةٌ مفتوحة المصدر، ومدعومةٌ من أغلبية أنظمة التشغيل.<br />
<br />
== لمحة عن Python ==<br />
إن كنت تنجز الكثير من الأعمال باستخدام الحاسوب، فستجد نفسك بحاجة إلى تأدية بعض المهام بصورة أوتوماتيكية. فعلى سبيل المثال قد ترغب في إنجاز عملية بحث واستبدال على عدد كبير من الملفات، أو إعادة تسمية وترتيب مجموعة من ملفات الصور وبطريقة معقدة. قد ترغب ربّما بكتابة قاعدة بيانات صغيرة، أو إنشاء تطبيق يمتلك واجهة رسومية خاصّة، أو حتى لعبة صغيرة.<br />
<br />
إن كنت من المحترفين في مجال تطوير البرمجيات فإنّك ستلجأ على الأرجح إلى استخدام العديد من مكتبات اللغات C/C++/Java ولكنّك ستجد أنّ عمليات الكتابة ثم التصريف ثم الاختبار ثم إعادة التصريف قد أصبحت سلسلة من العمليات المتكررة البطيئة للغاية.<br />
<br />
لربّما كنت تكتب حزمة اختبار لمثل هكذا مكتبة فوجدت أن كتابة شيفرة الاختبار أمر متعب للغاية، أو أنّك كتبت برنامجًا بمقدوره استخدام لغة ملحقة، ولكنّك لا ترغب بتصميم وتضمين لغة جديدة للتطبيق.<br />
<br />
كل ما سبق هو ما تقوم به لغة بايثون.<br />
<br />
يمكنك كتابة شيفرة صدفة في أنظمة يونكس (Unix) أو كتابة ملفات batch في نظام ويندوز (Windows) لأداء بعض من المهمات التي ذكرناها سابقًا، ولكن شيفرات الصدفة (shell scripts) ملائمة لنقل الملفات وإجراء التعديلات على البيانات النصية، وهي ليست ملائمةً إطلاقًا للتطبيقات ذات الواجهات الرسومية أو الألعاب. يمكنك أن تكتب برنامجًا باستخدام اللغات C/C++/Java ولكنّ قد تأخذ عملية النسخة الأولية وقتًا طويلًا. تمتاز لغة بايثون بسهولة الاستخدام، وتوفّرها في أنظمة Windows، و Mac OS X و Unix، وستساعدك في إنجاز أعمالك بسرعة أكبر.<br />
<br />
بايثون سهلة الاستخدام، ولكنّها في الوقت عينه لغة برمجية حقيقية، تقدّم دعمًا وبنية أكبر للبرامج الكبيرة من شيفرات الصدفة أو ملفات batch. ومن جانب آخر، تقدّم بايثون قدرة أكبر على تفحّص الأخطاء من لغة C، ونظرًا لكون بايثون لغة من المستوى العالي جدًّا، فإنّها تتضمّن أنواعًا ذات مستوى عالٍ أيضًا، كالمصفوفات المرنة والقواميس. ولمّا كانت الأنواع أكثر شمولية في بايثون فبالإمكان الاستفادة من اللغة في حل مشاكل أكبر من تلك التي يمكن حلّها بواسطة لغات مثل Awk أو حتى Perl، ومع ذلك فإنّ الأمور تكون في بايثون على أقلّ تقدير بنفس سهولة اللغتين السابقتين.<br />
<br />
تتيح بايثون تقسيم البرنامج إلى حزم متعددة يمكن إعادة استخدامها في برامج بايثون أخرى، وتمتلك اللغة مجموعة كبيرة من الحزم الأساسية التي يمكن استخدامها أساسا لبرامجك، أو أمثلة تساعدك في البدء بتعلّم البرمجة بواسطة بايثون. تقدّم بعض هذه الحزم أمورًا مثل نظام المدخلات والمخرجات للملفات file I/O، استدعاءات النظام، sockets وحتى واجهات لبعض حزم الواجهات مثل Tk.<br />
<br />
بايثون هي لغة مفسّرة (interpreted، وليست مبنية [compiled]) ما يتيح توفير الكثير من الوقت أثناء عملية التطوير نظرًا لانتفاء الحاجة إلى إجراء عملية التصريف والربط. يمكن استخدام المفسِّر بصورة تفاعلية، الأمر الذي يسهّل التعامل مع الخصائص التي تقدّمها اللغة، ولكتابة برامج لغرض التدريب أو الاختبار، أو لاختبار دالة أثناء عملية تطوير برنامج ما، إضافة إلى إمكانية استخدام المفسّر كآلة حاسبة.<br />
<br />
تتيح بايثون كتابة البرامج بأسلوب مختصر ومقروء، فالبرامج المكتوبة في بايثون تكون عادة أقصر بكثير من مكافئاتها في لغات C، أو C++، أو Java، ولعدّة أسباب:<br />
* تتيح أنواع البيانات ذات المستوى العالي إمكانية استخدام تعابير معقدّة في عبارة واحدة.<br />
* يجري تجميع العبارات باستخدام الإزاحات، بدلًا من أقواس البداية والنهاية.<br />
* لا حاجة للتصريح عن نوع المتغير أو الوسيط.<br />
بايثون قابلة للتجديد: إن كنت تجيد البرمجة باستخدام لغة C فمن السهل حينئذٍ أن تضيف دالة ضمنية إلى اللغة أو حزمة جديدة إلى المفسر، وذلك إمّا لتأدية المهام الضرورية بأقصى سرعة، أو لربط برامج بايثون مع المكتبات التي تكون متوفّرة بالصيغة الثنائية فقط (مثل مكتبات الرسوميات الخاصّة بالشركة). وعند إجراء عملية الربط يصبح بالإمكان ربط مفسِّر بايثون بتطبيق مكتوب بلغة C واستخدامه كأداة ملحقة أو كلغة أوامر في ذلك التطبيق.<br />
<br />
سمّيت لغة بايثون بهذا الاسم تيمّنًا بعرض السيرك الذي كانت تقدّمه قناة BBC والذي يحمل الاسم «Monty Python’s Flying Circus» ولا رابط بينه وبين الحيوانات الزاحفة.<br />
<br />
{{:Python/Topics}}<br />
[[تصنيف:Python]]</div>عاطف-بن-عليhttps://wiki.hsoub.com/index.php?title=Laravel/deployment&diff=27467Laravel/deployment2019-02-02T08:42:15Z<p>عاطف-بن-علي: استبدال ترجمة server بخادوم.</p>
<hr />
<div><noinclude>{{DISPLAYTITLE:النشر على الخادم الإنتاجي في Laravel}}</noinclude><br />
== مقدمة ==<br />
عندما تكون جاهزًا لنشر تطبيق [[Laravel]] على الخادوم الإنتاجي، هناك بعض الأشياء المهمة التي يمكنك القيام بها للتأكد من تشغيل التطبيق بأقصى كفاءة ممكنة. في هذا المستند، سنغطي بعض نقاط البداية الرائعة للتأكد من نشر تطبيق [[Laravel]] بشكل صحيح.<br />
<br />
== ضبط الخادوم ==<br />
<br />
=== [[Nginx]] ===<br />
إذا كنت تقوم بنشر تطبيقك على خادوم Nginx، فيمكنك استخدام ملف التهيئة التالي كنقطة بداية لتهيئة خادوم الويب الخاص بك. على الأرجح، يجب تخصيص هذا الملف بناءً على تهيئة خادومك. إذا كنت ترغب في المساعدة في إدارة الخادوم الخاص بك، فكر في استخدام خدمة مثل Laravel Forge:<syntaxhighlight lang="php"><br />
server {<br />
listen 80;<br />
server_name example.com;<br />
root /example.com/public;<br />
<br />
add_header X-Frame-Options "SAMEORIGIN";<br />
add_header X-XSS-Protection "1; mode=block";<br />
add_header X-Content-Type-Options "nosniff";<br />
<br />
index index.html index.htm index.php;<br />
<br />
charset utf-8;<br />
<br />
location / {<br />
try_files $uri $uri/ /index.php?$query_string;<br />
}<br />
<br />
location = /favicon.ico { access_log off; log_not_found off; }<br />
location = /robots.txt { access_log off; log_not_found off; }<br />
<br />
error_page 404 /index.php;<br />
<br />
location ~ \.php$ {<br />
fastcgi_split_path_info ^(.+\.php)(/.+)$;<br />
fastcgi_pass unix:/var/run/php/php7.1-fpm.sock;<br />
fastcgi_index index.php;<br />
include fastcgi_params;<br />
}<br />
<br />
location ~ /\.(?!well-known).* {<br />
deny all;<br />
}<br />
}<br />
</syntaxhighlight><br />
<br />
== التحسين ==<br />
<br />
=== تحسين المحمل التلقائي ===<br />
عند النشر على الخادوم الإنتاجي، تأكد من أنك تقوم بتحسين خريطة المحمل الآلي لبرمجية composer حتى يتمكن composer من العثور بسرعة على الملف المناسب للتحميل الصنف المعين:<syntaxhighlight lang="text"><br />
composer install --optimize-autoloader --no-dev<br />
</syntaxhighlight>بالإضافة إلى تحسين أداة التحميل التلقائي، يجب التأكد دائمًا من تضمين ملف <code>composer.lock</code> في مستودع التحكم في مصدر المشروع. يمكن تثبيت اعتماديات مشروعك بسرعة أكبر عندما يكون ملف <code>composer.lock</code> موجودًا.<br />
<br />
=== تحسين ضبط التحميل ===<br />
عند نشر التطبيق الخاص بك على الخادوم الإنتاجي، يجب عليك التأكد من تشغيل الأمر <code>config:cache Artisan</code>:<syntaxhighlight lang="php"><br />
php artisan config:cache<br />
</syntaxhighlight>سيعمل هذا الأمر على جمع جميع ملفات الضبط الخاصة بإطار [[Laravel]] في ملف واحد مخزنٌ تخزينًا مؤقتًا مما يؤدي إلى تقليل عدد الحركات التي يجب أن يقوم بها إطار العمل على نظام الملفات عندما تُحمَّل قيم خيارات الضبط.<br />
<br />
إذا قمت بتنفيذ الأمر <code>config:cache</code> أثناء عملية النشر على الخادوم الإنتاجي، فيجب أن تتأكد من أنك تقوم فقط بالاتصال بالدالة <code>env</code> من داخل ملفات الضبط الخاصة بك. بمجرد تخزين الضبط المؤقت، فلن يُحمِّل الملف <code>.env</code> وستُعيد كافة الإستدعاءات إلى الدالة <code>env</code> القيمة <code>null</code>.<br />
<br />
=== تحسين تحميل المسارات ===<br />
إذا كنت تقوم بإنشاء تطبيق كبير مع العديد من المسارات (routes)، يجب عليك التأكد من تشغيل الأمر <code>route:cache Artisan</code> أثناء عملية النشر على الخادوم الإنتاجي:<syntaxhighlight lang="php"><br />
php artisan route:cache<br />
</syntaxhighlight>هذا الأمر يقلل من عمليات تسجيل المسارات الخاصة بك من خلال استدعاء تابع وحيد ويتم تخزينه في ملف تخزين مؤقت، مما يؤدي إلى تحسين أداء تسجيل المسارات عند تسجيل مئات المسارات.<br />
<br />
نظرًا لأن هذه الميزة تستخدم [[PHP/serialization|سَلسَلة PHP]] (أي PHP serialization)، فإنه بإمكانك تخزين مسارات التطبيقات التي على وجه الحصر تستخدم المسارات التي تعتمد على التحكم (controller based routes). لأن [[PHP]] ليست قادرة على سَلسَلة النطاقات المغلقة (closures).<br />
<br />
=== النشر على الخادوم الإنتاجي مع منصة Forge ===<br />
إذا لم تكن مستعدًا تمامًا لإدارة تهيئة الخادوم الخاصة بك أو لم تكن مرتاحًا لتكوين جميع الخدمات المتنوعة اللازمة لتشغيل تطبيق Laravel القوي، فإن Laravel Forge بديل رائع.<br />
<br />
يمكن لخدمة Laravel Forge إنشاء خوادم على العديد من مزودي البنية الأساسية مثل DigitalOcean و Linode و AWS والمزيد. بالإضافة إلى ذلك، يقوم Forge بتثبيت وإدارة جميع الأدوات اللازمة لبناء تطبيقات [[Laravel]] قوية، مثل [[Nginx]] و [[MySQL]] و [[Redis]] و [[Memcached]] و [[Beanstalk]] والمزيد.<br />
<br />
== مصادر ==<br />
* [https://laravel.com/docs/5.6/deployment صفحة Deployment في توثيق Laravel الرسمي.]<br />
[[تصنيف:Laravel|{{SUBPAGENAME}}]]<br />
[[تصنيف:Laravel Getting started|{{SUBPAGENAME}}]]</div>عاطف-بن-عليhttps://wiki.hsoub.com/index.php?title=Laravel/Topics&diff=27466Laravel/Topics2019-02-02T08:37:43Z<p>عاطف-بن-علي: /* النشر على الخادم الإنتاجي */</p>
<hr />
<div>== البدء باستخدام Laravel ==<br />
=== [[Laravel/installation|التثبيت]] ===<br />
شرح متطلبات الخادم، وكيفية تثبيت Laravel وضبط خادم الويب.<br />
<br />
=== [[Laravel/configuration|الضبط]] ===<br />
كيفية ضبط إطار Laravel، والدخول في وضع الصيانة.<br />
<br />
=== [[Laravel/structure|بنية المجلدات في Laravel]] ===<br />
التعرّف على بنية المجلدات الموجودة في إطار Laravel ووظيفة كلٍّ منها.<br />
<br />
=== [[Laravel/homestead|بيئة Laravel Homestead]] ===<br />
التعرف على طريقة استخدام Laravel Homestead لتسهيل توفير بيئة متكاملة تشغِّل إطار Laravel.<br />
<br />
=== [[Laravel/valet|بيئة تطوير Valet Laravel]] ===<br />
بيئة Valet Laravel تشبه بيئة Laravel Homestead لكنها مخصصة لأجهزة ماك.<br />
<br />
=== [[Laravel/deployment|النشر على الخادوم الإنتاجي]] ===<br />
شرح النقاط المهمة التي يجب الانتباه إليها عند نشر تطبيق Laravel على خادومٍ إنتاجي.<br />
<br />
== المفاهيم البنيوية ==<br />
=== [[Laravel/lifecycle|دورة حياة الطلب (Request Lifecycle)]] ===<br />
أخذ نظرة عالية المستوى عمّا يجري داخل إطار Laravel لتفهم آلية عمله فهمًا جيدًا.<br />
<br />
=== [[Laravel/container|حاوي الخدمات (Service Container)]] ===<br />
شرح طريقة إضافة الاعتماديات باستخدام حاوي الخدمات.<br />
<br />
=== [[Laravel/providers|مقدمو الخدمات (Service Providers)]] ===<br />
شرح مفهوم تقديم الخدمات، وكيفية تسجيل مقدمي الخدمات.<br />
<br />
=== [[Laravel/facades|الواجهات الساكنة (Facades)]] ===<br />
شرح مفهوم الواجهات الساكنة ومتى نستخدمها، وكيفية عملها.<br />
<br />
=== [[Laravel/contracts|العقود (Contracts)]] ===<br />
شرح مفهوم العقود ومتى نستخدمها، وكيفية عملها.<br />
<br />
== الأساسيات ==<br />
=== [[Laravel/routing|التوجيه (Routing)]] ===<br />
شرح أساسيات التوجيه المستعملة في إطار Laravel.<br />
===[[Laravel/middleware|البرمجيات الوسيطة (Middleware)]]===<br />
كيفية تعريف وتسجيل البرمجيات الوسيطة التي توفِّر آلية لفرز طلبيات HTTP.<br />
===[[Laravel/csrf|الحماية من هجمات CSRF]]===<br />
سبل الحماية من هجمات تزوير الطلب العابر للمواقع.<br />
===[[Laravel/controllers|وحدات التحكّم (Controllers)]]===<br />
تعريف وحدات التحكم والفائدة منها وطريقة استعمالها.<br />
===[[Laravel/requests|طلبات HTTP]]===<br />
التعامل مع طلبات HTTP في Laravel.<br />
===[[Laravel/responses|ردود HTTP]]===<br />
التعامل مع ردود HTTP في Laravel.<br />
===[[Laravel/views|الواجهات (Views)]]===<br />
كيفية إنشاء الواجهات وطريقة تمرير البيانات إليها.<br />
===[[Laravel/urls|توليد عناوين URL]]===<br />
طريقة توليد روابط URL لمختلف أجزاء تطبيقك.<br />
===[[Laravel/session|جلسات HTTP]]===<br />
شرح كيفية تخزين البيانات في الجلسات واستردادها، وخلاف ذلك من المواضيع المرتبطة بالجلسات.<br />
===[[Laravel/validation|التحقق (Validation)]]===<br />
كيفية التحقق من صحة البيانات الواردة إلى التطبيق.<br />
===[[Laravel/errors|معالجة الأخطاء (Error Handling)]]===<br />
شرح كيف يعالج إطار Laravel الأخطاء.<br />
===[[Laravel/logging|التسجيل (Logging)]]===<br />
ضبط Laravel لتسجيل الرسائل على ملفات أو في سجل النظام أو إلى قناة Slack مخصصة.<br />
<br />
== الواجهة الأمامية ==<br />
=== [[Laravel/blade|قوالب Blade]] ===<br />
التعريف بمحرك القولبة الخاص بإطار Laravel و شرح كيفيّة استخدامه.<br />
<br />
=== [[Laravel/localization|التوطين]] ===<br />
شرح طريقة التوطين في Laravel.<br />
<br />
=== [[Laravel/frontend|بناء Javascript و CSS]] ===<br />
شرح كيفية تعامل Laravel مع الواجهات الأمامية.<br />
<br />
=== [[Laravel/mix|ترجمة الأصول (Laravel Mix)]] ===<br />
كيفيّة معالجة الأصول في تطبيق Laravel.<br />
<br />
== الأمان والحماية ==<br />
=== [[Laravel/authentication|الاستيثاق (Authentification)]] ===<br />
شرح برمجة نظام الاستيثاق وطرقه.<br />
<br />
=== [[Laravel/passport|الاستثياق باستخدام واجهة API خارجية (API Authentification)]] ===<br />
شرح برمجة نظام الاستيثاق باستخدام واجهة برمجية خارجية.<br />
<br />
=== [[Laravel/authorization|الترخيص (Authorization)]] ===<br />
كيفيّة ترخيص عمليات المستخدم على مورد معين.<br />
<br />
=== [[Laravel/encryption|التشفير (Encryption)]] ===<br />
شرح كيف يشفّر Laravel البيانات.<br />
<br />
=== [[Laravel/hashing|التجزئة (Hashing)]] ===<br />
التعرّف على كيفيّة التجزئة لتخزين كلمات مرور المستخدم.<br />
<br />
=== [[Laravel/passwords|إعادة تعيين كلمات المرور (Password Reset)]] ===<br />
شرح طرق إعادة تعيين كلمات المرور المنسية.<br />
<br />
== التعمق في Laravel ==<br />
=== [[Laravel/artisan|الأمر Artisan console) Artisan)]] ===<br />
التعريف بواجهة الأوامر المُرفقة ب Laravel.<br />
<br />
=== [[Laravel/broadcasting|البث (Broadcasting)]] ===<br />
كيفيّة بثّ الأحداث عن طريق websocket.<br />
<br />
=== [[Laravel/cache|التخزين المؤقت (Cache)]] ===<br />
التعريف بالواجهات البرمجيّة الخاصة بالتخزين المؤقت.<br />
<br />
=== [[Laravel/collections|المجموعات (Collections)]] ===<br />
كيفيّة التعامل مع مصفوفات البيانات عن طريق المجموعات.<br />
<br />
=== [[Laravel/events|الأحداث (Events)]] ===<br />
التعريف بالأحداث والمنصتات وكيفيّة التعامل معهنّ.<br />
<br />
=== [[Laravel/filesystem|تخزين الملفات (File storage)]] ===<br />
شرح كيف يخزن Laravel الملفات.<br />
<br />
=== [[Laravel/helpers|الدوال المساعدة (Helpers)]] ===<br />
التعريف بالدوال المساعدة وطريقة استعمالهنّ.<br />
<br />
=== [[Laravel/mail|التعامل مع البريد الإلكتروني (Mail)]] ===<br />
شرح كيف يتعامل Laravel مع الرسائل الإلكترونية.<br />
<br />
=== [[Laravel/notifications|الإشعارات (Notifications)]] ===<br />
شرح كيف يتعامل Laravel مع الإشعارات.<br />
<br />
=== [[Laravel/packages|الحزم (Package development)]] ===<br />
التعريف بالحزم وطريقة استخدامها.<br />
<br />
=== [[Laravel/queues|طوابير الانتظار (Queues)]] ===<br />
شرح طريقة التعامل مع طوابير الانتظار.<br />
<br />
=== [[Laravel/scheduling|جدولة المهام (Task scheduling)]] ===<br />
تعريف جدولة المهام وبيان كيفيّتها.<br />
<br />
== قواعد البيانات ==<br />
=== [[Laravel/database|مقدمة إلى التعامل مع قواعد البيانات]] ===<br />
شرح أساسيات التعامل مع قواعد البيانات في إطار Laravel.<br />
<br />
=== [[Laravel/queries|منشئ الاستعلامات]] ===<br />
التعريف بمنشئ الاستعلامات في Laravel وكيفيّة عمله.<br />
<br />
=== [[Laravel/pagination|ترقيم الصفحات Pagination]] ===<br />
شرح كيفيّة ترقيم الصفحات مع بيان استخداماته.<br />
<br />
=== [[Laravel/migrations|تهجير قاعدة البيانات]] ===<br />
تعريف تهجير قاعدة البيانات وشرح كيفيّته.<br />
<br />
=== [[Laravel/seeding|بذر قواعد البيانات بالبيانات الاختبارية Seeding]] ===<br />
شرح كيفيّة بذر قواعد البيانات بالبيانات الاختبارية.<br />
<br />
=== [[Laravel/redis|التعامل مع قواعد بيانات Redis]] ===<br />
كيفيّة استخدام Redis مع إطار Laravel.<br />
<br />
== رابط الكائنات بالعلاقات Eloquent ==<br />
=== [[Laravel/eloquent|مقدمة إلى رابط الكائنات بالعلاقات Eloquent]] ===<br />
التعريف برابط الكائنات بالعلاقات Eloquent المضمّن في Laravel.<br />
<br />
=== [[Laravel/eloquent_relationships|العلاقات في رابط الكائنات بالعلاقات Eloquent]] ===<br />
شرح مفهوم العلاقات في رابط الكائنات بالعلاقات Eloquent مع بيان كيفيّة استخدامهنّ.<br />
<br />
=== [[Laravel/eloquent_collections|المجموعات في رابط الكائنات بالعلاقات Eloquent]] ===<br />
تعريف المجموعات في رابط الكائنات بالعلاقات Eloquent.<br />
<br />
=== [[Laravel/eloquent_mutators|المعدلات في رابط الكائنات بالعلاقات Eloquent]] ===<br />
التعريف بالمعدلات والموصلات في رابط الكائنات بالعلاقات Eloquent وشرح طريقة استعمالهنّ.<br />
<br />
=== [[Laravel/eloquent_resources|الموارد في رابط الكائنات بالعلاقات Eloquent]] ===<br />
تعريف الموارد في رابط الكائنات بالعلاقات Eloquent.<br />
<br />
=== [[Laravel/eloquent_serialization|السلسلة في رابط الكائنات بالعلاقات Eloquent]] ===<br />
شرح كيفيّة السلسلة في رابط الكائنات بالعلاقات Eloquent.<br />
<br />
== الاختبار ==<br />
=== [[Laravel/testing|مقدمة إلى التعامل مع الاختبارات]] ===<br />
التعريف ببيئة الاختبارات في Laravel.<br />
<br />
=== [[Laravel/http_tests|اختبارات HTTP]] ===<br />
شرح كيفية اختبارات HTTP.<br />
<br />
=== [[Laravel/dusk|اختبارات المتصفح (Laravel Dusk)]] ===<br />
كيفيّة أتمتة المتصفّح واختبار الواجهات البرمجيّة.<br />
<br />
=== [[Laravel/database_testing|اختبارات قواعد البيانات]] ===<br />
شرح أساسيات اختبارات قواعد البيانات.<br />
<br />
=== [[Laravel/mocking|تزييف الأحداث لأغراض الاختبار Mocking]] ===<br />
شرح مفهوم تزييف الأحداث للاختبار مع بيان طرقه.<br />
<br />
== الحزم الرسمية ==<br />
=== [[Laravel/billing|Laravel Cashier]] ===<br />
التعريف بحزمة اشتراكات خدمات الفواتير Stripe و Braintree.<br />
<br />
=== [[Laravel/envoy|مشغِّل المهام Envoy]] ===<br />
التعريف بمشغّل المهام وكيفيّة ضبطه.<br />
<br />
=== [[Laravel/horizon|Laravel Horizon]] ===<br />
التعريف بحزمة التحكم في نظام الطوابير.<br />
<br />
=== [[Laravel/passport|الاستثياق باستخدام واجهة API خارجية]] ===<br />
شرح برمجة نظام الاستيثاق باستخدام واجهة برمجية خارجية.<br />
<br />
=== [[Laravel/scout|Laravel Scout]] ===<br />
التعريف بحزمة البحث عن نص كامل في نماذج Eloquent وكيفيّة ضبطها.<br />
<br />
=== [[Laravel/socialite|Laravel Socialite]] ===<br />
التعريف بحزمة الاستيثاق مع موفري OAuth وكيفيّة ضبطها.</div>عاطف-بن-عليhttps://wiki.hsoub.com/index.php?title=Laravel/configuration&diff=27465Laravel/configuration2019-02-02T08:35:21Z<p>عاطف-بن-علي: /* ضبط البيئة */</p>
<hr />
<div><noinclude>{{DISPLAYTITLE:الضبط في Laravel}}</noinclude><br />
== مقدمة ==<br />
جميع ملفات الضبط الخاصة بإطار عمل [[Laravel]] موجودة في المسار <code>config</code>. وجميع الخيارات موثّقة، لذا لا تتردد في النظر في ملفات [[Laravel]] والتعرف على جميع الخيارات المتاحة لك.<br />
<br />
== ضبط البيئة ==<br />
غالباً ما يكون من المفيد الحصول على قيم ضبط مختلفة بناءً على البيئة التي يعمل عليها التطبيق. على سبيل المثال، قد ترغب في استخدام برنامج ذاكرة تخزين مؤقتة مختلفة محليًا عمّا هو مضبوطٌ في الخادوم الإنتاجي الخاص بك.<br />
<br />
للقيام بهكذا أمر، يستخدم [[Laravel]] مكتبة <code>DotEnv PHP</code>. عند تثبيت Laravel جديد، سيحتوي المجلد الجذر للتطبيق الخاص بك على ملف <code>env.example.</code> إذا قمت بتثبيت [[Laravel]] باستخدام Composer، فستُعاد تسمية هذا الملف تلقائيًا إلى <code>.env</code>. خلاف ذلك، يجب إعادة تسمية الملف يدويًا.<br />
<br />
ليس بالضرورة أن يتم حفظ ملف <code>.env</code> في نظام إدارة إصدارات لوحة تحكم التطبيق الخاص بك، إذ قد يحتاج كل مطور/خادوم يستخدم التطبيق الخاص بك إلى تهيئة بيئة مختلفة. علاوةً على ذلك، فإن هذا من شأنه أن يشكل خطرًا على الأمان في حالة وصول دخيل إلى مستودع التحكم في المصدر، نظرًا لإمكانيّة كشف أية معلومات حساسة.<br />
<br />
إذا كنت تقوم بالتطوير مع فريق، فقد ترغب في الاستمرار في تضمين الملف <code>.env.example</code> مع التطبيق الخاص بك. من خلال وضع قيم بديلة وهمية في ملف تكوين المثال، يمكن لمطوري البرامج الآخرين في فريقك أن يروا بوضوح متغيرات البيئة المطلوبة لتشغيل التطبيق الخاص بك. يمكنك أيضًا إنشاء ملف <code>.env.testing</code>. سيتجاوز هذا الملف ملف <code>.env</code> عند تشغيل اختبارات PHPUnit أو تنفيذ الأمر Artisan باستخدام خيار <code>env=testing--</code>.<br />
<br />
ملاحظة: يمكن تجاوز أي متغير في ملف <code>env.</code> الخاص بك بواسطة متغيرات البيئة الخارجية مثل متغيرات البيئة على مستوى الخادوم أو مستوى النظام.<br />
<br />
=== أنواع البيئة المتغيرة ===<br />
تُحلَّل جميع المتغيرات في ملفات <code>env.</code> الخاصة بك بصفتها سلاسل نصية، لذلك أُنشِئَت بعض القيم المحجوزة للسماح لك بإعادة نطاق أوسع من الأنواع من الدالة <code>env()</code>:<br />
{| class="wikitable"<br />
!قيمة .env<br />
!قيمة env()<br />
|-<br />
|true<br />
|bool) true)<br />
|-<br />
|(true)<br />
|bool) true)<br />
|-<br />
|false<br />
|bool) false)<br />
|-<br />
|(false)<br />
|bool) false)<br />
|-<br />
|empty<br />
|" (string) <br />
|-<br />
|(empty)<br />
|" (string) <br />
|-<br />
|null<br />
|null) null)<br />
|-<br />
|(null)<br />
|null) null)<br />
|}<br />
إذا كنت بحاجة إلى تعريف متغير بيئة بقيمة تحتوي على مسافات، فيمكنك القيام بذلك عن طريق إحاطة القيمة بعلامات اقتباس مزدوجة.<syntaxhighlight lang="text"><br />
"APP_NAME="My Application<br />
</syntaxhighlight><br />
<br />
=== استرجاع ضبط البيئة ===<br />
ستُحمَّل جميع المتغيرات المدرجة في هذا الملف في المتغير العام <code>$_ENV</code> عندما يتلقى مشروعك طلبًا. ومع ذلك، يمكنك استخدام المساعد <code>env</code> لاسترداد القيم من هذه المتغيرات في ملفات الضبط الخاصة بك. في الواقع، إذا قمت بمراجعة ملفات ضبط [[Laravel]]، ستلاحظ العديد من الخيارات التي تستخدم بالفعل هذا المتغير:<syntaxhighlight lang="text"><br />
'debug' => env('APP_DEBUG', false),<br />
</syntaxhighlight>القيمة الثانية التي مُرِّرَت إلى الدالة <code>env</code> هي "القيمة الافتراضية". سيتم استخدام هذه القيمة في حالة عدم وجود متغير بيئة للمفتاح المحدد.<br />
<br />
=== تحديد البيئة الحالية ===<br />
تحدد بيئة التطبيق الحالية عبر المتغير <code>APP_ENV</code> من الملف <code>.env</code>. يمكنك الوصول إلى هذه القيمة من خلال التابع <code>environment</code> على [[Laravel/facades|الواجهة الساكنة]] (facade) App:<syntaxhighlight lang="text"><br />
$environment = App::environment();<br />
</syntaxhighlight><br />
<br />
يمكنك أيضًا تمرير الوسائط إلى التابع <code>environment</code> للتحقق مما إذا كانت البيئة تتطابق مع قيمة معينة. سيُعيد هذا التابع القيمة <code>true</code> إذا كانت البيئة مطابقة لأي من القيم المعطاة:<syntaxhighlight lang="php"><br />
if (App::environment('local')) {<br />
// بيئة التطوير المحلية<br />
<br />
}<br />
<br />
if (App::environment(['local', 'staging'])) {<br />
<br />
// إما أن تكون البيئة هي بيئة التطوير أو بيئة الخادوم التخزيني<br />
<br />
}<br />
<br />
<br />
</syntaxhighlight><br />
<br />
ملاحظة: يمكن تجاوز الكشف عن بيئة التطبيق الحالية من خلال متغير بيئة <code>APP_ENV</code> على مستوى الخادوم. يمكن أن يكون ذلك مفيدًا عندما تحتاج إلى مشاركة نفس التطبيق في بيئات مضبوطة ضبطًا مختلفًا، بحيث يمكنك إعداد مضيف معين لمطابقة بيئة معينة لضبط الخادوم الخاص بك.<br />
<br />
== الوصول إلى قيم الضبط ==<br />
يمكنك الوصول إلى قيم الضبط بسهولة باستخدام الدالة المساعدة العامة <code>config</code> من أي مكان في التطبيق الخاص بك. يمكن الوصول إلى قيم الضبط باستخدام صيغة «النقطة» (dot syntax)، والتي تتضمن اسم الملف والخيار الذي ترغب في الوصول إليه. قد تُحدَّد قيمة افتراضية أيضًا، وستُعاد إذا لم يكن خيار الضبط موجودًا:<syntaxhighlight lang="php"><br />
$value = config ('app.timezone');<br />
</syntaxhighlight>لتعيين قيم الضبط في وقت التشغيل، مرِّر مصفوفةً إلى الدالة المساعدة <code>config</code>:<syntaxhighlight lang="php"><br />
config(['app.timezone' => 'America/Chicago']);<br />
</syntaxhighlight><br />
<br />
== ضبط التخزين المؤقت ==<br />
لإعطاء تطبيقك سرعة مضاعفة، يجب تخزين جميع ملفات التهيئة في ملف واحد باستخدام الأمر Artisan الآتي <code>config: cache</code>. سيؤدي هذا الأمر إلى دمج جميع خيارات الضبط لتطبيقك في ملف واحد والذي سيُحمَّل تحميله بسرعة بواسطة إطار العمل.<br />
<br />
يجب أن تُعيد تشغيل الأمر <code>php artisan config: cache</code> كجزء من عملية نشر التطبيق الخاص بك على الخادوم الإنتاجي. يجب ألا يُشغَّل الأمر أثناء التطوير المحلي إذ ستحتاج إلى تغيير خيارات الضبط بشكل متكرر أثناء تطوير التطبيق الخاص بك.<br />
<br />
إذا نفّذتَ الأمر <code>config:cache</code> أثناء عملية النشر، فيجب أن تتأكد من أنك تستدعي الدالة <code>env</code> من داخل ملفات الضبط الخاصة بك. بمجرد تخزين الضبط المؤقت، لن يتم تحميل الملف <code>.env</code> وكافة استدعاءات الدالة <code>env</code> ستُعيد <code>[[PHP/null|null]]</code>.<br />
<br />
== وضع الصيانة ==<br />
عندما يكون التطبيق في وضع الصيانة، سيتم عرض واجهة مخصصة لجميع طلبات التطبيق. هذا يجعل من السهل "تعطيل" التطبيق الخاص بك أثناء تحديث أو عند إجراء الصيانة. يتم تضمين فحص وضع الصيانة في حزمة البرامج الوسيطة الافتراضية للتطبيق الخاص بك. إذا كان التطبيق في وضع الصيانة، سيرمى الاستثناء <code>MaintenanceModeException</code> مع رمز الحالة 503.<br />
<br />
لتمكين وضع الصيانة، نفِّذ <code>down</code> من خلال الأمر Artisan:<syntaxhighlight lang="php"><br />
php artisan down<br />
</syntaxhighlight>يمكنك أيضًا توفير الخيارات <code>message</code> و <code>retry</code> إلى الأمر <code>down</code>. يمكن استخدام قيمة <code>message</code> لعرض أو تسجيل رسالة خاصة، بينما سيتم تعيين قيمة <code>retry</code> كقيمة <code>Retry-After</code> لترويسة HTTP:<syntaxhighlight lang="php"><br />
php artisan down --message="Upgrading Database" --retry=60<br />
</syntaxhighlight>حتى في حالة الصيانة، قد يتم السماح لعناوين IP أو شبكات محددة بالوصول إلى التطبيق باستخدام الخيار <code>allow</code>:<syntaxhighlight lang="php"><br />
php artisan down --allow=127.0.0.1 --allow=192.168.0.0/16<br />
</syntaxhighlight>لتعطيل وضع الصيانة، استخدم الأمر <code>up</code>:<syntaxhighlight lang="php"><br />
php artisan up<br />
</syntaxhighlight>ملاحظة: يمكنك تخصيص قالب وضع الصيانة الافتراضي عن طريق تعريف القالب الخاص بك في <code>resources/views/errors/503.blade.php</code>.<br />
<br />
=== وضع الصيانة والطوابير ===<br />
بينما يكون التطبيق الخاص بك في وضع الصيانة، لن يتم التعامل مع أي مهمة في قائمة الانتظار. سيستمر التعامل مع المهام كالمعتاد بمجرد انتهاء التطبيق من وضع الصيانة.<br />
<br />
=== بدائل وضع الصيانة ===<br />
نظرًا لأن وضع الصيانة يتطلب أن يحتوي التطبيق على عدة ثوانٍ من وقت التوقف، ففكر في بدائل مثل Envoyer لإنجاز النشر بدون توقف مع [[Laravel]].<br />
<br />
== مصادر ==<br />
* [https://laravel.com/docs/5.6/configuration صفحة Configuration في توثيق Laravel الرسمي.]<br />
[[تصنيف:Laravel|{{SUBPAGENAME}}]]<br />
[[تصنيف:Laravel Getting started|{{SUBPAGENAME}}]]</div>عاطف-بن-عليhttps://wiki.hsoub.com/index.php?title=Laravel/installation&diff=27464Laravel/installation2019-02-02T08:27:09Z<p>عاطف-بن-علي: /* خادوم Nginx */</p>
<hr />
<div><noinclude>{{DISPLAYTITLE:تثبيت Laravel }}</noinclude><br />
== متطلبات الخادوم ==<br />
يتطلب إطار [[Laravel]] بعض متطلبات النظام. بالطبع ، يتم استيفاء جميع هذه المتطلبات من خلال النظام الوهمي لبيئة -Laravel (باسم [[Laravel/homestead|Homestead]])- لذلك يوصى باستخدام بيئة [[Laravel/homestead|Homestead]] بيئة تطوير [[Laravel]] المحلية الخاصة بك.<br />
<br />
ومع ذلك، إذا لم تكن بيئة [[Laravel/homestead|Homestead]] متاحةً لك أو لم ترغب في استخدامها، فستحتاج إلى التأكد من أن الخادوم يلبي المتطلبات التالية:<br />
* PHP >= 7.1.3<br />
* ملحق OpenSSL PHP<br />
* ملحق PDO PHP<br />
* ملحق Mbstring PHP<br />
* ملحق Tokenizer PHP<br />
* ملحق XML PHP<br />
* ملحق Ctype PHP<br />
* ملحق JSON PHP<br />
<br />
== تثبيت Laravel ==<br />
يستخدم إطار العمل [[Laravel]] برمجية Composer لإدارة الاعتماديات. لذا تأكد من تثبيت Composer على حاسوبك، قبل استخدام [[Laravel]].<br />
<br />
=== باستخدام مُثبِّت [[Laravel]] ===<br />
حمّل أوّلًا مثبّت [[Laravel]] باستخدام Composer :<syntaxhighlight lang="text"><br />
composer global require "laravel/installer"<br />
<br />
</syntaxhighlight>احرص على إضافة مجلد <code>vendor/bin</code> الخاصة ببرنامج Composer إلى متغير البيئة <code>$PATH</code> بحيث يمكن تحديد موقع الملف القابل للتنفيذ لإطار عمل [[Laravel]] بواسطة النظام الخاص بك. يوجد هذا المجلد في مواقع مختلفة اعتمادًا على نظام التشغيل الخاص بك؛ ومع ذلك، من الشائع أن يوجد في المسارات الآتية:<br />
<br />
· في نظام ماك: في المسار <code>$HOME/.composer/vendor/bin</code><br />
<br />
· في توزيعات لينكس: في المسار <code>$HOME/.config/composer/vendor/bin</code><br />
<br />
بعد تثبيته، سيُنشِئ الأمر <code>laravel new</code> مجلدًا يحتوي على نسخة جديدة من إطار [[Laravel]]. على سبيل المثال ، سيُنشِئ الأمر <code>laravel new blog</code> مجلدًا جديدًا باسم blog يحتوي على تثبيت [[Laravel]] جديد مع جميع اعتماديات [[Laravel]] اللازمة.<syntaxhighlight lang="text"><br />
laravel new blog<br />
</syntaxhighlight><br />
<br />
=== باستخدام Composer ===<br />
بدلا عن ذلك، يمكنك أيضًا تثبيت [[Laravel]] بتنفيذ الأمر <code>create-project</code> الخاص ببرمجية Composer في الطرفية على جهازك:<syntaxhighlight lang="text"><br />
composer create-project --prefer-dist laravel/laravel blog<br />
</syntaxhighlight><br />
<br />
=== باستخدام خادوم التطوير المحلي ===<br />
إذا كنت قد قمت بتثبيت [[PHP]] محليًا وترغب في استخدام خادوم التطوير الخاص بلغة PHP لتخديم تطبيقك، فيمكنك استخدام الأمر <code>Artisan serve</code>. سيبدأ هذا الأمر خادوم تطوير على<code><nowiki>http://localhost:8000</nowiki></code>:<syntaxhighlight lang="text"><br />
php artisan serve<br />
</syntaxhighlight>بالطبع، تتوفر خيارات التطوير المحلية الأكثر قوة من خلال [[Laravel/homestead|Homestead]] و [[Laravel/valet|Valet]].<br />
<br />
== الضبط ==<br />
<br />
=== المجلد العام ===<br />
بعد تثبيت [[Laravel]] ، يجب عليك ضبط جذر لخادوم الويب الخاص بك ليكون المجلد public. يعمل الملف <code>index.php</code> في هذا المسار بصفته وحدة تحكم أمامية لجميع طلبات HTTP التي تدخل التطبيق الخاص بك.<br />
<br />
=== ملفات الضبط ===<br />
تُخزَّن كافة ملفات الضبط الخاصة بإطار [[Laravel]] في مجلد <code>config.</code> كل خيار من تلك الخيارات موثقٌ توثيقًا كاملًا، لذلك لا تتردد في إلقاء نظرة على الملفات والتعرف على الخيارات المتاحة لك.<br />
<br />
=== أذونات المجلد ===<br />
بعد تثبيت Laravel، قد تحتاج إلى ضبط بعض الأذونات (permissions). يجب أن تكون المجلدات داخل مجلد storage ومجلد <code>bootstrap/cache</code> قابلةً للكتابة بواسطة خادوم الويب أو فلن يعمل Laravel. إذا كنت تستخدم بيئة عمل [[Laravel/homestead|Homestead]]، فستكون الأذونات المطلوبة مضبوطةً مسبقًا.<br />
<br />
=== مفتاح التطبيق ===<br />
أول ما عليك فعله بعد تثبيت Laravel هو ضبط مفتاح التطبيق الخاص بك إلى سلسلة نصية عشوائية. إذا قمت بتثبيت [[Laravel]] باستخدام Composer أو مثبت Laravel، فقد ضُبِطَ هذا المفتاح لك باستخدام الأمر <code>php artisan key:generate</code>.<br />
<br />
يجب أن تكون هذه السلسلة بطول 32 محرفًا عادةً. يمكن تعيين المفتاح في ملف البيئة .env. إذا لم تُعِد تسمية الملف <code>.env.example</code> إلى <code>.env</code>، فيجب عليك القيام بذلك الآن. إذا لم يُضبَط مفتاح التطبيق، فلن تكون جلسات المستخدم الخاصة بك وغيرها من البيانات المشفرة آمنة!<br />
<br />
=== الضبط الإضافي ===<br />
لا يحتاج Laravel إلى أي ضبط آخر مبدئيًا. يمكنك البدء بالتطوير فورًا. ومع ذلك، قد ترغب في مراجعة الملف <code>config/app.php</code> وتوثيقه. هذا الملف يحتوي على العديد من الخيارات مثل المنطقة الزمنية (timezone) والمحليّة (locale ) والتي قد ترغب في تغييرها وفقًا لتطبيقك.<br />
<br />
قد ترغب أيضًا في تكوين بعض المكونات الإضافية في [[Laravel]]، مثل:<br />
* ذاكرة التخزين المؤقتة<br />
* قاعدة البيانات<br />
* الجلسة<br />
<br />
== ضبط خادوم الويب ==<br />
<br />
=== عناوين URL جذابة ===<br />
<br />
==== خادوم [[Apache]] ====<br />
يتضمن Laravel الملف <code>public/.htaccess</code> الذي يُستخدم لتوفير عناوين URL دون وحدة التحكم <code>index.php</code> الأمامية في المسارات. قبل تخديم <nowiki/>[[Laravel]] مع [[Apache]]، تأكد من تفعيل الوحدة <code>mod_rewrite</code> بحيث تُنفَّذ محتويات ملف <code>.htaccess</code> بواسطة الخادوم.<br />
<br />
إذا كان ملف <code>.htaccess</code> الذي يأتي مع [[Laravel]] لا يعمل مع تثبيت [[Apache]] عندك، فجرّب هذا الملف البديل:<syntaxhighlight lang="text"><br />
Options+FollowSymLinks<br />
RewriteEngine On<br />
RewriteCond %{REQUEST_FILENAME} !-d<br />
RewriteCond %{REQUEST_FILENAME} !-f<br />
RewriteRule ^ index.php [L]<br />
<br />
<br />
</syntaxhighlight><br />
<br />
==== خادوم <nowiki/>[[Nginx]] ====<br />
إذا كنت تستخدم خادوم [[Nginx]]، فإن تعليمة الضبط الآتية في ملف ضبط موقعك سيوجه جميع الطلبات إلى <br />
<br />
وحدة التحكم الأمامية <code>index.php</code>:<syntaxhighlight lang="php"><br />
location / {<br />
try_files $uri $uri/ /index.php?$query_string;<br />
}<br />
</syntaxhighlight>بالطبع، عند استخدام [[Laravel/homestead|Homestead]] أو [[Laravel/valet|Valet]]، سيتم ضبط عناوين URL جذابة تلقائيًا.<br />
<br />
== مصادر ==<br />
* [https://laravel.com/docs/5.6/installation صفحة Installation في توثيق Laravel الرسمي.]<br />
[[تصنيف:Laravel|{{SUBPAGENAME}}]]<br />
[[تصنيف:Laravel Getting started|{{SUBPAGENAME}}]]</div>عاطف-بن-عليhttps://wiki.hsoub.com/index.php?title=Laravel/installation&diff=27463Laravel/installation2019-02-02T08:26:35Z<p>عاطف-بن-علي: /* مفتاح التطبيق */</p>
<hr />
<div><noinclude>{{DISPLAYTITLE:تثبيت Laravel }}</noinclude><br />
== متطلبات الخادوم ==<br />
يتطلب إطار [[Laravel]] بعض متطلبات النظام. بالطبع ، يتم استيفاء جميع هذه المتطلبات من خلال النظام الوهمي لبيئة -Laravel (باسم [[Laravel/homestead|Homestead]])- لذلك يوصى باستخدام بيئة [[Laravel/homestead|Homestead]] بيئة تطوير [[Laravel]] المحلية الخاصة بك.<br />
<br />
ومع ذلك، إذا لم تكن بيئة [[Laravel/homestead|Homestead]] متاحةً لك أو لم ترغب في استخدامها، فستحتاج إلى التأكد من أن الخادوم يلبي المتطلبات التالية:<br />
* PHP >= 7.1.3<br />
* ملحق OpenSSL PHP<br />
* ملحق PDO PHP<br />
* ملحق Mbstring PHP<br />
* ملحق Tokenizer PHP<br />
* ملحق XML PHP<br />
* ملحق Ctype PHP<br />
* ملحق JSON PHP<br />
<br />
== تثبيت Laravel ==<br />
يستخدم إطار العمل [[Laravel]] برمجية Composer لإدارة الاعتماديات. لذا تأكد من تثبيت Composer على حاسوبك، قبل استخدام [[Laravel]].<br />
<br />
=== باستخدام مُثبِّت [[Laravel]] ===<br />
حمّل أوّلًا مثبّت [[Laravel]] باستخدام Composer :<syntaxhighlight lang="text"><br />
composer global require "laravel/installer"<br />
<br />
</syntaxhighlight>احرص على إضافة مجلد <code>vendor/bin</code> الخاصة ببرنامج Composer إلى متغير البيئة <code>$PATH</code> بحيث يمكن تحديد موقع الملف القابل للتنفيذ لإطار عمل [[Laravel]] بواسطة النظام الخاص بك. يوجد هذا المجلد في مواقع مختلفة اعتمادًا على نظام التشغيل الخاص بك؛ ومع ذلك، من الشائع أن يوجد في المسارات الآتية:<br />
<br />
· في نظام ماك: في المسار <code>$HOME/.composer/vendor/bin</code><br />
<br />
· في توزيعات لينكس: في المسار <code>$HOME/.config/composer/vendor/bin</code><br />
<br />
بعد تثبيته، سيُنشِئ الأمر <code>laravel new</code> مجلدًا يحتوي على نسخة جديدة من إطار [[Laravel]]. على سبيل المثال ، سيُنشِئ الأمر <code>laravel new blog</code> مجلدًا جديدًا باسم blog يحتوي على تثبيت [[Laravel]] جديد مع جميع اعتماديات [[Laravel]] اللازمة.<syntaxhighlight lang="text"><br />
laravel new blog<br />
</syntaxhighlight><br />
<br />
=== باستخدام Composer ===<br />
بدلا عن ذلك، يمكنك أيضًا تثبيت [[Laravel]] بتنفيذ الأمر <code>create-project</code> الخاص ببرمجية Composer في الطرفية على جهازك:<syntaxhighlight lang="text"><br />
composer create-project --prefer-dist laravel/laravel blog<br />
</syntaxhighlight><br />
<br />
=== باستخدام خادوم التطوير المحلي ===<br />
إذا كنت قد قمت بتثبيت [[PHP]] محليًا وترغب في استخدام خادوم التطوير الخاص بلغة PHP لتخديم تطبيقك، فيمكنك استخدام الأمر <code>Artisan serve</code>. سيبدأ هذا الأمر خادوم تطوير على<code><nowiki>http://localhost:8000</nowiki></code>:<syntaxhighlight lang="text"><br />
php artisan serve<br />
</syntaxhighlight>بالطبع، تتوفر خيارات التطوير المحلية الأكثر قوة من خلال [[Laravel/homestead|Homestead]] و [[Laravel/valet|Valet]].<br />
<br />
== الضبط ==<br />
<br />
=== المجلد العام ===<br />
بعد تثبيت [[Laravel]] ، يجب عليك ضبط جذر لخادوم الويب الخاص بك ليكون المجلد public. يعمل الملف <code>index.php</code> في هذا المسار بصفته وحدة تحكم أمامية لجميع طلبات HTTP التي تدخل التطبيق الخاص بك.<br />
<br />
=== ملفات الضبط ===<br />
تُخزَّن كافة ملفات الضبط الخاصة بإطار [[Laravel]] في مجلد <code>config.</code> كل خيار من تلك الخيارات موثقٌ توثيقًا كاملًا، لذلك لا تتردد في إلقاء نظرة على الملفات والتعرف على الخيارات المتاحة لك.<br />
<br />
=== أذونات المجلد ===<br />
بعد تثبيت Laravel، قد تحتاج إلى ضبط بعض الأذونات (permissions). يجب أن تكون المجلدات داخل مجلد storage ومجلد <code>bootstrap/cache</code> قابلةً للكتابة بواسطة خادوم الويب أو فلن يعمل Laravel. إذا كنت تستخدم بيئة عمل [[Laravel/homestead|Homestead]]، فستكون الأذونات المطلوبة مضبوطةً مسبقًا.<br />
<br />
=== مفتاح التطبيق ===<br />
أول ما عليك فعله بعد تثبيت Laravel هو ضبط مفتاح التطبيق الخاص بك إلى سلسلة نصية عشوائية. إذا قمت بتثبيت [[Laravel]] باستخدام Composer أو مثبت Laravel، فقد ضُبِطَ هذا المفتاح لك باستخدام الأمر <code>php artisan key:generate</code>.<br />
<br />
يجب أن تكون هذه السلسلة بطول 32 محرفًا عادةً. يمكن تعيين المفتاح في ملف البيئة .env. إذا لم تُعِد تسمية الملف <code>.env.example</code> إلى <code>.env</code>، فيجب عليك القيام بذلك الآن. إذا لم يُضبَط مفتاح التطبيق، فلن تكون جلسات المستخدم الخاصة بك وغيرها من البيانات المشفرة آمنة!<br />
<br />
=== الضبط الإضافي ===<br />
لا يحتاج Laravel إلى أي ضبط آخر مبدئيًا. يمكنك البدء بالتطوير فورًا. ومع ذلك، قد ترغب في مراجعة الملف <code>config/app.php</code> وتوثيقه. هذا الملف يحتوي على العديد من الخيارات مثل المنطقة الزمنية (timezone) والمحليّة (locale ) والتي قد ترغب في تغييرها وفقًا لتطبيقك.<br />
<br />
قد ترغب أيضًا في تكوين بعض المكونات الإضافية في [[Laravel]]، مثل:<br />
* ذاكرة التخزين المؤقتة<br />
* قاعدة البيانات<br />
* الجلسة<br />
<br />
== ضبط خادوم الويب ==<br />
<br />
=== عناوين URL جذابة ===<br />
<br />
==== خادوم [[Apache]] ====<br />
يتضمن Laravel الملف <code>public/.htaccess</code> الذي يُستخدم لتوفير عناوين URL دون وحدة التحكم <code>index.php</code> الأمامية في المسارات. قبل تخديم <nowiki/>[[Laravel]] مع [[Apache]]، تأكد من تفعيل الوحدة <code>mod_rewrite</code> بحيث تُنفَّذ محتويات ملف <code>.htaccess</code> بواسطة الخادوم.<br />
<br />
إذا كان ملف <code>.htaccess</code> الذي يأتي مع [[Laravel]] لا يعمل مع تثبيت [[Apache]] عندك، فجرّب هذا الملف البديل:<syntaxhighlight lang="text"><br />
Options+FollowSymLinks<br />
RewriteEngine On<br />
RewriteCond %{REQUEST_FILENAME} !-d<br />
RewriteCond %{REQUEST_FILENAME} !-f<br />
RewriteRule ^ index.php [L]<br />
<br />
<br />
</syntaxhighlight><br />
<br />
==== خادوم <nowiki/>[[Nginx]] ====<br />
إذا كنت تستخدم خادوم [[Nginx]]، فإن تعليمة الضبط الآتية في ملف ضبط موقعك سيوجه جميع الطلبات إلى <br />
<br />
إلى <br />
<br />
ى وحدة التحكم الأمامية <code>index.php</code>:<syntaxhighlight lang="php"><br />
location / {<br />
try_files $uri $uri/ /index.php?$query_string;<br />
}<br />
</syntaxhighlight>بالطبع، عند استخدام [[Laravel/homestead|Homestead]] أو [[Laravel/valet|Valet]]، سيتم ضبط عناوين URL جذابة تلقائيًا.<br />
<br />
== مصادر ==<br />
* [https://laravel.com/docs/5.6/installation صفحة Installation في توثيق Laravel الرسمي.]<br />
[[تصنيف:Laravel|{{SUBPAGENAME}}]]<br />
[[تصنيف:Laravel Getting started|{{SUBPAGENAME}}]]</div>عاطف-بن-عليhttps://wiki.hsoub.com/index.php?title=Laravel/installation&diff=27461Laravel/installation2019-02-02T08:23:46Z<p>عاطف-بن-علي: إصلاح خطأ إملائي</p>
<hr />
<div><noinclude>{{DISPLAYTITLE:تثبيت Laravel }}</noinclude><br />
== متطلبات الخادوم ==<br />
يتطلب إطار [[Laravel]] بعض متطلبات النظام. بالطبع ، يتم استيفاء جميع هذه المتطلبات من خلال النظام الوهمي لبيئة -Laravel (باسم [[Laravel/homestead|Homestead]])- لذلك يوصى باستخدام بيئة [[Laravel/homestead|Homestead]] بيئة تطوير [[Laravel]] المحلية الخاصة بك.<br />
<br />
ومع ذلك، إذا لم تكن بيئة [[Laravel/homestead|Homestead]] متاحةً لك أو لم ترغب في استخدامها، فستحتاج إلى التأكد من أن الخادوم يلبي المتطلبات التالية:<br />
* PHP >= 7.1.3<br />
* ملحق OpenSSL PHP<br />
* ملحق PDO PHP<br />
* ملحق Mbstring PHP<br />
* ملحق Tokenizer PHP<br />
* ملحق XML PHP<br />
* ملحق Ctype PHP<br />
* ملحق JSON PHP<br />
<br />
== تثبيت Laravel ==<br />
يستخدم إطار العمل [[Laravel]] برمجية Composer لإدارة الاعتماديات. لذا تأكد من تثبيت Composer على حاسوبك، قبل استخدام [[Laravel]].<br />
<br />
=== باستخدام مُثبِّت [[Laravel]] ===<br />
حمّل أوّلًا مثبّت [[Laravel]] باستخدام Composer :<syntaxhighlight lang="text"><br />
composer global require "laravel/installer"<br />
<br />
</syntaxhighlight>احرص على إضافة مجلد <code>vendor/bin</code> الخاصة ببرنامج Composer إلى متغير البيئة <code>$PATH</code> بحيث يمكن تحديد موقع الملف القابل للتنفيذ لإطار عمل [[Laravel]] بواسطة النظام الخاص بك. يوجد هذا المجلد في مواقع مختلفة اعتمادًا على نظام التشغيل الخاص بك؛ ومع ذلك، من الشائع أن يوجد في المسارات الآتية:<br />
<br />
· في نظام ماك: في المسار <code>$HOME/.composer/vendor/bin</code><br />
<br />
· في توزيعات لينكس: في المسار <code>$HOME/.config/composer/vendor/bin</code><br />
<br />
بعد تثبيته، سيُنشِئ الأمر <code>laravel new</code> مجلدًا يحتوي على نسخة جديدة من إطار [[Laravel]]. على سبيل المثال ، سيُنشِئ الأمر <code>laravel new blog</code> مجلدًا جديدًا باسم blog يحتوي على تثبيت [[Laravel]] جديد مع جميع اعتماديات [[Laravel]] اللازمة.<syntaxhighlight lang="text"><br />
laravel new blog<br />
</syntaxhighlight><br />
<br />
=== باستخدام Composer ===<br />
بدلا عن ذلك، يمكنك أيضًا تثبيت [[Laravel]] بتنفيذ الأمر <code>create-project</code> الخاص ببرمجية Composer في الطرفية على جهازك:<syntaxhighlight lang="text"><br />
composer create-project --prefer-dist laravel/laravel blog<br />
</syntaxhighlight><br />
<br />
=== باستخدام خادوم التطوير المحلي ===<br />
إذا كنت قد قمت بتثبيت [[PHP]] محليًا وترغب في استخدام خادوم التطوير الخاص بلغة PHP لتخديم تطبيقك، فيمكنك استخدام الأمر <code>Artisan serve</code>. سيبدأ هذا الأمر خادوم تطوير على<code><nowiki>http://localhost:8000</nowiki></code>:<syntaxhighlight lang="text"><br />
php artisan serve<br />
</syntaxhighlight>بالطبع، تتوفر خيارات التطوير المحلية الأكثر قوة من خلال [[Laravel/homestead|Homestead]] و [[Laravel/valet|Valet]].<br />
<br />
== الضبط ==<br />
<br />
=== المجلد العام ===<br />
بعد تثبيت [[Laravel]] ، يجب عليك ضبط جذر لخادوم الويب الخاص بك ليكون المجلد public. يعمل الملف <code>index.php</code> في هذا المسار بصفته وحدة تحكم أمامية لجميع طلبات HTTP التي تدخل التطبيق الخاص بك.<br />
<br />
=== ملفات الضبط ===<br />
تُخزَّن كافة ملفات الضبط الخاصة بإطار [[Laravel]] في مجلد <code>config.</code> كل خيار من تلك الخيارات موثقٌ توثيقًا كاملًا، لذلك لا تتردد في إلقاء نظرة على الملفات والتعرف على الخيارات المتاحة لك.<br />
<br />
=== أذونات المجلد ===<br />
بعد تثبيت Laravel، قد تحتاج إلى ضبط بعض الأذونات (permissions). يجب أن تكون المجلدات داخل مجلد storage ومجلد <code>bootstrap/cache</code> قابلةً للكتابة بواسطة خادوم الويب أو فلن يعمل Laravel. إذا كنت تستخدم بيئة عمل [[Laravel/homestead|Homestead]]، فستكون الأذونات المطلوبة مضبوطةً مسبقًا.<br />
<br />
=== مفتاح التطبيق ===<br />
أول ما عليك فعله بعد تثبيت Laravel هو ضبط مفتاح التطبيق الخاص بك إلى سلسلة نصية عشوائية. إذا قمت بتثبيت [[Laravel]] باستخدام Composer أو مثبت Laravel، فقد ضُبِطَ هذا المفتاح لك باستخدام الأمر <code>php artisan key:generate</code>.<br />
<br />
يجب أن تكون هذه السلسلة بطول 32 محرفًا عادةً. يمكن تعيين المفتاح في ملف البيئة .env. إذا لم تُعِد تسمية الملف <code>.env.example</code> إلى <code>.env</code>، فيجب عليك القيام بذلك الآن. إذا لم يُضبَط مفتاح التطبيق، فلن تكون جلسات المستخدم الخاصة بك وغيرها من البيانات المشفرة آمنة!<br />
<br />
=== الضبط الإضافي ===<br />
لا يحتاج Laravel إلى أي ضبط آخر مبدئيًا. يمكنك البدء بالتطوير فورًا. ومع ذلك، قد ترغب في مراجعة الملف <code>config/app.php</code> وتوثيقه. هذا الملف يحتوي على العديد من الخيارات مثل المنطقة الزمنية (timezone) والمحليّة (locale ) والتي قد ترغب في تغييرها وفقًا لتطبيقك.<br />
<br />
قد ترغب أيضًا في تكوين بعض المكونات الإضافية في [[Laravel]]، مثل:<br />
* ذاكرة التخزين المؤقتة<br />
* قاعدة البيانات<br />
* الجلسة<br />
<br />
== ضبط خادوم الويب ==<br />
<br />
=== عناوين URL جذابة ===<br />
<br />
==== خادوم [[Apache]] ====<br />
يتضمن Laravel الملف <code>public/.htaccess</code> الذي يُستخدم لتوفير عناوين URL دون وحدة التحكم <code>index.php</code> الأمامية في المسارات. قبل تخديم <nowiki/>[[Laravel]] مع [[Apache]]، تأكد من تفعيل الوحدة <code>mod_rewrite</code> بحيث تُنفَّذ محتويات ملف <code>.htaccess</code> بواسطة الخادوم.<br />
<br />
إذا كان ملف <code>.htaccess</code> الذي يأتي مع [[Laravel]] لا يعمل مع تثبيت [[Apache]] عندك، فجرّب هذا الملف البديل:<syntaxhighlight lang="text"><br />
Options+FollowSymLinks<br />
RewriteEngine On<br />
RewriteCond %{REQUEST_FILENAME} !-d<br />
RewriteCond %{REQUEST_FILENAME} !-f<br />
RewriteRule ^ index.php [L]<br />
<br />
<br />
</syntaxhighlight><br />
<br />
==== خادوم <nowiki/>[[Nginx]] ====<br />
إذا كنت تستخدم خادوم [[Nginx]]، فإن تعليمة الضبط الآتية في ملف ضبط موقعك سيوجه جميع الطلبات<br />
<br />
إلى وحدة التحكم الأمامية <code>index.php</code>:<syntaxhighlight lang="php"><br />
location / {<br />
try_files $uri $uri/ /index.php?$query_string;<br />
}<br />
</syntaxhighlight>بالطبع، عند استخدام [[Laravel/homestead|Homestead]] أو [[Laravel/valet|Valet]]، سيتم ضبط عناوين URL جذابة تلقائيًا.<br />
<br />
== مصادر ==<br />
* [https://laravel.com/docs/5.6/installation صفحة Installation في توثيق Laravel الرسمي.]<br />
[[تصنيف:Laravel|{{SUBPAGENAME}}]]<br />
[[تصنيف:Laravel Getting started|{{SUBPAGENAME}}]]</div>عاطف-بن-عليhttps://wiki.hsoub.com/index.php?title=Laravel/installation&diff=23104Laravel/installation2018-11-10T14:58:02Z<p>عاطف-بن-علي: اقتراح بعض التعديلات.</p>
<hr />
<div><noinclude>{{DISPLAYTITLE:تثبيت Laravel }}</noinclude><br />
== متطلبات الخادوم ==<br />
يتطلب إطار [[Laravel]] بعض متطلبات النظام. بالطبع ، يتم استيفاء جميع هذه المتطلبات من خلال النظام الوهمي لبيئة -Laravel (باسم [[Laravel/homestead|Homestead]])- لذلك يوصى باستخدام بيئة [[Laravel/homestead|Homestead]] بيئة تطوير [[Laravel]] المحلية الخاصة بك.<br />
<br />
ومع ذلك، إذا لم تكن بيئة [[Laravel/homestead|Homestead]] متاحةً لك أو لم ترغب في استخدامها، فستحتاج إلى التأكد من أن الخادوم يلبي المتطلبات التالية:<br />
* PHP >= 7.1.3<br />
* ملحق OpenSSL PHP<br />
* ملحق PDO PHP<br />
* ملحق Mbstring PHP<br />
* ملحق Tokenizer PHP<br />
* ملحق XML PHP<br />
* ملحق Ctype PHP<br />
* ملحق JSON PHP<br />
<br />
== تثبيت Laravel ==<br />
يستخدم إطار العمل [[Laravel]] برمجية Composer لإدارة الاعتماديات. لذا تأكد من تثبيت Composer على حاسوبك، قبل استخدام [[Laravel]].<br />
<br />
=== باستخدام مُثبِّت [[Laravel]] ===<br />
حمّل أوّلًا مثبّت [[Laravel]] باستخدام Composer :<syntaxhighlight lang="text"><br />
composer global require "laravel/installer"<br />
<br />
</syntaxhighlight>احرص على إضافة مجلد <code>vendor/bin</code> الخاصة ببرنامج Composer إلى متغير البيئة <code>$PATH</code> بحيث يمكن تحديد موقع الملف القابل للتنفيذ لإطار عمل [[Laravel]] بواسطة النظام الخاص بك. يوجد هذا المجلد في مواقع مختلفة اعتمادًا على نظام التشغيل الخاص بك؛ ومع ذلك، من الشائع أن يوجد في المسارات الآتية:<br />
<br />
· في نظام ماك: في المسار <code>$HOME/.composer/vendor/bin</code><br />
<br />
· في توزيعات لينكس: في المسار <code>$HOME/.config/composer/vendor/bin</code><br />
<br />
بعد تثبيته، سيُنشِئ الأمر <code>laravel new</code> مجلدًا يحتوي على نسخة جديدة من إطار [[Laravel]]. على سبيل المثال ، سيُنشِئ الأمر <code>laravel new blog</code> مجلدًا جديدًا باسم blog يحتوي على تثبيت [[Laravel]] جديد مع جميع اعتماديات [[Laravel]] اللازمة.<syntaxhighlight lang="text"><br />
laravel new blog<br />
</syntaxhighlight><br />
<br />
=== باستخدام Composer ===<br />
بدلا عن ذلك، يمكنك أيضًا تثبيت [[Laravel]] بتنفيذ الأمر <code>create-project</code> الخاص ببرمجية Composer في الطرفية على جهازك:<syntaxhighlight lang="text"><br />
composer create-project --prefer-dist laravel/laravel blog<br />
</syntaxhighlight><br />
<br />
=== باستخدام خادوم التطوير المحلي ===<br />
إذا كنت قد قمت بتثبيت [[PHP]] محليًا وترغب في استخدام خادوم التطوير الخاص بلغة PHP لتخديم تطبيقك، فيمكنك استخدام الأمر <code>Artisan serve</code>. سيبدأ هذا الأمر خادوم تطوير على<code><nowiki>http://localhost:8000</nowiki></code>:<syntaxhighlight lang="text"><br />
php artisan serve<br />
</syntaxhighlight>بالطبع، تتوفر خيارات التطوير المحلية الأكثر قوة من خلال [[Laravel/homestead|Homestead]] و [[Laravel/valet|Valet]].<br />
<br />
== الضبط ==<br />
<br />
=== المجلد العام ===<br />
بعد تثبيت [[Laravel]] ، يجب عليك ضبط جذر لخادوم الويب الخاص بك ليكون المجلد public. يعمل الملف <code>index.php</code> في هذا المسار بصفته وحدة تحكم أمامية لجميع طلبات HTTP التي تدخل التطبيق الخاص بك.<br />
<br />
=== ملفات الضبط ===<br />
تُخزَّن كافة ملفات الضبط الخاصة بإطار [[Laravel]] في مجلد <code>config.</code> كل خيار من تلك الخيارات موثقٌ توثيقًا كاملًا، لذلك لا تتردد في إلقاء نظرة عل الملفات والتعرف على الخيارات المتاحة لك.<br />
<br />
=== أذونات المجلد ===<br />
بعد تثبيت Laravel، قد تحتاج إلى ضبط بعض الأذونات (permissions). يجب أن تكون المجلدات داخل مجلد storage ومجلد <code>bootstrap/cache</code> قابلةً للكتابة بواسطة خادوم الويب أو فلن يعمل Laravel. إذا كنت تستخدم بيئة عمل [[Laravel/homestead|Homestead]]، فستكون الأذونات المطلوبة مضبوطةً مسبقًا.<br />
<br />
=== مفتاح التطبيق ===<br />
أول ما عليك فعله بعد تثبيت Laravel هو ضبط مفتاح التطبيق الخاص بك إلى سلسلة نصية عشوائية. إذا قمت بتثبيت [[Laravel]] باستخدام Composer أو مثبت Laravel، فقد ضُبِطَ هذا المفتاح لك باستخدام الأمر <code>php artisan key:generate</code>.<br />
<br />
يجب أن تكون هذه السلسلة بطول 32 محرفًا عادةً. يمكن تعيين المفتاح في ملف البيئة .env. إذا لم تُعِد تسمية الملف <code>.env.example</code> إلى <code>.env</code>، فيجب عليك القيام بذلك الآن. إذا لم يُضبَط مفتاح التطبيق، فلن تكون جلسات المستخدم الخاصة بك وغيرها من البيانات المشفرة آمنة!<br />
<br />
=== الضبط الإضافي ===<br />
لا يحتاج Laravel إلى أي ضبط آخر مبدئيًا. يمكنك البدء بالتطوير فورًا. ومع ذلك، قد ترغب في مراجعة الملف <code>config/app.php</code> وتوثيقه. هذا الملف يحتوي على العديد من الخيارات مثل المنطقة الزمنية (timezone) والمحليّة (locale ) والتي قد ترغب في تغييرها وفقًا لتطبيقك.<br />
<br />
قد ترغب أيضًا في تكوين بعض المكونات الإضافية في [[Laravel]]، مثل:<br />
* ذاكرة التخزين المؤقتة<br />
* قاعدة البيانات<br />
* الجلسة<br />
<br />
== ضبط خادوم الويب ==<br />
<br />
=== عناوين URL جذابة ===<br />
<br />
==== خادوم [[Apache]] ====<br />
يتضمن Laravel الملف <code>public/.htaccess</code> الذي يُستخدم لتوفير عناوين URL دون وحدة التحكم <code>index.php</code> الأمامية في المسارات. قبل تخديم <nowiki/>[[Laravel]] مع [[Apache]]، تأكد من تفعيل الوحدة <code>mod_rewrite</code> بحيث تُنفَّذ محتويات ملف <code>.htaccess</code> بواسطة الخادوم.<br />
<br />
إذا كان ملف <code>.htaccess</code> الذي يأتي مع [[Laravel]] لا يعمل مع تثبيت [[Apache]] عندك، فجرّب هذا الملف البديل:<syntaxhighlight lang="text"><br />
Options+FollowSymLinks<br />
RewriteEngine On<br />
RewriteCond %{REQUEST_FILENAME} !-d<br />
RewriteCond %{REQUEST_FILENAME} !-f<br />
RewriteRule ^ index.php [L]<br />
<br />
<br />
</syntaxhighlight><br />
<br />
==== خادوم <nowiki/>[[Nginx]] ====<br />
إذا كنت تستخدم خادوم [[Nginx]]، فإن تعليمة الضبط الآتية في ملف ضبط موقعك سيوجه جميع الطلبات<br />
<br />
إلى وحدة التحكم الأمامية <code>index.php</code>:<syntaxhighlight lang="php"><br />
location / {<br />
try_files $uri $uri/ /index.php?$query_string;<br />
}<br />
</syntaxhighlight>بالطبع، عند استخدام [[Laravel/homestead|Homestead]] أو [[Laravel/valet|Valet]]، سيتم ضبط عناوين URL جذابة تلقائيًا.<br />
<br />
== مصادر ==<br />
* [https://laravel.com/docs/5.6/installation صفحة Installation في توثيق Laravel الرسمي.]<br />
[[تصنيف:Laravel|{{SUBPAGENAME}}]]<br />
[[تصنيف:Laravel Getting started|{{SUBPAGENAME}}]]</div>عاطف-بن-علي