الرئيسية قاعدة المعرفة البرمجة والمنطق البرمجة كائنية التوجه في أنظمة الأتمتة
البرمجة والمنطق

البرمجة كائنية التوجه في أنظمة الأتمتة

البرمجة الكائنية: لغة الآلات تتكلم بالكائنات

تخيّل أنك تقف أمام خط إنتاج في مصنع سوري للمواد الغذائية. أمامك آلة تعبئة، وحزام ناقل، ومستشعر وزن، ولوحة تحكم. كل واحد من هذه المكونات له خصائص (سرعة، حالة، درجة حرارة) وسلوكيات (تشغيل، إيقاف، ضبط). هذا بالضبط ما تفعله البرمجة الكائنية (OOP) — تحوّل العالم الحقيقي إلى كائنات برمجية يمكن التحكم بها.

البرمجة الكائنية ليست مجرد أسلوب كتابة كود — إنها طريقة تفكير تجعل برامج التحكم الصناعي أكثر تنظيماً وقابلية للصيانة والتوسيع.

الصنف والكائن: المخطط والآلة الحقيقية

الصنف (Class) هو المخطط الهندسي — الرسم التقني الذي يصف كيف تُبنى الآلة. الكائن (Object) هو الآلة الفعلية التي بُنيت من هذا المخطط.

مثال عملي — لنمثّل محرّكاً كهربائياً:

class Motor:
    def __init__(self, rated_power_kw, rated_rpm):
        self.rated_power = rated_power_kw    # الاستطاعة المقنّنة
        self.rated_rpm = rated_rpm            # السرعة المقنّنة
        self.is_running = False               # حالة التشغيل
        self.current_rpm = 0                  # السرعة الحالية

    def start(self):
        if not self.is_running:
            self.is_running = True
            self.current_rpm = self.rated_rpm
            print(f"المحرك يعمل بسرعة {self.current_rpm} RPM")

    def stop(self):
        self.is_running = False
        self.current_rpm = 0
        print("المحرك توقف")

    def get_status(self):
        state = "يعمل" if self.is_running else "متوقف"
        return f"الحالة: {state} | السرعة: {self.current_rpm} RPM"

الآن ننشئ كائنات فعلية — كل كائن هو محرك مستقل:

pump_motor = Motor(rated_power_kw=5.5, rated_rpm=1450)
conveyor_motor = Motor(rated_power_kw=2.2, rated_rpm=960)

pump_motor.start()       # المحرك يعمل بسرعة 1450 RPM
print(conveyor_motor.get_status())  # الحالة: متوقف | السرعة: 0 RPM

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

التغليف: حماية الأجزاء الداخلية

التغليف (Encapsulation) يعني إخفاء التفاصيل الداخلية وعرض واجهة بسيطة فقط — تماماً كما تتعامل مع لوحة تحكم الآلة دون الحاجة لمعرفة تفاصيل الدارات الإلكترونية بداخلها.

class TemperatureController:
    def __init__(self, setpoint):
        self._setpoint = setpoint       # درجة الحرارة المطلوبة
        self._current_temp = 25.0       # القراءة الحالية
        self._kp = 2.0                  # معامل PID داخلي
        self._output = 0.0              # خرج التحكم

    def update_reading(self, sensor_value):
        """الواجهة العامة — يستدعيها المستخدم"""
        self._current_temp = sensor_value
        self._calculate_output()        # الحساب الداخلي مخفي

    def _calculate_output(self):
        """منطق داخلي لا يحتاج المستخدم لمعرفته"""
        error = self._setpoint - self._current_temp
        self._output = max(0, min(100, self._kp * error))

    @property
    def output_percent(self):
        return self._output

    @property
    def setpoint(self):
        return self._setpoint

    @setpoint.setter
    def setpoint(self, value):
        if 0 <= value <= 200:
            self._setpoint = value
        else:
            raise ValueError("درجة الحرارة خارج النطاق المسموح")

المستخدم يتعامل فقط مع update_reading و setpoint — لا يحتاج لمعرفة كيف يُحسب الخرج داخلياً. هذا يمنع الأخطاء ويسهّل الصيانة.

الوراثة: بناء عائلات من الآلات

الوراثة (Inheritance) تتيح لك إنشاء أصناف جديدة تبني على أصناف موجودة — كما أن المحرك الكهربائي والمحرك الهيدروليكي كلاهما "محرك" لكن لكل منهما خصائص إضافية.

class Actuator:
    """الصنف الأب: أي مشغّل صناعي"""
    def __init__(self, name, max_force_n):
        self.name = name
        self.max_force = max_force_n
        self.position = 0.0  # النسبة المئوية 0-100

    def move_to(self, target_percent):
        self.position = max(0, min(100, target_percent))
        print(f"{self.name}: الموضع = {self.position}%")

    def emergency_stop(self):
        self.position = 0
        print(f"{self.name}: توقف طارئ!")

class PneumaticCylinder(Actuator):
    """أسطوانة هوائية — ترث من Actuator"""
    def __init__(self, name, max_force_n, stroke_mm, pressure_bar):
        super().__init__(name, max_force_n)
        self.stroke_mm = stroke_mm
        self.pressure = pressure_bar

    def extend(self):
        self.move_to(100)

    def retract(self):
        self.move_to(0)

class ServoMotor(Actuator):
    """محرك سيرفو — ترث من Actuator وتضيف دقة الموضع"""
    def __init__(self, name, max_force_n, resolution_bits):
        super().__init__(name, max_force_n)
        self.resolution = 2 ** resolution_bits

    def move_to_angle(self, degrees):
        percent = (degrees / 360.0) * 100
        self.move_to(percent)
cylinder = PneumaticCylinder("CYL-01", 500, stroke_mm=200, pressure_bar=6)
servo = ServoMotor("SRV-01", 50, resolution_bits=12)

cylinder.extend()           # CYL-01: الموضع = 100%
servo.move_to_angle(90)     # SRV-01: الموضع = 25.0%
cylinder.emergency_stop()   # CYL-01: توقف طارئ!

كلاهما يملك move_to و emergency_stop من الصنف الأب، لكن كل منهما يضيف سلوكه الخاص.

تعدد الأشكال: نفس الأمر، تنفيذ مختلف

تعدد الأشكال (Polymorphism) يعني أن نفس الأمر (مثلاً "شغّل") يتنفّذ بشكل مختلف حسب نوع الكائن — المحرك الكهربائي يتصرف بشكل مختلف عن الصمام الهوائي عند تلقي أمر التشغيل.

class ElectricValve(Actuator):
    def move_to(self, target_percent):
        if target_percent > 50:
            self.position = 100  # الصمام إما مفتوح أو مغلق
            print(f"{self.name}: الصمام مفتوح بالكامل")
        else:
            self.position = 0
            print(f"{self.name}: الصمام مغلق")

class ProportionalValve(Actuator):
    def move_to(self, target_percent):
        self.position = target_percent  # فتح نسبي مستمر
        print(f"{self.name}: الفتح = {self.position}%")
devices = [
    ElectricValve("V-101", 200),
    ProportionalValve("PV-201", 200),
    ServoMotor("SRV-02", 50, 12),
]

for device in devices:
    device.move_to(75)  # نفس الاستدعاء — نتائج مختلفة

الخرج:

V-101: الصمام مفتوح بالكامل
PV-201: الفتح = 75%
SRV-02: الموضع = 75%

هذا قوي جداً في الأتمتة — يمكنك كتابة كود تحكم عام يعمل مع أي نوع من المشغّلات.

نمذجة خط إنتاج كامل

لنجمع كل المفاهيم في نموذج لخط إنتاج بسيط:

class ProductionLine:
    def __init__(self, name):
        self.name = name
        self._devices = []          # قائمة الأجهزة
        self._is_running = False

    def add_device(self, device):
        self._devices.append(device)

    def start_all(self):
        print(f"--- تشغيل خط {self.name} ---")
        self._is_running = True
        for device in self._devices:
            device.move_to(100)     # تعدد الأشكال هنا!

    def emergency_stop_all(self):
        print(f"!!! توقف طارئ — خط {self.name} !!!")
        self._is_running = False
        for device in self._devices:
            device.emergency_stop()

    def status_report(self):
        print(f"\n=== تقرير خط {self.name} ===")
        for device in self._devices:
            print(f"  {device.name}: موضع={device.position}%")
line = ProductionLine("خط التعبئة")
line.add_device(PneumaticCylinder("CYL-دفع", 800, 300, 6))
line.add_device(ProportionalValve("PV-تعبئة", 150))
line.add_device(ServoMotor("SRV-ختم", 100, 16))

line.start_all()
line.status_report()
line.emergency_stop_all()

أنماط التصميم الشائعة في الأتمتة

نمط المراقب (Observer Pattern)

عندما يتغير مستشعر، يجب إعلام عدة أنظمة فرعية:

class Sensor:
    def __init__(self, name):
        self.name = name
        self._value = 0
        self._observers = []

    def attach(self, observer):
        self._observers.append(observer)

    def set_value(self, new_value):
        self._value = new_value
        for obs in self._observers:
            obs.on_sensor_update(self.name, new_value)

class AlarmSystem:
    def on_sensor_update(self, sensor_name, value):
        if value > 80:
            print(f"[تنبيه] {sensor_name} = {value} — تجاوز الحد!")

class DataLogger:
    def on_sensor_update(self, sensor_name, value):
        print(f"[سجل] {sensor_name} = {value}")

نمط آلة الحالة (State Machine)

الآلات الصناعية تتنقل بين حالات محددة:

class MachineState:
    IDLE = "خامل"
    STARTING = "بدء_التشغيل"
    RUNNING = "يعمل"
    ERROR = "خطأ"
    STOPPING = "إيقاف"

class PackagingMachine:
    def __init__(self):
        self.state = MachineState.IDLE

    def start(self):
        if self.state == MachineState.IDLE:
            self.state = MachineState.STARTING
            # تهيئة المستشعرات...
            self.state = MachineState.RUNNING
            print("الآلة تعمل")
        elif self.state == MachineState.ERROR:
            print("يجب إزالة الخطأ أولاً!")

    def report_error(self, code):
        self.state = MachineState.ERROR
        print(f"خطأ رقم {code} — الآلة متوقفة")

متى تستخدم OOP ومتى لا تستخدمها؟

الحالة الأسلوب المناسب
نمذجة آلات ومعدات لها حالات وسلوكيات OOP
حسابات رياضية بسيطة (تحويل وحدات) دوال عادية
أنظمة تحكم معقدة متعددة المكونات OOP مع أنماط تصميم
سكربتات قصيرة لمهمة واحدة لا حاجة لـ OOP
واجهات تواصل مع أجهزة PLC مختلفة OOP مع تعدد الأشكال

الخلاصة

البرمجة الكائنية تمنحك أدوات قوية لنمذجة أنظمة الأتمتة الصناعية:

  • الأصناف والكائنات تمثّل الآلات والمكونات الفعلية
  • التغليف يحمي المنطق الداخلي من التلاعب
  • الوراثة تبني عائلات من الأجهزة المتشابهة
  • تعدد الأشكال يتيح كود تحكم مرن وعام
  • أنماط التصميم توفّر حلولاً مجرّبة للمشاكل الشائعة

ابدأ بنمذجة الآلات التي تعمل عليها — ستجد أن OOP تُترجم العالم الصناعي إلى كود بشكل طبيعي جداً.

OOP class inheritance encapsulation polymorphism design-patterns البرمجة الكائنية الكائن التوريث التغليف تعدد الأشكال أنماط التصميم