OpenEdge® Development: Object-oriented Programming

Считаю, что рано или поздно нужно начинать использовать технологии ООП в OpenEdge. Помочь разобраться поможет официальное руководство OpenEdge® Development: Object-oriented Programming, перевод которого я выкладываю по мере готовности.

ABL и объектно-ориентированное программирование

Объектно-ориентированное программирование – популярная модель разработки программного обеспечения. Существуют определенные стандарты для ОО (объектно-ориентированных) языков – это поддержка инкапсуляции, наследования и строгой типизации. В версиях OpenEdge младше чем 10.2А ABL предоставлял лишь ограниченную поддержку этих стандартов при помощи персистентных (persistent) процедур. Текущий релиз OE включает в себя расширения языка для более полной поддержки стандартов ОО программирования в той мере, в какой эти стандарты реализованы в популярных языках программирования, например в JAVA.

Эти расширения дополняют мощь языка ABL и могут легко сочетаться с процедурной моделью разработки программ. Таким образом, ОО-расширения в языке только усиливают возможности ABL в своей бизнес-ориентированности, высокой производительности и легкости использования.

Ниже приводится краткий обзор

  • Поддержки классов в ABL
  • Модели разработки ABL
  • Обзор объектно-ориентированной парадигмы разработки
  • Обзор классов ABL
  • Соглашения при использовании классов

Поддержка классов в ABL

Основной задачей при встраивании ОО-функционала в ABL было расширение языка связной и стандартной моделью ООП при одновременной поддержке предыдущей процедурной модели разработки. Таким образом, наряду с процедурным программированием добавлены классы ABL. ОО-методика разработка приложений соответствует стандартам OpenEdge Reference Architecture (OERA), разработка которых началась с версии OE 10.
Всю необходимую информацию по OERA можно найти по ссылке http://communities.progress.com/pcom/community/psdn/openedge/architecture.

Класс, так же, как и процедура содержит данные (или своё состояние) и определяет способы манипуляции этими данными. Таким образом, классы и процедуры похожи тем, что они обладают возможностью определять объекты. Объект – это автономный блок кода, который определяет экземпляр с четко определенным состоянием и поведением.

В выпусках OE до версии 10.1A персистентные процедуры позволяли вам манипулировать только такими объектами, большинство связей между которыми создавалось и управлялось только во время исполнения кода. С другой стороны, классы ABL позволяют определить связи между собой ещё во время компиляции, что позволяет виртуальной машине ABL (AVM, ABL Virtual Machine) автоматически управлять этими связями во время исполнения программы. Таким образом, в отличии от персистентной процедуры класс является хорошо структурированным типом (или объектным типом), который распознается AVM при компиляции и позволяет вам реализовать во время исполнения программы объект в соответствии со своим описанием.

Классы, по своему определению, используют множество ОО-функций, которые позволяют поддерживать состояние и поведение объекта в приложении. Персистентные процедуры могут предоставить лишь ограниченную поддержку такого функционала. Переменные, буферы, временные таблицы итд, определяемые в MAIN-блоке персистентной процедуры описывают данные объекта, а внутренние процедуры и пользовательские функции – поведение объекта. Но не все особенности ООП можно передать при помощи персистентных процедур.

Улучшения в языке ABL предоставляют полный набор ОО-ориентированных конструкций, которые соответствуют стандартам ООП. Любой специалист, разбирающийся в ООП, может начать без особого труда разрабатывать ОО-программы в ABL. А любой новичок в ООП может читать любую книгу о концепциях ООП и взять из этого руководства новый синтаксис ABL .

Сильные стороны классов в ABL

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

 

  • Классы поддерживают мощную модель программирования путем инкапсуляции связанной функциональности в объектах. Преимущество такого рода организованного кода проявляется в обслуживании, где необходимые изменения или улучшения могут быть ограничены другими зависящими объектами
  • Классы позволяют повторно использовать код. Общий код может быть помещен в один класс и использоваться в других связанных классах. Эти классы могут при необходимости переопределять начальную функциональность класса-предка, а также функциональность других связанных классов.
  • Классы обеспечивают строгий контроль типов, который позволяет ABL проводить проверку еще при компиляции, не доводя дело до выполнения. Проверка во время компиляции просмтаривает абсолютно все интерфейсы и процедуры, что не всегда удается при обычном тестировании
  • ОО-архитектура легче транспонируется на сервисно-ориентированную архитектуру приложений (SOA) и позволяет широко использовать другие современные инструменты моделирования/проектирования приложений
  • Поддержка ООП в ABL позволяет использовать .Net объекты в Windows. При помощи OpenEdge GUI для .Net можно использовать любую форму или контрол .Net для создания .Net-графического интерфейса для всех Windows-клиентов ABL. Использовать можно также и невизуальные объекты .Net

 

Основы классов ABL

Язык имеет  большое количество конструкций для поддержки классов. Самая основная и первоочередная конструкция – оператор CLASS, который может использоваться для описания нового объектного типа в ABL. ABL также включает в себя встроенный набор классов для базовой функциональности. Классы, определяемые оператором CLASS содержат в своем описании состояние и поведение.

Описание классов в ABL поддерживает наследование свойств одного класса другим. Т.е. возможно описать новый класс-потомок, который наследует часть своего функционала от  класса-предка и имеет свой некоторый собственный функционал. Таким образом множество классов могут ссылаться на другие классы по определенной иерархии, определяемой наследуемым функционалом.

Класс может реализовывать интерфейс при помощи оператора INTERFACE. Реализация интерфейса заключается в том, что в описании класса данный интерфейс указывается как реализуемый, а в коде класса обязательно определяются все методы, которые описаны в интерфейсе, в полном соответствии с сигнатурами из описания этого интерфейса. То есть, если класс реализует интерфейс, для любого экземпляра этого класса существуют и могут быть вызваны все описанные в интерфейсе методы. Один класс может реализовать несколько интерфейсов одновременно. Интерфейсы могут наследоваться друг от друга.

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

Вдобавок к возможности описания своих собственных интерфейсов при помощи оператора INTERFACE язык ABL предоставляет встроенные интерфейсы для существующих служебных классов.

Замечание: В этом руководстве если не сказано иное термин наследование употребляется применительно к наследованию классов.

Таким образом, тип класс или тип интерфейс – это всего лишь тип данных, который можно объявить где угодно и их поведение аналогично встроенным типам языка, например – INTEGER. Поддержка классов и интерфейсов в OE подобна реализации классов и интерфейсов в Java или других ОО-языках.

Any given ABL object built from classes and interfaces can be seen as more than one type, depending on the hierarchy of classes and interfaces used to define the object. In other words, each class or interface type that you use to construct an object provides a different type through which you can access the object. Any consumer of the object only needs to access the object as a supported class or interface type in order to use the functionality supported by that type. Thus, depending on the type you use to access the object, the same object can provide different subsets of its total functionality.

Оператор CLASS или INTERFACE указывает, что далее идет описание класса или интерфейса, а не просто процедурный код ABL. Описание осуществляется при помощи нескольких специфических конструкций ABL, которые нельзя использовать в процедурном программировании.

Иначе говоря, существует четкое различие между классами и процедурами, компилятор определяет это различие по употреблению таких операторов как CLASS и INTERFACE. Но если вы не новичок в программировании на ABL, то вы скоро поймете, что практически все ваши знания пригодятся в ABL ООП.

Модели программирования в ABL

Как было рассказано в предыдущей главе ABL поддерживает два типа объектов – объекты, основанные на использовании процедур и объекты основанные на использовании классов. Несмотря на то, что  большая часть синтаксиса в программировании этих двух типов похожа каждый способ программирования разделяют  модели:

  • Процедурная модель разработки
  • Модель разработки на основе классов

Процедурная модель разработки

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

При использовании процедурных объектов состояние и поведение одного объекта по отношению к другому определено нестрого. Вы можете устанавливать любые отношения между объектами во время исполнения используя операторы ABL для доступа к объектам. Можно строить иерархические структуры, но они устанавливаются операторами во время исполнения программы. Как результат – на плечи разработчика ложатся контроль времени жизни объекта, контроль непротиворечивости,  консистентности объекта и задача учета связи объектов друг с другом.

Модель разработки на основе классов.

В этой модели вы разрабатываете и создаете объекты основанные на строго-типизированных классах. Так же, как и процедурные объекты, классы имеют run-time контекст, к которому могут получить доступ другие объекты. Этот контекст может включать разные типы данных (статические поля и свойства), но в отличие от процедур доступ к данным осуществляется через события или методы класса.

Метод – это процедура или функция, связанная с классом. Он определяет действия, которые можно выполнять над объектом такого типа, и которые сам объект может выполнять.

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

Для решения поставленной задачи создаются обработчики событий: как только программа попадает в заданное состояние, происходит событие, посылается сообщение, а обработчик перехватывает это сообщение. В общем случае в обработчик не передаётся ничего, либо передаётся ссылка на объект, инициировавший (породивший) обрабатываемое событие. В особых случаях в обработчик передаются значения некоторых переменных или ссылки на какие-то другие объекты, чтобы обработка данного события могла учесть контекст возникновения события.

Данные-члены класса (data member)  это переменные, буфера, временные таблицы  итд, которые определяются внутри класса таким же образом, как и методы.

Свойства объекта – это псевдополя, доступные для чтения и/или записи. Свойства внешне выглядят как поля и используются аналогично доступным полям (с некоторыми исключениями), однако фактически при обращении к ним происходит вызов методов доступа. Таким образом, свойства можно рассматривать как «умные» поля данных, сопровождающие доступ к внутренним данным объекта какими-либо дополнительными действиями.

Примечание: Методы классов не только во многом похожи на встроенные методы хэндл-объектов ABL, но еще и отличаются от них. Основное отличие в том, что методы класса могут определяться пользователем и они имеют строгий контроль типов.

Любой объект  в языке всегда имеет строго определённый тип, который фиксируется на момент компиляции программы.

Cтрогая типизация является непременным элементом обеспечения надёжности разрабатываемых программных средств. При правильном применении (подразумевающем, что в программе объявляются и используются отдельные типы данных для логически несовместимых значений) она защищает программиста от простых, но труднообнаруживаемых ошибок, связанных с совместным использованием логически несовместимых значений, возникающих иногда просто из-за элементарной опечатки. Так как вся информация об объекте доступна на стадии компиляции, то  ABL реализует стандартные функции создания и удаления объектов непротиворечивым и не подверженном ошибкам образом.

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

Вы не можете создать экземпляр абстрактного объекта.

Обратите внимание на то, что интерфейс (описан выше) может объявлять прототипы методов свойств и событий, которые должен реализовать класс. Различие интерфейсов и абстрактных классов состоит в том, что абстрактный класс может содержать некоторую реализацию, а интерфейс – нет.

Иными словами говоря, класс определяет сущность  — отвечает на вопрос «кто есть я», интерфейс определяет действие или набор действий выражаемых глаголами т.е. отвечает на вопрос «что я могу делать».

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

Сравнение моделей программирования

В целом, run-time принцип процедурного программирования может использовать больше возможностей для динамического программирования задачи, нежели при её же разработке с использованием классов. Использование классов, с другой стороны упрощают структуру программы, упрощает её поддержку и позволяет повторно использовать код объектов.

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

Много успешных приложений создавались и будут создаваться с использованием процедурной модели программирования и её псевдообъектного расширения – персистентных процедур и супер-процедур, которые позволяют строить в run-time цепочку наследования.

Progress Software рекомендует для новых разработок использовать ООП. Эта модель позволяет утверждать на стадии компиляции  что скомпилированный код сможет нормально запуститься. В отличие от этого все ветки процедурного кода возможно проверить только тестированием во время выполнения.

Конечно, существуют и обстоятельства, при которых использование процедурной модели является наилучшим выбором. В этом случае обычно используют супер-процедуры, которые объединяют процедуры в иерархию по правилам, которые можно задать логикой приложения в run-time. Аналогично динамический оператор RUN VALUE (procedure-variable) для процедур и DYNAMIC-FUNCTION для функций позволяет вызывать процедуры и функции определяемые во время run-time.

В этом руководстве будут часто сравниваться эти две модели программирования. Для упрощения термин class-based будет обозначать объекты и модель программирования, основанную на классах ABL. Термин procedure-based будет обозначать процедурную модель программирования. Кроме того, ниже вы увидите некоторое количество подразделов с одинаковым названием “Сравнение моделей программирования” – в них будет идти речь о реализации функционала при помощи class-based и procedure-based моделей.

2 комментария

  1. Дима! Класс! Эта тема сейчас очень актуальна. Спасибо! И ждем продолжения 😉

Leave a Reply

You must be logged in to post a comment.