OOP dalam bahasa pemrograman grafis. Bagian 2 MOS dan OOP

Pada bagian pertama, saya mencoba untuk menunjukkan bahwa kucing OOP hitam di ruang gelap bahasa grafis ada, bahkan jika itu bukan kucing, tetapi kucing setengah mati dari flayer Schroedinger, yang artinya tidak. Contoh implementasi metodologi pemrograman berorientasi objek ditunjukkan, ketika sebuah program bukan C ++ atau kode Java, tetapi diagram Simulink, SimInTech, SimulationX atau SCADE Esterel - setiap notasi grafis dari deskripsi algoritma.


Dalam materi iklan, Matlab Simulink sering menggunakan istilah MOS - desain berbasis model. Dalam banyak teks, mereka menekankan bahwa diagram grafis dari algoritma adalah model, yang tentu saja benar. Namun, dalam definisi awal MOS, model ini terutama merupakan model objek yang dikembangkan sistem kontrol, termasuk perangkat lunak kontrol. Lebih banyak metodologi MOS dijelaskan di sini. Jadi, ketika mengembangkan sistem kontrol sesuai dengan metodologi MOS, adalah mungkin dan perlu untuk menggunakan metodologi OOP untuk pengembangan perangkat lunak manajemen. Dan untuk benar-benar menutup masalah dengan model, inilah gambar dengan perbedaan satu dari yang lain. Jika semuanya jelas, maka Anda tidak bisa lagi membaca.




Mari kita kembali ke bahasa grafis dan OOP sebagaimana diterapkan untuk mengontrol program untuk industri. Bahasa pemrograman grafis menyediakan catatan program dalam bentuk diagram dari serangkaian blok yang dihubungkan oleh jalur komunikasi. Sebagai aturan, dalam pemrograman industri, kode untuk kompiler dan pemuatan berikutnya ke peralatan target dibuat dari sirkuit grafis oleh generator kode otomatis.


Sebagai bagian dari spesialisasi saya, saya harus bekerja dengan mengelola perangkat lunak untuk pembangkit listrik tenaga nuklir di mana dilarang untuk menggunakan C ++ dengan standar keamanan, hanya C murni, dan dalam beberapa kasus bahkan tidak C, tetapi logika "besi", di mana algoritma diimplementasikan sebagai sirkuit elektronik pada transistor dan menyampaikan Dan kepatuhan terhadap standar dipantau oleh para pengawas yang keras.



Tapi di sini, betapapun mengejutkannya kedengarannya, pengembangannya masih menggunakan metodologi OOP. Karena ketika Anda tidak dapat menggunakan OOP, tetapi Anda benar-benar ingin, Anda bisa. Benar, maka semuanya harus dikembalikan kembali, dan itu tidak akan menjadi C ++ dan kode akhir, untuk keamanan dan standar standar semua. Seperti yang mereka katakan, makan ikan, dan tidak duduk untuk pelanggaran.


Untuk membuat objek nyata dengan definisi OOP, kami mengikat struktur data dan skema pemrosesan menjadi satu objek, ini disebut enkapsulasi. Dan karena kita tidak dapat menggunakan C ++ untuk sistem NPP yang andal, kita harus menguraikan semua ini saat membuat kode. Seperti yang dijelaskan dalam komentar di artikel sebelumnya, kompiler C ++ Front pertama bekerja dengan cara yang sama, ia menerjemahkan kode OOP C ++ menjadi murni C.


Dalam versi pertama implementasi OOP dalam bahasa grafis, kami membuat blok khusus yang berisi skema perhitungan grafis. Selama inisialisasi, blok ini mengikat skema kelas (metode) ke "instance kelas" tertentu - satu set variabel yang dinamai dengan cara khusus.


Pertimbangkan perwujudan kedua dari metodologi OOP dalam bahasa pemrograman grafis. Gambar 1 menunjukkan operasi algoritma pemrosesan sensor.



Gambar 1. Program pemrosesan sensor.


Ini adalah metode kelas. Ini sesuai dengan kategori sendiri "Sensor" dalam database - kelas abstrak dengan seperangkat bidang yang diberikan dan instance dari sensor spesifik kelas KBA31CFO1 . Untuk sensor ini, bidang memiliki nilai tertentu, beberapa bidang ditetapkan oleh pengguna, beberapa bidang dihitung selama pelaksanaan program. lihat gambar 2



Gambar 2. Database sinyal dengan kategori terbuka "Sensor".


Sejauh ini, semuanya seperti pada perwujudan pertama, di mana kami membentuk pengikatan skema desain ke sensor tertentu saat memasang unit pada sirkuit. "Di mana bedanya?" - kamu bertanya. Dan perbedaannya ada di dalam blok. Jika dalam versi pertama ada diagram desain di dalamnya, yang disalin dengan setiap instalasi blok, maka dalam versi ini bagian dalamnya terlihat seperti ini:



Gambar 3. Interior dari instance blok dari instance kelas.


Alih-alih skema desain, hanya pengiriman dan penerimaan data yang "ditunjukkan" di dalam blok.
Dan perhitungan itu sendiri terjadi di tempat lain, dalam diagram dari Gambar 1. Dalam beberapa kasus, dimungkinkan untuk tidak menggunakan blok sama sekali dalam diagram perhitungan, cukup untuk memiliki contoh kelas sensor dalam database tunggal. Ini adalah cara kedua untuk mengimplementasikan enkapsulasi dalam bahasa grafis. Kuncinya adalah bahwa semua blok dalam diagram pada Gambar 1 adalah vektorial, dan mereka memproses bukan satu sinyal, tetapi vektor sinyal dari semua sensor jenis ini dalam skema perhitungan. Jika Anda mengaktifkan mode menampilkan hasil pada jalur komunikasi, maka kita akan melihat bahwa setiap jalur komunikasi tidak mengandung satu digit, tetapi vektor 4 angka (sesuai dengan jumlah sensor dalam database).



Gambar 4. Diagram pemrosesan sinyal sensor dalam mode nilai tampilan.


Dengan demikian, satu skema pemrosesan mengimplementasikan pemrosesan semua sensor dalam proyek, dengan masing-masing sensor diproses dengan parameternya sendiri yang ditentukan dalam database sebagai karakteristik instance kelas tertentu. Sebagai contoh, limiter mengambil nilai maksimum dari database, yang ditetapkan sama untuk tiga sensor pertama dan berbeda untuk yang keempat. (lihat gambar 5)



Gambar 5. Parameter blok limiter dalam skema perhitungan.


Dan bagaimana dengan kode yang dihasilkan, yang secara otomatis dihasilkan sesuai dengan skema luar biasa ini, bagaimana Anda mengatur untuk menghindari artefak OOP? Ini sederhana: tidak ada kecurangan dan tidak ada OOP, C murni dalam kode. Untuk setiap blok skema pemrosesan vektor, siklus akan dibentuk yang menyediakan banyak perhitungan karena ada instance kelas dalam proyek. Dalam kasus kami, ada 4 sensor, jadi pertama-tama kami membentuk array dimensi "4" dengan membaca sinyal dari sensor:


/* Index=104 UID=104 GeneratorClassName=TSignalReader Name=buz1.sensor.Macro6.Macro3.Macro157.SignalReader3 Type=    */ }; state_vars->kbastdv104_out_0_[0] = kba31cf001_mf_type; state_vars->kbastdv104_out_0_[1] = kba32cf001_mf_type; state_vars->kbastdv104_out_0_[2] = kba33cf001_mf_type; state_vars->kbastdv104_out_0_[3] = uf40y329084320_mf_type 

Lalu kami mengurutkan semua blok secara berurutan dan menjalankannya dalam satu lingkaran. Untuk setiap elemen array tipe, setiap blok perhitungan akan dilakukan untuk semua sensor.


 /* Index=211 UID=211 GeneratorClassName=TAndSrc Name=buz1.sensor.Macro6.And61 Type=  */ for(i=0;i<4;i++){ locals->v211_out_0_[i] = state_vars->kbastdv125_out_0_[i] && (!(locals->v191_out_7_[i] > 0.5)); /* Index=212 UID=212 GeneratorClassName=TMulDbl Name=buz1.sensor.Macro6.Mul_oper1 Type= */ locals->v209_out_2_[i] = consts->kbastdv121_a_[i]*state_vars->kbastdv127_out_0_[i]; /* Index=213 UID=213 GeneratorClassName=TSumSrc Name=buz1.sensor.Macro6.Add_oper1 Type= */ locals->v209_out_3_[i] = (1)*consts->kbastdv122_a_[i]+(1)*locals->v209_out_2_[i]; … } 

Setelah perhitungan, kami merekam sinyal untuk setiap instance kelas:

 /* Index=776 UID=776 GeneratorClassName=TSignalWriter Name=buz1.sensor.Macro6.Macro3.SignalWriter4 Type=    */ kba31cf001_mf_xb01 = state_vars->kbastdv207_out_0_[0]; kba32cf001_mf_xb01 = state_vars->kbastdv207_out_0_[1]; kba33cf001_mf_xb01 = state_vars->kbastdv207_out_0_[2]; uf40y329084320_mf_xb01 = state_vars->kbastdv207_out_0_[3]; 

Seperti yang Anda lihat, tidak ada objek dalam kode akhir. SI bersih, polos dan aman. Dalam contoh di atas, implementasi OOP dalam bahasa grafis, rangkaian vektor menghitung semua sensor dari jenis yang sama. Teknik ini memungkinkan Anda mengubah satu skema untuk mengubah pemrosesan semua sensor.


Manfaat tambahan lain dari pendekatan ini adalah asuransi kesalahan. Bayangkan: Anda secara manual menambahkan sensor dan di satu tempat Anda lupa menambah jumlah pengulangan selama pemrosesan dalam satu siklus. Tidak ada penganalisa kode statis yang dapat mendeteksi kesalahan ini, kodenya benar. Dan bahkan di tempat kerja ini mungkin tidak mempengaruhi dengan segera dan dengan cara yang jelas.


Pada akhirnya, polimorfisme dan warisan yang dijanjikan. Dalam metode pertama, pengguna menerima banyak skema identik, yang dapat diedit setelah menginstal blok submodel dan, dengan demikian, melakukan polimorfisme, mengubah perilaku instance kelas tertentu. Saya pikir semua orang menduga bahwa mungkin untuk mengubah skema pemrosesan untuk sensor tertentu, dan kami akan mendapatkan kelas baru yang memiliki bidang yang sama, tetapi metodenya berbeda. Anda juga bisa menambahkan bidang baru dan mendapatkan kelas baru dengan bidang berbeda yang berisi semua bidang induk dan metode induk.


Gambar 6 menunjukkan contoh dua blok kelas "induk" dan "pewaris". Di dalam blok, skema perhitungan kelas induk disimpan. Semua data pergi ke blok vektor umum, mirip dengan blok pada Gambar. 4. Metode kelas induk diulangi sepenuhnya. Dan kemudian kelas penerus memiliki Yatm bidang tambahan dan perhitungan kembali nilai tambahan menggunakan blok interpolasi linier.


Dengan demikian, tetap dimungkinkan untuk mengubah metode pemrosesan induk, yang akan berubah di semua kelas-ahli waris, serta secara individual menyesuaikan perilaku ahli waris.



Gambar 6. Polimorfisme pada ahli waris kelas.


Untuk meringkas, kami dapat berpendapat bahwa metodologi OOP dapat digunakan untuk membuat perangkat lunak dalam bahasa pemrograman grafis. Abstraksi, enkapsulasi, pewarisan, polimorfisme - semua prinsip ini mudah dan alami diimplementasikan oleh alat pengembangan yang tepat. Penting untuk dicatat bahwa kode akhir, setelah pembuatan otomatis dari bahasa grafis, tetap murni aman C tanpa OOP


Dalam beberapa kasus, hasil pengembangan perangkat lunak kontrol dalam bentuk grafis bukan kode C untuk memuat ke controller, tetapi diagram sirkuit "logika besi", tetapi teknik yang dijelaskan di atas OOP juga berfungsi dengan baik.

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


All Articles