Найти в Дзене

Codesys ООП. Объектно-ориентированное программирование на ПЛК.

Что-то эта тема стала слишком часто всплывать в разговорах, на различных семинарах и встречах. Я постараюсь структурировать все что знаю, не особо вдаваясь в подробности(вряд ли вам сильно понадобятся шаблоны проектирования), но максимально захватывая основы ООП в среде Codesys. ВТОРАЯ ЧАСТЬ(переход на мой блог) Что такое ООП и как представлено в языках МЭК. Объектно-ориентированное программирование (ООП) — методология программирования, основанная на представлении программы в виде совокупности объектов, каждый из которых является экземпляром определённого класса, а классы образуют иерархию наследования. Основные принципы структурирования в случае ООП связаны с различными аспектами базового понимания предметной задачи, которое требуется для оптимального управления соответствующей моделью: Вот что нам говорит первый абзац википедии. Если вы никогда с этим не сталкивались, то это вас может отпугнуть, а еще это новая тема для вечных споров, но это все мы затронем, но чуть позже. Из нашего
Оглавление

Что-то эта тема стала слишком часто всплывать в разговорах, на различных семинарах и встречах. Я постараюсь структурировать все что знаю, не особо вдаваясь в подробности(вряд ли вам сильно понадобятся шаблоны проектирования), но максимально захватывая основы ООП в среде Codesys.

ВТОРАЯ ЧАСТЬ(переход на мой блог)

Что такое ООП и как представлено в языках МЭК.

Объектно-ориентированное программирование (ООП) — методология программирования, основанная на представлении программы в виде совокупности объектов, каждый из которых является экземпляром определённого класса, а классы образуют иерархию наследования.

Основные принципы структурирования в случае ООП связаны с различными аспектами базового понимания предметной задачи, которое требуется для оптимального управления соответствующей моделью:

  • абстракция для выделения в моделируемом предмете важного для решения конкретной задачи по предмету, в конечном счёте — контекстное понимание предмета, формализуемое в виде класса;
  • инкапсуляция для быстрой и безопасной организации собственно иерархической управляемости: чтобы было достаточно простой команды «что делать», без одновременного уточнения как именно делать, так как это уже другой уровень управления;
  • наследование для быстрой и безопасной организации родственных понятий: чтобы было достаточно на каждом иерархическом шаге учитывать только изменения, не дублируя всё остальное, учтённое на предыдущих шагах;
  • полиморфизм для определения точки, в которой единое управление лучше распараллелить или наоборот — собрать воедино.

Вот что нам говорит первый абзац википедии. Если вы никогда с этим не сталкивались, то это вас может отпугнуть, а еще это новая тема для вечных споров, но это все мы затронем, но чуть позже.

Из нашего определения мы выяснили, что основной рабочей единицей для ООП является класс.

Класс в свою очередь — это описание того какой логикой и какими свойствами будет обладать объект. Объект — это экземпляр класса, который обладает собственным состоянием этих свойств.

В языках МЭК тоже есть такая вещь это FB и экземпляр (Instance), вот на основе этого и будет развиваться дальнейшее повествование.

И хоть в среде Codesys FB и класс это один и тот же элемент программы, но суть у них разная.

Теперь дальше, обращая внимание на великую мантру: абстракция, инкапусляция, наследование и полиморфизм.

Вот эту часть нам завезла третья редакция МЭК61131-3. И Codesys вроде как позволяет нам делать все эти страшные вещи.

Наследование

Вот наверно это одно из любимых и нужных на проектах с большим количеством однотипных объектов, но разных модификаций.

Наследование — это механизм, который позволяет перенять одним классом поведения и свойства другого класса для дальнейшего расширения или модификации.

Если очень в кратце, то вот у нас есть какой-нибудь класс, который отвечает за клапан.

FUNCTION_BLOCK VALVE
(* Функциональный блок клапана *)

METHOD Open
(* Логика открытия клапана *)
END_METHOD

METHOD CLOSE
(* Логика закрытия клапана *)
END_METHOD

END_FUNCTION_BLOCK

И вот у нас появляется новый клапан, который немного имеет кроме методов открытия и закрытия еще какое-то среднее положение

FUNCTION_BLOCK 3POS_VALVE(VALVE)//Наследуемся от FB VALVE
(* Функциональный блок трехпозиционного клапана *)
METHOD 2POS
(* Логика перехода к среднему положению*)
END_METHOD

END_FUNCTION_BLOCK

И теперь наш FB 3POS_VALVE имеет такую же логику открытия и закрытия как VALVE, но еще имеет 2POS, которого не было у родителя. И всем очень хорошо.

В стандартном процедурном подходе мы могли бы создать функцию открытия, функцию закрытия, функцию среднего положения. Там внутри ФБ вызывать или запихать все в один ФБ, нагородив разные команды.

Абстракция

Как видно из примера выше у каждого класса есть метода — его логика. А теперь представьте, что мы можем найти какие-то общие методы у множества объектов. да пусть даже тот же клапан, только обозначить что существуют такие методы поведения, но не реализовывать их.

Вот такое представление объекта, когда мы достаточно точно описываем его и есть абстракция.

Абстракция может быть представлена двумя способами — абстрактный класс и интерфейс.

В случае абстрактного класса он как описывает некоторые методы и состояния, так и может реализовывать часть их, но у абстрактного класса нет и не может быть экземпляра.

Интерфейс же только описывает методы и свойства, без реализации.

И если у вас тут просыпается вопрос, а зачем это надо, то считайте эти абстрактные вещи контрактом на реализацию. Благодаря интерфейсам и абстрактным классам, при наследовании от них, мы обязуемся реализовать все те методы, которые они описывают.

Для чего же?

Полиморфизм.

Это еще одна из фич системы, которая позволяет нам иметь множество реализация одного интерфейса и радоваться жизни.

Как это штука работает вместе с абстракциями?

И так у нас есть интерфейс клапана, который нам говорит что клапан имеет два метода Open и Close

INTERFACE VALVE
(* Интерфейс клапана *)

METHOD Open : BOOL
VAR_INPUT
(*Необходимые аргументы функцияя...ой*)
END_VAR

METHOD CLOSE : BOOL
VAR_INPUT

(*Необходимые аргументы метода*)
END_VAR

END_INTERFACE

А дальше представим, что у нас есть бочка(TANK), которая должна быть утыкана этими клапанами аки рождественская елка, проблема только в том, что мы пока еще не знаем какие клапана будут, но что нам мешает указать в FB емкости интерфейсы(НИЧЕГО)

И при реализации логики работы емкости я буду пользоваться методами интерфейса, а когда узнаю про клапана, то смогу реализовать логику открытия клапана и в программе подставлю готовый объект на вход где используется интерфейс. Если клапан заменят на клапан с другой логикой, я перепишу логику клапана, а емкости все равно, она не знает про реализацию, она лишь знает что у клапана наследуемого от интерфейса есть два метода, которые она и будет дергать.

Инкапсуляция

Инкапсуляция — это контроль доступа к полям и методам объекта. Под контролем доступа подразумевается не только можно/неможно, но и различные валидации, подгрузки, вычисления и прочее динамическое поведение.

Весьма нужный механизм, который позволяет держать внутри FB(класса) все данные необходимые для работы этого FB и плюс ограничивает доступ к методам и свойствам, оставляя возможность оперировать только открытыми методами и свойствами.

Зачем?

Вот самый важны вопрос всего этого действа. Стоит понимать, что ООП — не панацея. Данная парадигма не решает проблемы за раз, она не совсем дружелюбна, она тащит за собой много лишнего кода.

Что же она позволяет? Позволяет строит гибкие приложения, которые легко масштабируются(если все правильно продумать изначально) и легко редактируются.

Именно из-за плюсов и минусов в стандарте прописали смешенную парадигму. И в гайдлайне от PLCOpen также написано, что применяйте там где требуется и когда требуется. Так что всегда выбирайте инструмент под задачу, потому что если у вас в руках молоток, то все становится гвоздями.

От Автора

Если вы прочли статью и вам понравилось, то подпишитесь на канал. Также буду рад вашим комментариям и вопросам.

Новости автоматизации публикую здесь:

https://t.me/wtfcontrolsengineer

Большая часть практики будет тут:

https://blog.engcore.ru/

Список литературы