يصف القابل للتغيير مقابل الثابت ما إذا كان يمكن تغيير الأنظمة أو البنية التحتية أو البيانات بعد الإنشاء. ويمكن تعديل الموارد القابلة للتغيير في مكانها. ولا يمكن تغيير الموارد الثابتة—أي تعديل يؤدي إلى إنشاء مثيل جديد.
القابل للتغيير مقابل الثابت هو مبدأ يقود الأساليب الحديثة لكل من تطوير البرمجيات وإدارة البنية التحتية.
يمكن مقارنة التمييز بكتابة نص على السبورة البيضاء. إذا كان بإمكانك إضافة كلمات أو مسح أجزاء أو تغيير ما هو مكتوب، فهذا يشبه موردًا قابلاً للتغيير. ولكن إذا تم إغلاق السبورة البيضاء تحت الزجاج في اللحظة التي تنتهي فيها من الكتابة ويجب عليك استخدام سبورة بيضاء جديدة لكتابة شيء آخر، فهذا مورد غير قابل للتغيير.
في حين أن هذا المفهوم ينطبق على نطاق واسع عبر الحوسبة، إلا أنه أكثر شيوعًا في البرمجة. في البرمجة، يُعد فهم أنواع البيانات التي يمكن تعديلها بشكل مباشر مقابل متى يجب إنشاء نسخة جديدة أمرًا ضروريًا للمهام الشائعة. وتتضمن هذه المهام كتابة الخوارزميات وبناء واجهات برمجة التطبيقات (APIs) وتصميم الفئات في البرمجة الموجهة للكائنات (OOP).
يؤثر الاختيار بين استخدام الكائنات القابلة للتغيير أو غير القابلة للتغيير على كيفية إدارة البيانات في الذاكرة، ومدى أمان مشاركتها أو تغييرها، وما إذا كانت قد تحدث آثار جانبية غير مقصودة. ولهذا السبب، يُعد مفهوم "القابل للتغيير مقابل غير القابل للتغيير" مفهومًا تأسيسيًّا لكل من المبرمجين المبتدئين وذوي الخبرة على حد سواء.
على سبيل المثال، في لغة برمجة Python، تُعد القوائم والقواميس أنواعًا قابلة للتغيير. ويمكن إضافة العناصر أو إزالتها أو تعديلها داخل هذه الكائنات. في المقابل، فإن الكائنات مثل القيم المنطقية (القيم الصحيحة أو الخاطئة) أو المجموعات—المجموعات المرتبة مثل (1،2،3)—هي أنواع ثابتة. لا يمكن تغيير محتوياتها أو تحويرها دون إنشاء كائن جديد تمامًا.
النشرة الإخبارية الخاصة بالمجال
ابقَ على اطلاع دومًا بأهم—اتجاهات المجال وأكثرها إثارة للفضول—بشأن الذكاء الاصطناعي والأتمتة والبيانات وغيرها الكثير مع نشرة Think الإخبارية. راجع بيان الخصوصية لشركة IBM.
سيتم تسليم اشتراكك باللغة الإنجليزية. ستجد رابط إلغاء الاشتراك في كل رسالة إخبارية. يمكنك إدارة اشتراكاتك أو إلغاء اشتراكك هنا. راجع بيان خصوصية IBM لمزيد من المعلومات.
يعتمد الاختيار بين البيانات القابلة للتغيير وغير القابلة للتغيير بشكل عام على ثلاثة عوامل رئيسية: ما إذا كانت البيانات تحتاج إلى تحديثات متكررة أو تتم مشاركتها عبر مسارات الرسائل أو تتطلب سجل الإصدارات.
تعمل الأنواع القابلة للتغيير بشكل أفضل عمومًا عندما تحتاج البيانات إلى تحديثات متكررة، وتقوم أجزاء متعددة من البرنامج بتعديل الكائن نفسه.
تقوم الكائنات القابلة للتغيير بتعديل البيانات في مكانها، ما يقلل من استخدام الذاكرة عن طريق تجنب الحاجة إلى إنشاء كائنات جديدة. ويمكن أن يقلل من استخدام المعالج لجمع البيانات المهملة—عملية إزالة البيانات غير المستخدمة لتحرير الذاكرة—لأنه قد يلزم إنشاء عدد أقل من الكائنات المؤقتة وجمعها.
على سبيل المثال، تستخدم عربات التسوق في التطبيقات قوائم قابلة للتغيير لإضافة العناصر أو إزالتها مباشرةً دون إنشاء كائنات جديدة لكل تغيير.
تعمل الأنواع القابلة للتغيير بشكل أفضل مع البيانات المتغيرة بشكل متكرر—مثل القوائم المتزايدة أو العدادات في الوقت الفعلي—لأنها تقوم بتحديث الكائنات الموجودة بدلاً من إنشاء كائنات جديدة. وتعمل هذه الكفاءة على تسريع العمليات في هياكل البيانات التي تعتمد على التعديلات السريعة.
على سبيل المثال، يمكن لقائمة تشغيل تطبيق الموسيقى استخدام قائمة قابلة للتغيير لإجراء تحديثات سريعة. ويمكنه القيام بذلك في ميكروثانية عند إضافة أغنية أو حذفها، مقارنة بإعادة إنشاء قائمة تشغيل مكونة من 1,000 أغنية لكل تغيير.
تسمح الكائنات القابلة للتغيير لأجزاء متعددة من البرنامج بالوصول إلى الكائن نفسه وتغييره. وتمكّنهم هذه العملية من العمل مع حالة مشتركة—البيانات التي تقرأها وتكتبها عناصر متعددة لتنسيق إجراءاتها. وتكون مفيدة عندما تحتاج العناصر إلى التنسيق أو التواصل من خلال بيانات مشتركة.
على سبيل المثال، يستخدم تطبيق إدارة المشروعات كائنات قابلة للتغيير لمشاركة قوائم المهام والتقويمات والإشعارات. وعندما يقوم أحد أعضاء الفريق بتحديث مهمة ما، يرى الجميع التغيير على الفور.
عادة ما تعمل الأنواع الثابتة بشكل أفضل عندما لا تتغير البيانات بعد إنشائها. وهذا مهم بشكل خاص في التطبيقات المتزامنة، حيث تصل أجزاء متعددة من البرنامج إلى البيانات نفسها.
نظرا لأن حالة الكائن غير القابل للتغيير ثابتة، فلن يتم تغييرها بواسطة تعليمات برمجية أخرى. وتجعل هذه الميزة البرامج أكثر قابلية للتنبؤ بها وأسهل للفهم لأنها تقضي على الأخطاء المتعلقة بالطفرات غير المتوقعة.
على سبيل المثال، كثيرًا ما تخزين التطبيقات البنكية سجلات المعاملات ككائنات ثابتة حتى لا يمكن لأي رمز تغييرها لاحقًا. من المهم جدًا المساعدة على ضمان الامتثال التنظيمي والحفاظ على مسارات التدقيق التي تثبت عدم التلاعب بالمعاملات.
الكائنات الثابتة آمنة بشكل عام لمؤشر الترابط لأن حالتها لا يمكن أن تتغير بعد الإنشاء. ويمكن لمؤشرات الترابط المتعددة قراءتها بأمان في وقت واحد دون تعارضات، على الرغم من أن المطورين لا يزالون بحاجة إلى إدارة المراجع بعناية في الأنظمة المتزامنة. ما يجعلها مثالية للبرامج متعددة المسارات، حيث يجب أن تصل مؤشرات الترابط المتعددة إلى نفسها البيانات دون التسبب في تعارضات.
على سبيل المثال، يمكن للتطبيق تشغيل مؤشرات ترابط متزامنة للظروف الحالية والتنبؤات والتنبيهات. ويعني تخزين بيانات الطقس ككائنات ثابتة، أن كل مؤشر ترابط يمكنه قراءة المعلومات نفسها دون المخاطرة بتغيرها بشكل غير متوقع.
يمكن للأشياء غير القابلة للتغيير تبسيط عملية تصحيح الأخطاء لأن القيم لا تتغير بشكل غير متوقع في أثناء تنفيذ البرنامج. ويمكن أن تقلل هذه الميزة من الأخطاء الناتجة عن الآثار الجانبية وتساعد الفرق على حل المشكلات بشكل أسرع.
على سبيل المثال، تقوم ألعاب الفيديو في كثير من الأحيان بتخزين الأمان والإحصائيات الخاصة باللاعبين ككائنات ثابتة. نظرا لأن هذه القيم لا يمكن أن تتغير بشكل غير متوقع، يمكن للمطورين بسهولة تعقب الأخطاء مع العلم أن التعليمات البرمجية غير ذات الصلة لن تغير الإحصائيات.
اثنان من أكثر أنماط البرمجة استخدامًا—البرمجة الموجهة للكائنات (OOP) والبرمجة الوظيفية—يتعاملان مع قابلية التغيير بشكل مختلف.
غالبًا ما تتبنى OOP قابلية التغيير، وتبني برامج حول الكائنات التي تحتوي على كل من البيانات والسلوكيات. ويمكن أن تتغير هذه الكائنات بمرور الوقت باستخدام وظائف خاصة تسمى المحددات، حيث يمكنها تحديث قيمة الخاصية (على سبيل المثال ، تغيير عمر الشخص أو سعر المنتج).
في المقابل، تميل البرمجة الوظيفية نحو الثبات. حيث تقوم بإنشاء قيم جديدة وإعادتها كلما احتاج شيء ما إلى التغيير، ما يجعل البرامج أكثر قابلية للتنبؤ بها وأسهل في الاختبار.
تختلف لغات البرمجة أيضًا في نهجها تجاه الأنواع القابلة للتغيير مقابل الأنواع غير القابلة للتغيير.
في Python، تكون الأنواع القابلة للتغيير والثابتة شائعة.
أحد الأمثلة على ذلك هو السلاسل—سلاسل من الأحرف مثل الأسماء أو الجمل. السلاسل في Python ثابتة. ويؤدي إلحاق نص جديد إلى إنشاء كائن سلسلة جديد. في المقابل، القوائم قابلة للتغيير. هذه المجموعات المرتبة قابلة للتكرار—يمكنك إضافة عناصر داخل كائن القائمة أو إزالتها أو تعديلها.
بدلاً من استخدام مُجمِّع (برنامج يحول الرمز إلى لغة الآلة قبل التنفيذ) للتحقق من الرمز قبل تشغيله، ويتحقق Python من الأنواع في وقت التشغيل. هذا يعني أنه يتم اكتشاف الأخطاء فقط في أثناء تشغيل البرنامج. وتؤدي الأخطاء التي تنطوي على قابلية التغيير—مثل محاولة تعديل سلسلة ثابتة—إلى تشغيل TypeError.
إذا لم يتم التعامل مع الخطأ، فإنه يوقف البرنامج على الفور، ما يمنع تشغيل أي تعليمات برمجية أخرى. ويتيح هذا الإجراء تطويرًا أسرع ولكنه يتطلب اهتمامًا دقيقًا بمعالجة الكتابة.
فهم قابلية التغيير في Python يساعد على منع الأخطاء عند مشاركة البيانات بين الدوال أو العمل ضمن وحدة نمطية مشتركة. وتوفر البرامج التعليمية وأمثلة التعليمات البرمجية على GitHub أفضل الممارسات لاستخدام أنواع Python المضمنة.
تستخدم JavaScript كلا من الأنواع القابلة للتغيير والثابتة. كما هو الحال في Python، فإن السلاسل ثابتة أيضًا. ومع ذلك، على عكس Python، تكون جميع الكائنات قابلة للتغيير بشكل افتراضي.
تدعم بنية JavaScript المرنة كلاً من الأنماط الموجهة للكائنات والوظيفية على حد سواء، ما يسمح للمطورين بإدارة قابلية التغيير حسب الحاجة.
على غرار Python، سلاسل Java ثابتة. وبمجرد إنشائها، لا يمكن تغيير قيمة السلسلة. كما يمكن أن تكون هذه الخاصية غير فعالة للبرامج التي تنشئ النص أو تعدله بشكل متكرر.
لمعالجة هذه المشكلة، توفر Java فئة StringBuilder—وهي فئة سلاسل قابلة للتغيير تسمح بتعديل النص مباشرةً دون إنشاء كائنات جديدة. ويمكن أن يحسن الأداء ويقلل من استخدام الذاكرة، ويوازن بين سلامة الثبات وفوائد الأداء في قابلية التغيير.
يستخدم C ++ الكلمة الأساسية const لتمييز المتغيرات والوظائف وحتى الكائنات بأكملها على أنها للقراءة فقط. ويمكن أن يمنح المطورين تحكمًا دقيقًا في قابلية التغيير، ما يحول بفعالية كائنًا قابلاً للتغيير إلى كائن ثابت عن طريق منع التغييرات.
مثل Java، يمكن أن تكون سلاسل C ++ قابلة للتغيير أو ثابتة، اعتمادًا على تنفيذها.
يدعم C ++ كل من أنماط البرمجة الموجهة للكائنات والبرمجة الوظيفية. في نمط OOP، يقوم المطورون بتعديل الكائنات الموجودة بمرور الوقت، بينما تنشئ البرمجة الوظيفية قيمًا جديدة بدلاً من تغيير البيانات الموجودة.
تمتد مبادئ القابلية للتغيير مقابل عدم القابلية للتغيير إلى ما هو أبعد من البرمجة لتشمل البنية التحتية والأنظمة. ويطبق مهندسو البرمجيات الحديثة هذه المفاهيم نفسها عند تصميم البنى السحابية ومسارات النشر.
تشير البنية التحتية القابلة للتغيير إلى الخوادم أو موارد تكنولوجيا المعلومات الأخرى التي يمكن تغييرها بعد النشر. على سبيل المثال، يمكنك تسجيل الدخول إلى خادم وتحديث البرامج يدويًّا أو تغيير التكوينات أو تثبيت التصحيحات. وفي حين أن هذا النهج يوفر المرونة، إلا أنه يمكن أن يؤدي إلى انجراف التكوين، حيث تتحول الخوادم إلى خوادم فريدة في إعداداتها "snowflakes" وتصبح التغييرات مستحيلة التتبع أو إعادة الإنتاج.
تعني البنية التحتية الثابتة أنه لا يمكن تغيير الخوادم أو موارد تكنولوجيا المعلومات بعد النشر. بدلاً من تحديث الأنظمة قيد التشغيل، ينشر الفريق مثيلات جديدة مع التغييرات المضمنة، ثم يسحب المثيلات القديمة. ويقلل هذا النهج من انحراف التهيئة ويبسط التراجع ويساعد على ضمان عمليات النشر المتسقة.
يمكن أن تنطبق مبادئ القابلية للتغيير والثبات أيضًا على مجالات أخرى من تصميم البرامج والأنظمة.
تستخدم بعض قواعد البيانات سجلات الإلحاق فقط، ما يعني أن كل تغيير يتم تسجيله بشكل دائم ولا يمكن تغييره. البعض الآخر قابل للتغيير، ما يسمح بتحديثات البيانات أو حذفها مباشرة، مثل تحرير مستند.
يمكن تهيئة بعض أنظمة التخزين السحابي على أنها تخزين ثابت للاحتفاظ بالإصدارات السابقة وتأمينها من التغييرات. ويساعد هذا على حماية البيانات من التغيير أو الحذف عن طريق الخطأ. ويتيح التخزين القابل للتغيير إمكانية تحرير الملفات أو استبدالها في أي وقت.
تتبع العديد من أدوات التحكم في الإصدار، مثل Git، نموذجًا ثابتًا، حيث يتم حفظ كل التزام كلقطة منفصلة غير قابلة للتغيير. ما يساعد على ضمان وجود سجل موثوق للإصدارات، حتى مع إضافة تغييرات جديدة.