Menu
CoddyTech

التحقق من البيانات في الـ Setters

جزء من قسم البرمجة كائنية التوجه في رحلة C على Coddy. الدرس 20 من 61.

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

تخيّل Counter الذي يجب ألا تصبح قيمته سالبة أبدًا. من دون التغليف، يمكن لأي شخص كتابة c->value = -50 وإفساد الحالة. باستخدام دالة ضبط، يمكنك التحكم في القيم المسموح بها:

// counter.c
void counter_set_value(Counter *c, int new_value) {
    if (new_value < 0) {
        return;  // ارفض المدخلات غير الصالحة بصمت
    }
    c->value = new_value;
}

الآن يتم تجاهل القيم السالبة ببساطة.

قد تختار أيضًا إرجاع رمز حالة للإشارة إلى النجاح أو الفشل:

int counter_set_value(Counter *c, int new_value) {
    if (new_value < 0) {
        return 0;  // فشل
    }
    c->value = new_value;
    return 1;  // نجاح
}

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

challenge icon

التحدي

سهل

لننشئ وحدة Temperature تحمي بياناتها باستخدام التحقق في دالة الضبط. ستنشئ متعقّبًا لدرجة الحرارة لا يقبل إلا القيم ضمن نطاق صالح، موضحًا كيف تعمل دوال الضبط كحراس لحالة الكائن.

ستنشئ ثلاثة ملفات:

  • temperature.h: واجهتك العامة باستخدام نمط المؤشر المعتم. صرّح عن النوع Temperature باستخدام تصريح أمامي فقط. صرّح عن هذه الدوال:
    • create_temperature: تأخذ عددًا صحيحًا لدرجة الحرارة الابتدائية وتُعيد مؤشرًا إلى Temperature
    • free_temperature: تحرر الذاكرة المخصصة
    • temp_get_degrees: دالة جلب تُعيد قيمة درجة الحرارة الحالية
    • temp_set_degrees: دالة ضبط تُعيد int (1 للنجاح، و0 للإخفاق)
    استخدم حراس التضمين مع الرمز TEMPERATURE_H.
  • temperature.c: عرّف البنية الفعلية struct Temperature مع عضو مخفي int degrees. نفّذ جميع الدوال. النقطة الأساسية هي دالة الضبط. يجب ألا تقبل إلا القيم بين -50 و150 (شاملًا). إذا كانت القيمة خارج هذا النطاق، فأعِد 0 واترك درجة الحرارة دون تغيير. وإذا كانت صالحة، فحدّث القيمة وأعِد 1.
  • main.c: وضّح التحقق بمحاولة ضبط درجتي حرارة صالحة وغير صالحة، مع إظهار رفض القيم غير الصالحة وقبول القيم الصالحة.

ستتلقى ثلاث قيم إدخال: درجة الحرارة الابتدائية، ودرجة حرارة صالحة لضبطها (ضمن النطاق)، ودرجة حرارة غير صالحة لمحاولة ضبطها (خارج النطاق).

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

اطبع المخرجات بهذا التنسيق:

Initial: {degrees}
Set {invalid}: {0 or 1}
After invalid: {degrees}
Set {valid}: {0 or 1}
After valid: {degrees}
Freed

على سبيل المثال، مع قيم الإدخال 25 و100 و200، ستكون المخرجات:

Initial: 25
Set 200: 0
After invalid: 25
Set 100: 1
After valid: 100
Freed

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

جرّب بنفسك

#include <stdio.h>
#include "temperature.h"

int main() {
    // اقرأ المدخلات
    int initial, valid_temp, invalid_temp;
    scanf("%d", &initial);
    scanf("%d", &valid_temp);
    scanf("%d", &invalid_temp);
    
    // TODO: أنشئ Temperature بالقيمة الأولية
    
    // TODO: اطبع درجة الحرارة الأولية
    // التنسيق: "Initial: {degrees}"
    
    // TODO: حاول تعيين درجة الحرارة غير الصالحة
    // اطبع النتيجة وأظهر أن القيمة لم تتغير
    // التنسيق: "Set {invalid}: {0 or 1}"
    // التنسيق: "After invalid: {degrees}"
    
    // TODO: عيّن درجة الحرارة الصالحة
    // اطبع نتيجة النجاح وأظهر القيمة المحدّثة
    // التنسيق: "Set {valid}: {0 or 1}"
    // التنسيق: "After valid: {degrees}"
    
    // TODO: حرّر الذاكرة واطبع "Freed"
    
    return 0;
}
quiz iconاختبر نفسك

يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.

جميع دروس البرمجة كائنية التوجه

تدرّب بنفسك: مترجم C عبر الإنترنت