Объектно-ориентированное программирование (ООП) – концепция, которая призвана облегчить разработку сложных систем, за счет введения новых понятий, более приближенных к реальному миру, чем функциональные и процедурные языки программирования. Как пишет википедия, «Обычный человеческий язык в целом отражает идеологию ООП, начиная с инкапсуляции представления о предмете в виде его имени и заканчивая полиморфизмом использования слова в переносном смысле, что в итоге развивает выражение представления через имя предмета до полноценного понятия – класса.» Но с точки зрения всех, кто впервые сталкивался эти этим абстракциями, после классических процедурных языков понятнее не становилось, кажется наоборот все еще больше запутывалось. С другой стороны, есть графические нотации работы программы, которые не приближены к человеческому языку, но гораздо понятнее, чем даже любой код, не то что ООП. Вполне возможно, что это более понятно мне, испорченному инженерным образованием, но таких как я много и этот текст для таких же испорченных физиков, не понимающих высокие абстракции. Вот, например, реальное описание в графической нотации алгоритма управления задвижками АЭС.:  Слева входные сигналы, справа команды.

Мне кажется, что такой алгоритм прочитать может даже ребенок:

 В бытность мою студентом я подрабатывал, создавая библиотеку компонентов для Delphi и был знаком с ООП не понаслышке. Потом, когда столкнулся с реальными программами управления АЭС, очень удивился что нет никакого абстрагирования, инкапсуляции и, прости господи полиморфизма, только чистый Си, и еще желательно урезанный правилами и рекомендация MISRA C, чтобы все было надёжно, переносимо, безопасно.  Вершиной обрезания Си в моей практике был язык FIL, для систем управления реакторами РБМК. В нем функции заранее писались на Си, компилировались, а потом вызывались на основе текстового файла, где они были описаны на языке FIL. В итоге, можно было вызвать только ограниченный, но тщательно проверенный и отлаженный набор функций. И все это – во имя безопасности и надежности. Но при этом система управления реактором и в целом система управления АЭС – это как раз тот случай, где принципы ООП должны применятся в полный рост. В само деле, есть множество однотипного оборудования – задвижки, насосы, датчики, всё легко классифицируется, есть готовые объекты, соответствующие реальному оборудованию. Казалось бы, вот оно – применяй ООП, классы, наследование, абстрагирование и полиморфизм. Но нет, нужен чистый Си и это требования безопасности.  А дальше – еще интереснее. На самом деле программу для управления АЭС пишет не программист, а технолог – только он знает, что и когда закрывать, открывать, включать, а главное – он знает, когда всю это байду выключать, чтобы не долбануло. А программист должен аккуратно всё это реализовать на коде Си. А еще лучше, что бы программиста вообще бы не было, а технолог сам рисовал технологические алгоритмы управляющих программ в графическом виде, автоматически генерировал код Си и загружал его в аппаратуру управления. Это рекомендуют международные стандарты по безопасности, в этом случае программист – как скрипач – не нужен. Он вносит только дополнительные ошибки и искажения в реализацию мыслей технолога. Каково же было мое изумление, когда я узнал, что технологи и проектанты АЭС, сами независимо от программистов разработали и успешно применяют объектно-ориентированное программирование, да еще в графических нотациях, но при этом результирующий код полностью удовлетворяет требованиям безопасности и не содержит артефактов методологии ООП. В самом деле, если посмотреть на код, который сгенерирован из схемы на рисунке 1 мы увидим чистый Си без всяких там классов.
Например таблица входа в алгоритм: Просто присвоение переменных.
Любой блок описывается как вычисление выхода по входу, с учетом параметров, заданных в списке констант. Например блок «Больше» выглядит в коде так: Выход блока это результат сравнение сигнала входа со значением в константе. Таким образом, и в других блоках происходит последовательное вычисление локальных переменных из входных, и в конце цикла программы осуществляется запись в выходные переменные. А где здесь классы, спросите вы? Вся методология, связанная с ООП, находится в именах переменных. Казалось бы, что такого может быть в имени переменной? А там может быть цела бездна. Например имя переменной kba31ap001_xb01, просто переменная в коде Си отвечающая требованием по наименованию переменных. Однако для технолога проектанта она выглядит примерно так: «Реакторное отделение, система промышленного водоснабжения, первый насос, пуск». Все это волшебство преобразования происходит благодаря замечательной немецкой системе кодирования (Kraftwerk-Kennzeichensystem) KKS, цитата: “Данная система классификации кодирования предназначена для электростанций и обладает большими возможностями, а так же, учитывает особенности свободно-программируемых микропроцессорных технических средств. Наряду с маркировкой технологического оборудования, исполнительных органов (запорно-регулирующей, предохранительной, отсечной и т.п. арматуры, механизмов собственных нужд), точек измерения, монтажных единиц, устройств автоматизации, зданий и сооружений, система KKS позволяет маркировать алгоритмы и программы различного вида и назначения (алгоритмы обработки измеряемых технологических параметров, сигнализации, автоматического регулирования, технологических защит, логического управления: блокировок, АВР, пошаговых программ, — расчета технико-экономических показателей и диагностики состояния технологического оборудования), входные, выходные и промежуточные сигналы этих алгоритмов и программ, видеограммы всех уровней, отображаемые на видеотерминалах, кабели и пр.». Но самое интересное в последней части имени — _xb01, то что задается через знак подчеркивания. Если посмотреть на базу сигналов для проекта управления, то мы увидим там классы, понятные и знакомые всем, кто когда-то, как-то и где-то интересовался ООП (см. Рис. 2).  У нас есть классы, или таблицы, на рисунке это столбец «Категории». Например, «KD1» у которых есть таблица шаблонных сигналов, полей класса Верхний предел измерения, нижний предел измерения, показание датчика и т.д. — это абстракция. А так же есть реализация данного класса — конкретный датчик, например ТК21F02B1, расположенный в контуре, как вы уже догадались по его названию, в «Реакторном отделении, системе промышленного водоснабжения, у первого насоса», да и то, что это датчик расхода, тоже есть в этом названии, но это не точно. И у этого экземпляра данного класса есть конкретные сигналы и их значения, в процессе работы программы, и к ним можно получить доступ по именам полей класса. Например, показание датчика рабочее обозначается переменной ТК21F02B1_XQ04.  На этом месте можно сказать, постой это же не совсем ООП, или даже совсем не ООП, тут же просто структуры данных, это есть и в стандартном Си. А где инкапсуляция методов в состав класса? Обработка данных должна быть в классе, тогда это и будет настоящий кошерный метод ООП. 
Посмотрим, как выглядит в графическом виде подпрограмма контроля достоверности датчика. На рисунке 3 часть схемы обработки сигналов:  Видно, что в подпрограмме обработки используются имена переменных ТК21F02B1_XQ04, сформированные по правилам ККS и на основании таблицы полей класса. В приведенном примере происходит вычисление показания датчика в процентах ТК21F02B1_XQ03 по заданным значениям полей экземпляра класса таким, как ТК21F02B1_Xmin и ТК21F02B1_Xmax.  Если обратится к коду, сгенерированному из этой схемы, то мы увидим простое присвоение значение переменной, чистый Си и никаких плюсов и ООП. И присвоение результата расчета, тоже как простое присвоение переменной (с проверкой на действительность числа, что бы не уронить систему если в результате обработки сигналов мы получили ошибку) А в какой же момент появляется объединение данных полей класса методов обработки? На самом деле я знаком с двумя вариантами этого фокуса. Сейчас разберем один из них. (Второй вариант разобран здесь..)
Посмотрим, как на схеме настраивается блок в котором расположена схема программы обработки (см. рис. 4). У нас есть схема, на которую мы размещаем блоки субмодели графического языка программирования, внутри этих блоков находится графическая схема, часть которой приведена на рисунке 3, — программа обработки сигналов с датчиков. В свойствах данного блока мы видим поля базы данных сигналов и выпадающий список, в котором находятся уже существующих в базе данных сигналов, экземпляры класса, конкретные датчики данного типа. Достаточно выбрать нужный датчик, экземпляр класса по имени и происходит чудо. В схеме все блоки чтение и записи получают имена типа ТК21F02B1_XQ03, (имя датчика экземпляра класса + имя поля).  Теперь при генерации кода Си все переменные получат значения нужного датчика. И программист не нужен, технолог все сделал сам когда разрабатывал схему в графическом языке програмирования для алгоритма управления АЭС.   Для присвоения имен служит специальный скрипт автоматики в среде проектирования систем управления, примерно такой, как на рисунке 5. Всем блокам чтения на схеме присваиваются имена, состоящие из имени объекта и имени поля в классе (см. рис. 5).  Ясно, что аналогичным образом может быть создано неограниченное количество вариантов обработки сигналов, по сути методов для класса в методологии ООП. Точно так же могут быть сформированы для датчика, его подведение при отображении на видеокадрах SCADA системы, или например обработка процедур изменения уставок. Создается схема в графическом виде, сохраняется виде блока и используется при необходимости. Подведу итог: в графических языках программирования методы ООП так же применяются и приносят пользу. А после генерации исходного кода управляющих программ, все артефакты методологии ООП, исчезают и остается, чистый С, безопасный, надежный, верифицируемый. Понятно, что такое применение средств автоматизации кроме ускорения разработки, позволяет так же значительно сокращать время разработки количество ошибок в управляющих программах. Продолжение темы здесь. Моделирование сложных технических систем