برمجة الكائنات في اللغات الرسومية

البرمجة الموجهة للكائنات (OOP) هي مفهوم مصمم لتسهيل تطوير النظم المعقدة من خلال إدخال مفاهيم جديدة أقرب إلى العالم الحقيقي من لغات البرمجة الوظيفية والإجرائية. كما كتبت ويكيبيديا ، "اللغة الإنسانية العادية ككل تعكس أيديولوجية OOP ، بدءًا بتغليف فكرة كائن في شكل اسمه وتنتهي مع تعدد الأشكال من استخدام الكلمة بالمعنى المجازي ، الذي يطور في نهاية المطاف التعبير عن التمثيل من خلال اسم الكائن إلى فئة كاملة المفهوم."




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


من ناحية أخرى ، هناك تدوينات رسومية للبرنامج ، وهي ليست قريبة من اللغة البشرية ، ولكنها أكثر قابلية للفهم حتى من أي رمز ، وليس مثل OOP. من الممكن أن يكون هذا الأمر أكثر وضوحًا بالنسبة لي ، وهو مدلل بالتعليم الهندسي ، لكن هناك الكثير من الناس مثلي وهذا النص لنفس علماء الفيزياء المدللين الذين لا يفهمون التجريدات العالية.


هنا ، على سبيل المثال ، وصف حقيقي في التدوين الرسومي لخوارزمية التحكم في صمام بوابة NPP:



الشكل 1. مثال لبرنامج التحكم NPP في تدوين رسومية

على اليسار توجد إشارات الإدخال ، على اليمين توجد الأوامر.

يبدو لي أنه حتى الطفل يمكنه قراءة هذه الخوارزمية:

  • إذا تم تشغيل المضخة لمدة 60 ثانية وكان معدل التدفق أقل من 10 ، فافتح صمام إعادة الدوران.
  • إذا كانت المضخة قيد التشغيل ، فامنح الأمر لفتح خلال 5 ثوانٍ للصمامات 001 و 002.
  • إذا كان معدل التدفق أكبر من 20 وتم تشغيل المضخة ، في غضون 5 ثوانٍ لإرسال صمام الغالق 003 لإغلاق أمر.

عندما كنت طالبًا ، عملت بدوام جزئي من خلال إنشاء مكتبة مكونات لـ Delphi وكنت معتادًا على OOP بشكل مباشر. ثم ، عندما صادفت برامج حقيقية للتحكم في محطات الطاقة النووية ، فوجئت جدًا بعدم وجود أي تجريد أو تغليف أو سامحني ، تعدد الأشكال ، توصية C فقط صافية ، وتوصية MISRA C التي تم تقليصها بموجب القواعد بحيث أصبح كل شيء موثوقًا به ومحمولًا.


كانت ذروة قطع C في ممارستي FIL ، لأنظمة التحكم في مفاعل RBMK. في ذلك ، تمت كتابة الوظائف مسبقًا في C ، وتم تجميعها ، ثم استُدعت على أساس ملف نصي ، حيث تم وصفها بلغة FIL. نتيجة لذلك ، كان من الممكن استدعاء مجموعة محدودة فقط ، ولكن تم اختبارها بعناية وتصحيحها. وكل هذا باسم السلامة والموثوقية.


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


وبعد ذلك - حتى أكثر إثارة للاهتمام. في الواقع ، فإن برنامج إدارة محطة الطاقة النووية ليس مكتوبًا من قبل المبرمج ، ولكن من قِبل المبرمج - إنه يعرف فقط ما ومتى يجب إغلاقه ، وفتحه ، وتشغيله ، والأهم من ذلك - إنه يعرف متى يقوم بإيقاف الزورق ، حتى لا يتعطل. ويجب على مبرمج تنفيذ كل هذا بعناية في رمز C. والأفضل من ذلك ، أنه لن يكون هناك مبرمج على الإطلاق ، وقد رسم الخبير التقني نفسه الخوارزميات التكنولوجية لبرامج التحكم في شكل رسوم بيانية ، وقام بإنشاء كود C تلقائيًا وتحميله في معدات التحكم. توصي معايير السلامة الدولية بهذا ؛ وفي هذه الحالة ، لا يلزم وجود مبرمج - مثل عازف الكمان. يقدم فقط الأخطاء والتشوهات الإضافية في تنفيذ أفكار تقني.




كان ما دهشني عندما اكتشفت أن تقنيي ومصممي NPP ، بصرف النظر عن المبرمجين ، قاموا بتطوير واستخدام البرمجة الموجهة للكائنات بنجاح ، وحتى في التدوينات الرسومية ، لكن الشفرة الناتجة تلبي تمامًا متطلبات الأمان ولا تحتوي على عناصر منهجية OOP .


في الواقع ، إذا نظرت إلى الكود الذي تم إنشاؤه من الدائرة في الشكل 1 ، فسوف نرى C خالص دون أي فصول هناك.
على سبيل المثال ، جدول إدخال الخوارزمية:


/* Index=0 UID=0 GeneratorClassName=TSignalReader Name=KBA__AA.KBA31EY001.alg_inp Type=  */ state_vars->kbaalgsv0_out_1_ = kba31ap001_xb01; state_vars->kbaalgsv0_out_4_ = kba31cf001_xq01; 

مجرد تعيين المتغيرات.
يتم وصف أي كتلة على أنها حساب المخرجات حسب المدخلات ، مع مراعاة المعلمات المحددة في قائمة الثوابت. على سبيل المثال ، تبدو كتلة "المزيد" هكذا في الكود:


 /* Index=5 UID=5 GeneratorClassName=TLogBlock Name=KBA__AA.KBA31EY001.smu.GT2 Type=  */ locals->v5_out_0_ = state_vars->kbaalgsv0_out_4_ > consts->kbaalgsv3_a_; 

إخراج الكتلة هو نتيجة لمقارنة إشارة الدخل مع قيمة في ثابت.


وبالتالي ، في الكتل الأخرى ، يتم حساب المتغيرات المحلية من متغيرات الإدخال بالتسلسل ، وفي نهاية دورة البرنامج ، تتم كتابة المتغيرات على متغيرات المخرجات.


 /* Index=14 UID=14 GeneratorClassName=TSignalWriter Name=KBA__AA.KBA31EY001.alg_out Type=  */ if((action==f_InitState)||(action==f_GoodStep)||(action==f_RestoreOuts)){ kba31ey001_yb01 = locals->v8_out_0_; kba31ey001_yb11 = state_vars->kbaalgsv9_out_0_; kba31ey001_yb12 = state_vars->kbaalgsv12_out_0_; kba31ey001_yb02 = locals->v13_out_0_; }; 

أين هي الطبقات هنا ، تسأل؟


المنهجية الكاملة المتعلقة بـ OOP موجودة بأسماء متغيرة. يبدو أن هذا يمكن أن يكون في اسم متغير؟ وقد يكون هناك هاوية كاملة. على سبيل المثال ، اسم المتغير هو kba31ap001_xb01 ، مجرد متغير في كود C يلبي متطلبات اسم المتغيرات. ومع ذلك ، بالنسبة لمهندس التصميم ، يبدو الأمر كما يلي: "حجرة المفاعل ، نظام تزويد المياه الصناعي ، المضخة الأولى ، بدء التشغيل". يحدث كل هذا التحويل السحري بفضل نظام الترميز الألماني الرائع (Kraftwerk-Kennzeichensystem) KKS ، اقتباس:


"تم تصميم نظام تصنيف الترميز هذا لمحطات الطاقة ولديه إمكانات كبيرة ، كما أنه يأخذ في الاعتبار ميزات أجهزة المعالجات الدقيقة القابلة للبرمجة بحرية.


إلى جانب وضع العلامات على المعدات التكنولوجية والهيئات التنفيذية (الإغلاق والسلامة والإغلاق وما إلى ذلك الصمامات والآليات المساعدة) ونقاط القياس ووحدات التركيب وأجهزة الأتمتة والمباني والهياكل ، يسمح نظام KKS بوضع علامات على خوارزميات وبرامج من أنواع مختلفة والأغراض (معالجة خوارزميات المعلمات التكنولوجية المقاسة ، والتشوير ، والتنظيم التلقائي ، والحماية التكنولوجية ، والتحكم المنطقي: الأقفال ، ABP ، البرامج خطوة بخطوة ، - حساب t يتم عرض مؤشرات hniko والاقتصادية وتشخيص المعدات التكنولوجية)، المدخلات والمخرجات وإشارات وسيطة من الخوارزميات وبرامج وتسجيلات الفيديو من جميع المستويات على محطات الفيديو، والكابلات، الخ ... "


ولكن الأكثر إثارة للاهتمام في الجزء الأخير من الاسم هو _xb01 ، والذي يتم تحديده من خلال الشرطة السفلية. إذا نظرت إلى قاعدة الإشارة لمشروع الإدارة ، فسوف نرى فصولاً هناك مفهومة ومألوفة لكل من كان مهتمًا في مكان ما وفي مكان ما وفي مكان ما (انظر الشكل 2).



الشكل 2. مثال على بنية قاعدة إشارة لنظام التحكم في محطة الطاقة النووية.

لدينا فصول ، أو جداول ، في الشكل ، هذا هو العمود "الفئات". على سبيل المثال ، "KD1" الذي يحتوي على جدول إشارات المخطط ، وحقول فئة الحد الأقصى للقياس ، والحد الأدنى للقياس ، وقراءة المستشعر ، إلخ. هو التجريد.


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


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


في هذه المرحلة ، يمكننا القول ، الانتظار ، هذه ليست OOP على الإطلاق ، أو حتى لا OOP على الإطلاق ، إنها مجرد بنية بيانات ، إنها في المعيار C. وأين هو تغليف الأساليب في الفصل؟ يجب أن تكون معالجة البيانات في الفصل ، ثم ستكون هذه هي طريقة OOS الحقيقية.
دعونا نرى كيف تبدو الروتين الفرعي للتحكم في موثوقية المستشعر في شكل رسوم بيانية. الشكل 3 جزء من دائرة معالجة الإشارات:



الشكل 3. مثال على برنامج معالجة الإشارات.

يمكن ملاحظة أنه في عملية المعالجة الفرعية ، يتم استخدام أسماء المتغيرات TK21F02B1_XQ04 ، وتم تشكيلها وفقًا لقواعد KKS واستناداً إلى جدول حقل الفئة. في المثال أعلاه ، يتم حساب قراءات المستشعر في المئة TK21F02B1_XQ03 وفقًا للقيم المحددة لحقول مثيل الفئة مثل TK21F02B1_Xmin و TK21F02B1_Xmax.


إذا لجأنا إلى الكود الذي تم إنشاؤه من هذا المخطط ، فسوف نرى تعيينًا بسيطًا لقيمة لمتغير ونقي C ولا إيجابيات و OOP.


  /* Index=12 UID=12 GeneratorClassName=TSignalReader Name=KD1.kd3_45.SR6 Type=    */ state_vars->su100v12_out_0_ = tk21f02b1_ai; 

وتعيين نتيجة الحساب ، وأيضًا كإحالة بسيطة لمتغير (مع التحقق من صحة الرقم ، حتى لا يتم إسقاط النظام إذا تلقينا خطأ نتيجة لمعالجة الإشارة)


 /* Index=100 UID=100 GeneratorClassName=TSignalWriter Name=KD1.kd3_45.SW3 Type=    */ if(isfinite(locals->v63_out_0_)){ tk21f02b1_xq04 = locals->v63_out_0_; }; 

وفي أي لحظة يظهر اتحاد هذه الحقول من فئة أساليب المعالجة؟ في الواقع ، أنا معتاد على خيارين لهذا التركيز. الآن سوف نقوم بتحليل واحد منهم. ( يتم تحليل الخيار الثاني هنا .. )
دعونا نرى كيف تم تكوين الكتلة التي توجد بها دائرة برنامج المعالجة على الرسم البياني (انظر الشكل 4).


لدينا دائرة نضع عليها كتل من نموذج فرعي من لغة البرمجة الرسومية ؛ داخل هذه الكتل دائرة رسومية ، يظهر جزء منها في الشكل 3 ، وهو برنامج لمعالجة الإشارات من أجهزة الاستشعار.


في خصائص هذه الكتلة ، نرى حقول قاعدة بيانات الإشارة وقائمة منسدلة تحتوي على إشارات موجودة بالفعل في قاعدة البيانات ، ومثيلات الفئة ، وأجهزة استشعار محددة من هذا النوع. يكفي اختيار المستشعر المرغوب ، ومثال الفئة بالاسم ، وتحدث المعجزة. في المخطط ، تتلقى جميع كتل القراءة والكتابة أسماء من النوع TK21F02B1_XQ03 ، (اسم مستشعر مثيل الفئة + اسم الحقل).


الآن ، عند إنشاء رمز C ، ستتلقى جميع المتغيرات قيم المستشعر المرغوب. وليس هناك حاجة للمبرمج ، فقد قام الفني بكل شيء بنفسه عندما طور المخطط بلغة البرمجة الرسومية لخوارزمية التحكم في NPP.



الشكل 4. مثال على إعداد دائرة تجهيز أجهزة الاستشعار.

لتعيين الأسماء ، يتم استخدام برنامج نصي خاص للتشغيل الآلي في بيئة تصميم نظام التحكم ، كما هو موضح تقريبًا كما هو موضح في الشكل 5. يتم تعيين جميع كتل القراءة في الرسم التخطيطي على أسماء تتكون من اسم الكائن واسم الحقل في الفصل (انظر الشكل 5).



الشكل 5. تحديد اسم المتغيرات في كتل القراءة.

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


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


من الواضح أن مثل هذا التطبيق لأدوات التشغيل الآلي ، بالإضافة إلى تسريع عملية التطوير ، يمكن أيضًا أن يقلل بشكل كبير من وقت التطوير ، وعدد الأخطاء في برامج التحكم.

Source: https://habr.com/ru/post/ar451148/


All Articles