Dans la première partie, j'ai essayé de montrer qu'un chat OOP noir dans une pièce sombre des langages graphiques existe, même s'il ne s'agit pas d'un chat, mais d'un chat à moitié mort de l'écorcheur Schroedinger, c'est-à-dire qu'il ne l'est pas. Un exemple de la mise en œuvre de la méthodologie de la programmation orientée objet a été présenté, lorsqu'un programme n'est pas du code C ++ ou Java, mais un diagramme Simulink, SimInTech, SimulationX ou SCADE Esterel - toute notation graphique de la description de l'algorithme.
Dans le matériel publicitaire, Matlab Simulink utilise souvent le terme MOS - Design basé sur un modèle. Dans de nombreux textes, ils soulignent que le diagramme graphique de l'algorithme est un modèle, ce qui, bien sûr, est vrai. Cependant, dans la définition initiale de MOS, le modèle est principalement le modèle de l'objet sur lequel le système de contrôle est développé, y compris le logiciel de contrôle. Plus de méthodologie MOS est décrite ici. Ainsi, lors du développement d'un système de contrôle selon la méthodologie MOS, il est possible et nécessaire d'utiliser la méthodologie OOP pour développer un logiciel de gestion. Et pour fermer complètement le problème avec les modèles, voici une photo avec les différences de l'un par rapport à l'autre. Si tout est clair, alors vous ne pouvez plus lire.

Revenons aux langages graphiques et à la POO appliqués aux programmes de contrôle pour l'industrie. Le langage de programmation graphique fournit un enregistrement de programme sous la forme d'un diagramme à partir d'un ensemble de blocs connectés par des lignes de communication. En règle générale, dans la programmation industrielle, un code pour le compilateur et le chargement ultérieur dans l'équipement cible est créé à partir d'un circuit graphique par un générateur de code automatique.
Dans le cadre de ma spécialité, j'ai dû travailler avec la gestion de logiciels pour les centrales nucléaires où il est interdit d'utiliser le C ++ avec des normes de sécurité, uniquement du C pur, et dans certains cas même pas du C, mais une logique «ironique», où les algorithmes sont implémentés sous forme de circuits électroniques sur des transistors et relais. Et le respect des normes est surveillé par des gars de surveillance sévères.

Mais ici, aussi surprenant que cela puisse paraître, le développement utilise toujours la méthodologie OOP. Parce que lorsque vous ne pouvez pas utiliser la POO, mais que vous le voulez vraiment, vous le pouvez. Certes, alors tout doit être retourné, et ce ne serait pas un C ++ et le code final, pour des normes de sécurité et über alles. Comme on dit, manger un poisson et ne pas s'asseoir pour des violations.
Pour créer un objet réel par la définition de la POO, nous lions les structures de données et les schémas de traitement en un seul objet, c'est ce qu'on appelle l'encapsulation. Et comme nous ne pouvons pas utiliser C ++ pour des systèmes NPP fiables, nous devons analyser tout cela lors de la génération du code. Comme expliqué dans les commentaires de l'article précédent, le premier compilateur C ++ Front a fonctionné de la même manière, il a traduit le code OOP C ++ en C. pur
Dans la première version de l'implémentation de la POO dans un langage graphique, nous avons créé un bloc spécial contenant un schéma de calcul graphique. Lors de l'initialisation, ce bloc a lié le schéma de classes (méthode) à une «instance de classe» spécifique - un ensemble de variables nommées d'une manière spéciale.
Considérons le deuxième mode de réalisation de la méthodologie OOP dans les langages de programmation graphique. La figure 1 montre le fonctionnement de l'algorithme de traitement des capteurs.

Figure 1. Programme de traitement des capteurs.
Il s'agit d'une méthode de classe. Il correspond à sa propre catégorie "Capteurs" dans la base de données - une classe abstraite avec un ensemble donné de champs et une instance du capteur spécifique à la classe KBA31CFO1 . Pour ce capteur, les champs ont des valeurs spécifiques, certains champs sont définis par l'utilisateur, certains champs sont calculés par le processus d'exécution du programme. voir la photo 2

Figure 2. La base de données de signaux avec la catégorie ouverte «Capteur».
Jusqu'à présent, tout est comme dans le premier mode de réalisation, où nous avons formé la liaison du schéma de conception à un capteur spécifique lors de l'installation de l'unité sur le circuit. "Où est la différence?" - demandez-vous. Et la différence est à l'intérieur du bloc. Si dans la première version il y avait un schéma de conception à l'intérieur, qui a été copié avec chaque installation du bloc, alors dans cette version, l'intérieur ressemble à ceci:

Figure 3. L'intérieur d'une instance de bloc d'une instance de classe.
Au lieu du schéma de conception, seules la transmission et la réception des données sont «affichées» à l'intérieur du bloc.
Et le calcul lui-même a lieu à un autre endroit, dans le diagramme de la figure 1. Dans certains cas, il est possible de ne pas utiliser du tout de blocs dans le diagramme de calcul, il suffit d'avoir des instances de la classe de capteur dans la base de données des singles. Il s'agit de la deuxième façon d'implémenter l'encapsulation dans les langages graphiques. L'astuce est que tous les blocs dans le diagramme de la figure 1 sont vectoriels, et ils traitent non pas un signal, mais un vecteur de signaux de tous les capteurs de ce type dans le schéma de calcul. Si vous activez le mode d'affichage des résultats sur la ligne de communication, alors nous verrons que chaque ligne de communication contient non pas un chiffre, mais un vecteur de 4 nombres (selon le nombre de capteurs dans la base de données).

Figure 4. Schéma de traitement du signal des capteurs en mode de visualisation des valeurs.
Ainsi, un schéma de traitement implémente le traitement de tous les capteurs du projet, chaque capteur étant traité avec ses propres paramètres spécifiés dans la base de données en tant que caractéristiques d'une instance particulière de la classe. Par exemple, le limiteur prend la valeur maximale de la base de données, qui est la même pour les trois premiers capteurs et diffère pour le quatrième. (voir fig.5)

Figure 5. Paramètres du bloc limiteur dans le schéma de calcul.
Et qu'en est-il du code résultant, qui est généré automatiquement selon ce merveilleux schéma, comment parvenez-vous à éviter les artefacts OOP? C'est simple: pas de triche et pas de POO, du pur C dans le code. Pour chaque bloc du schéma de traitement vectoriel, un cycle sera formé qui fournira autant de calculs qu'il y a d'instances de classe dans le projet. Dans notre cas, il y a 4 capteurs, nous formons donc d'abord des tableaux de dimension «4» en lisant les signaux des capteurs:
}; 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
Ensuite, nous trions tous les blocs dans l'ordre et les exécutons en boucle. Pour chaque élément d'un tableau de type, chaque bloc de calculs sera effectué pour tous les capteurs.
for(i=0;i<4;i++){ locals->v211_out_0_[i] = state_vars->kbastdv125_out_0_[i] && (!(locals->v191_out_7_[i] > 0.5)); locals->v209_out_2_[i] = consts->kbastdv121_a_[i]*state_vars->kbastdv127_out_0_[i]; locals->v209_out_3_[i] = (1)*consts->kbastdv122_a_[i]+(1)*locals->v209_out_2_[i]; … }
Après le calcul, nous enregistrons les signaux pour chaque instance de la classe:
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];
Comme vous pouvez le voir, il n'y a aucun objet dans le code final. SI propre, innocent et sûr. Dans l'exemple ci-dessus, la mise en œuvre de la POO dans un langage graphique, un circuit vectoriel calcule tous les capteurs du même type. Cette technique vous permet de modifier un schéma pour modifier le traitement de tous les capteurs.
Un autre avantage supplémentaire de cette approche est l'assurance contre les erreurs. Imaginez: vous ajoutez manuellement un capteur et à un endroit, vous avez oublié d'augmenter le nombre de répétitions pendant le traitement dans un cycle. Aucun analyseur de code statique ne pourra détecter cette erreur, le code est correct. Et même au travail, cela peut ne pas affecter immédiatement et de manière évidente.
Eh bien, au final, le polymorphisme et l'héritage promis. Dans la première méthode, l'utilisateur a reçu de nombreux schémas identiques, qu'il a pu modifier après l'installation du bloc de sous-modèle et, par conséquent, effectuer un polymorphisme, modifiant le comportement d'une instance particulière de la classe. Je pense que tout le monde a deviné qu'il est possible de changer le schéma de traitement pour un capteur particulier, et nous obtiendrons une nouvelle classe avec des champs qui correspondent, mais les méthodes sont différentes. Vous pouvez également ajouter de nouveaux champs et obtenir une nouvelle classe avec différents champs contenant tous les champs du parent et les méthodes du parent.
La figure 6 montre un exemple de deux blocs des classes «parent» et «héritier». À l'intérieur du bloc, le schéma de calcul de la classe parent est enregistré. Toutes les données vont à un bloc vectoriel commun, similaire au bloc de la Fig. 4. La méthode de la classe parent est complètement répétée. Et puis la classe successeur a un champ supplémentaire Yatm et un recalcul supplémentaire de la valeur en utilisant le bloc d'interpolation linéaire.
Ainsi, il reste possible de changer les méthodes de traitement du parent, qui changeront dans toutes les classes-héritières, ainsi que de personnaliser individuellement le comportement de l'héritier.

Figure 6. Polymorphisme chez les héritiers de la classe.
Pour résumer, nous pouvons affirmer que la méthodologie OOP peut être utilisée pour créer des logiciels dans des langages de programmation graphiques. Abstraction, encapsulation, héritage, polymorphisme - tous ces principes sont facilement et naturellement mis en œuvre par les bons outils de développement. Il est important de noter que le code final, après génération automatique à partir d'un langage graphique, reste du C pur sans aucun OOP
Dans certains cas, le résultat du développement d'un logiciel de contrôle sous forme graphique n'est pas le code C pour le chargement dans les contrôleurs, mais le schéma de circuit "logique de fer", mais la technique décrite ci-dessus OOP fonctionne également très bien.