Рассматривая объектно-ориентированное программирование на ПЛК в среде Codesys следует затронуть тему об отношениях между различными функциональными блоками(классами) и объектами(экземплярами данных классов/функциональных блоков).
В предыдущих сериях:
Отношения в ООП
Отношения в объектно-ориентированной парадигме — это связь между этими самыми объектами. Во всяких языках где есть динамическое создание от этого зависит и время жизни объектов, но так как в нашем случае динамическое создание это очень муторно, да и вообще противозаконно, все отношения будут рассмотрены с точки зрения доступа к данным.
Далее будут рассмотрены наследование или генерализация, и два типа ассоциации и мы вообще не будем затрагивать реализацию и углубляться в мелочи.
Наследование
Наследование уже была рассмотрено ранее и было сказано, что это механизм, который позволяет перенять одним классом поведение другого. Благодаря наследованию мы с уверенностью можем сказать, что все что справедливо для родительского класса, справедливо и для дочернего.
И снова пример про клапаны.
Для начала у нас был родительский класс Valve, который имеет в себе два метода: Open(), Close(), которые работают ровно так как вы от них ожидаете и одна Output переменная xSignal, необходимая для подачи сигнала.
Потом у нас в системе появляется клапан с обратной связью. Разница в том, что у нас есть две переменные в Input блоке, которые показывают значение концевиков,мы немного расширили сигналы вывода. Теперь наш блок выдает наружу состояние клапана. И метод Update(), который реализует логику обновления выходных данных согласно новым входным данным.
И теперь в случае чего мы можем спокойно поменять клапана Valve на клапан ValveFB так как у нас есть методы Open(), Close() и тут и там. Но мы не можем использовать клапана Valve там, где используется клапан ValveFB из-за метода Update() и вороха новых переменных.
Лирическое отступление.
В примере выше мы рассматриваем только наследование и ничего более. OCP не входит в зону ответственности.
Агрегация
Это отношение, когда функциональный блок ну или DUT создается где-то вне и потом передается. В нашем случае либо в InOut переменные, ну либо ссылочкой в Input переменные.
И вот самое интересное, что у нас есть. Мы в функциональный блок Tank передаем указатель на функциональный блок ValveFB, который будет где-то объявлен, но суть агрегации в том, что мы можем использовать экземпляр функционального блока ValveFB где-то еще.
Композиция
Очень похожа на агрегацию, за одним маленьким исключением. Объект создается внутри функционального блока, живет там и там же умирает.
Все что отсылает нас к композиции мы объявляем в разделе VAR. Мы можем использовать эти переменные и классы, и методы только внутри этого функционального блока.
Стандартная вещь — это блоки таймеров внутри FB
Итого
Были рассмотрены основные виды отношений в ООП. Главный вопрос, а для чего? Во-первых, для формирование общего понятийного аппарата, а во вторых, для того чтобы было проще дальше разбираться с объектно-ориентированным программированием.
Если вы дочитали до конца, то можете подписаться на новостной канал в ТГ. Там частенько появляются новости промышленной автоматизации, которые отличаются от «Вышел новый датчик от…». Всем спасибо.