Перспективы развития аспектно-ориентированного программирования



Содержание

 

Введение                                                                                                                                                                        3

Глава 1. Аспектно – ориентированное программирование                                                        4

 

1.1 Введение в АОП                                                                                                                              4

1.2 Основные концепции АОП                                                                                                  7

1.3 AspectJ как одна из реализаций АОП                                                                11

1.4 Другие реализации АОП                                                                                            21

 

Глава 2. Перспективы развития аспектно – ориентированного программирования                                                                                                                                       23

 

2.1 Преимущества и недостатки использования АОП                                                  23

2.2 Эволюция              развития АОП                                                                                                                  27

 

Заключение                                                                                                                                                    29

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

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Введение

 

Аспектно-ориентированное программирование (АОП) - это новая развивающаяся концепция, призванная сократить время, стоимость и сложность разработки программного обеспечения (ПО). Известно, что в жизненном цикле ПО 70% всего времени отводится на сопровождение и внесение изменений в готовый программный код. Кроме того, фактом является положение, утверждающее, что большинство необходимых программных продуктов уже реализовано, протестировано и внедрено. Таким образом, сопровождение приобретает первостепенную значимость, а это, в свою очередь, требует специальных подходов для обеспечения достаточно быстрой и всегда безболезненной модификации программы.

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

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

 

 

Глава 1. Аспектно – ориентированное программирование

 

1.1 Введение в АОП

 

Аспектно-ориентированное программирование (АОП) — парадигма программирования, основанная на идее разделения функциональности для улучшения разбиения программы на модули.

В основе подхода АОП лежит возможность структурного разбиения программы на составляющие модули, что, позволяет разбить задачу на части с целью более рационального распределения времени и сил. В модуле, исходя из определенного мотива, собирается код из различных мест программы, затем он параметризуется с целью абстрагирования от конкретной задачи для перенесения полученных достижений и на другие проекты. В этом случае мы получаем в свое распоряжение не просто константные модули, призванные сливаться с имеющимся кодом, а реальные гибкие компоненты, способные формировать необходимые фрагменты кода и интеллектуально распадаться в зависимости от ситуации. При подключении модуля происходит его распад на множество фрагментов кода, которые инсталлируется в заранее утвержденные места программы. В докладе предлагаются новые методы подключения (отключения) модулей при работе с каркасом программы - ее базовой почти не изменяемой частью. Работа с фрагментами кода позволяет приблизиться к логике задачи: к существующим общесистемным требованиям и одновременно отдалиться от предлагаемых средой разработки способов декомпозиции. Таким образом, совокупность фрагментов текста программы - это элемент декомпозиции, такой же, как, например функция или класс.

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

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

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

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

Подход был реализован на примере модернизации HTML-страниц и предназначен для решения задачи построения сайта на основе компонентов - XML-спецификаций и XSLT-трансформаций. Эти компоненты легко подключаются к некоторой исходной HTML-странице. После написания достаточно большого количества таких заготовок и их объединения в хранилище модулей появляется возможность создавать необходимые страницы гораздо быстрее и качественнее, чем это было раньше. Все это будет достигаться за счет возможностей построенной модели и качественного создания модулей, в которых будут предусматриваться необходимые параметры. Получив доступ к таким хранилищам, пользователь сможет повысить производительность своего труда путем несложного задания тегов XML-документа. Система может найти свое применение в различных областях, где запросы на качество и функциональность высоки, а количество времени ограничено.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

1.2 Основные концепции АОП

 

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

АОП позволяет реализовывать отдельные концепции в слабосвязанном виде, и, комбинируя такие реализации, формирует конечную систему. АОП позволяет построить систему, используя слабосвязанные, разбитые на отдельные модули (аспекты) реализации общесистемных требований.

Разработка в рамках АОП состоит из трех отдельных шагов:

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

      Реализация функциональности: Реализовать каждое требование отдельно. В примере с кредитными картами необходимо отдельно реализовать модули обработки кредитных карт, журнала и аутентификации.

      Компоновка аспектов: На этом шаге аспектный интегратор определяет правила для создания своих модулей — аспектов, составляя конечную систему. В примере с кредитными картами необходимо определить в терминах языка, реализующего АОП, при вызове каких операций необходимо вносить запись в журнал, и по завершению каких действий необходимо сообщать об успехе/неуспехе операции. Также можно определить правила, по которым будет вызываться модуль аутентификации перед доступом к бизнес-логике обработки кредитных карт.

 

 

Рисунок 1. Фазы аспектно-ориентированной разработки ПО

 

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

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

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

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

1.3 AspectJ как одна из реализаций АОП

 

АОП можно поддерживать в рамках уже существующих языков. Так, в частности, исследовательский центр Xerox PARC разработал систему AspectJ, поддерживающую АОП в рамках языка Java. Этот пакет встраивается в такие системы разработки, как Eclipse, Sun ONE Studio, Forte 4J и Borland JBuilder. Рассмотрим AspectJ из-за того, что эта реализация АОП обладает наиболее широкими возможностями.

AspectJ — это простое и практическое расширение языка Java, которое добавляет к Java возможности, предоставляемые АОП. Пакет AspectJ состоит из компилятора (ajc), отладчика (ajdb), и генератора документации (ajdoc). Поскольку AspectJ является расширением Java, то любая программа, написанная на Java, будет правильной с точки зрения семантики AspectJ. Компилятор AspectJ выдает байт-код, совместимый с виртуальной машиной Java. Поскольку в качестве базового языка для AspectJ был выбран язык Java, то он унаследовал от Java все преимущества, и спроектирован таким образом, что будет легко понятен Java-разработчикам. Добавленные расширения касаются в основном способов задания правил интеграции аспектов и java-объектов. Данные правила выражаются в ключевых понятиях AspectJ:

 

      JoinPoint — строго определенная точка выполнения программы, ассоциированная с контекстом выполнения (вызов метода, конструктора, доступ к полю класса, обработчик исключения, и т.д.).

      Pointcut — набор (срез) точек JoinPoint удовлетворяющих заданному условию.

      Advice — набор инструкций языка java, выполняемых до, после или вместо каждой из точек выполнения (JoinPoint), входящих в заданный срез (Pointcut).

      Aspect — основная единица модульности AspectJ. В аспектах задаются срезы точек выполнения (Pointcut) и инструкции, которые выполняются в точках выполнения (Advice).

      Introduction — способность аспекта изменять структуру Java-класса путем добавления новых полей и методов, так и иерархию класса.

 

Pointcut и Advice определяют правила интеграции. Аспект — единица, напоминающая класс в ООП, она соединяет элементы pointcut и элементы advice вместе, и формирует модуль на срезе системы.

Рассмотрим пример, демонстрирующий, как язык AspectJ реализует принципы АОП. В качестве примера возьмем модель простого графического редактора. Этот редактор может работать с двумя типами графических элементов — точкой и линией. Диаграмма классов редактора представлена на рисунке 2. Классы Point и Line реализуют интерфейс FigureElement, содержащий метод перемещения фигуры. Операциями, влияющими на обновление экрана, являются операции перемещения фигур. После перемещения фигуры необходимо обновить изображение (Display). Обновление изображения в данном случае является сквозной функциональностью, которая должна вызываться при некоторых условиях (изменении положения фигур).

 

Рисунок 2. Модель графического редактора.

 

Класс Line содержит в себе 2 экземпляра класса Point. Классы, реализующие точку и линию, могут быть представлены в следующем виде:

 

class Line implements FigureElement

{

  private Point p1, p2;

  Point getP1() { return p1; }

  Point getP2() { return p2; }

  void setP1(Point p1) { this.p1 = p1; }

  void setP2(Point p2) { this.p2 = p2; }

  void moveBy(int dx, int dy) { ... }

}

 

class Point implements FigureElement

{

  private int x = 0, y = 0;

  int getX() { return x; }

  int getY() { return y; }

  void setX(int x) { this.x = x; }

  void setY(int y) { this.y = y; }

  void moveBy(int dx, int dy) { ... }

}

 

Предположим, пользователь переместил фигуру на 2 пункта, при этом отработал метод lineInst.moveBy(2,2). На схеме вызываемых функций можно увидеть, как работает этот метод. В теле вызываемого метода moveBy() содержится логика перемещения фигуры; метод имеет входные параметры, возвращаемое значение и набор инструкций языка, среди которых находится вызов аналогичного метода у двух точек — элементов класса Line. Метод moveBy() класса Point также имеет входные параметры, возвращаемое значение и набор инструкций языка. Каждая строго определенная точка выполнения программы, ассоциированная с контекстом выполнения, с учетом ограничений языка AspectJ является JoinPoint-ом. Выполнение метода moveBy() класса Line, вызов метода moveBy у Point — являются точками JoinPoint.

 

 

Рисунок 3. Схема вызываемых функций.

 

Здесь необходимо ввести различия между точками выполнения программы в рамках AspectJ. Точки выполнения бывают двух типов — точка выполнения метода, которая представляет собой выполнение всего тела метода, и точка вызова метода, которая представляет собой точку непосредственного вызова метода. Другими словами, тело метода может быть представлено точкой со стороны клиента либо только вызов метода может быть представлен как точка.

Язык AspectJ позволяет описывать несколько типов подобных точек выполнения программы:

      Вызов методов и конструкторов.

      Выполнение методов и конструкторов.

      Доступ к полям класса.

      Обработка исключительных ситуаций.

      Статическая и динамическая инициализация классов.

При вызове клиентом метода moveBy все точки выполнения (joinPoint) находятся внутри потока управления, начиная с точки, удовлетворяющей условию. Средствами языка AspectJ можно влиять на поток управления, описав соответствующий поток управления как набор точек pointcut.

Конструкцией языка, позволяющей описывать набор точек JoinPoint, удовлетворяющих заданному условию, является pointcut. Например, call(void Line.setP1(Point)) соответствует каждой точке выполнения программы, если она является вызовом метода с сигнатурой "void Line.setP1(Point)". При конструировании подобных срезов можно использовать логические операции &&, || и !, что дает большую гибкость при описании наборов точек выполнения программы. Срезы точек могут иметь имя, что позволяет их повторно использовать при конструировании других срезов и описании набора инструкций Advice.

 

 

Рисунок 4. Поток выполнения метода moveBy.

 

Advice — набор инструкций языка java, выполняемых до, после или вместо каждой из точек выполнения, входящих в заданный срез. Язык AspectJ позволяет описывать подобные инструкции по следующим правилам:

      before. Набор инструкций выполняется перед выполнением инструкций, входящих в описываемую точку выполнения.

      afterreturning. Набор инструкций выполняется после возвращения значения из описываемой точки выполнения.

      afterthrowing. Набор инструкций выполняется после возникновения исключительной ситуации в описываемой точке выполнения.

      after. Набор инструкций выполняется после возвращения из описываемой точки выполнения в любом случае.

      around. Набор инструкций выполняется вместо описываемой точки выполнения.

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

Аспект — единица модульности AspectJ. В аспектах задаются срезы точек выполнения и инструкции, которые выполняются в точках выполнения. Аспект имеет сходство с классом — аспект может содержать методы и поля, расширять другие классы или аспекты, или реализовывать интерфейсы.

Далее представлено два варианта кода рассматриваемого графического редактора — с использованием языка AspectJ и без него. В варианте без использования AspectJ видно, что при изменении координат фигур в методы, отвечающие за эту функциональность, встроен код, реализующий обновление дисплея. В примере с использованием аспектного подхода классы содержат код, отвечающий только за свою логику. Набор инструкций, реализующий сквозную функциональность "обновление дисплея", находится в аспектном модуле — aspect DisplayUpdating. На этом примере наглядно показано основное преимущество аспектного подхода — локализация сквозной функциональности в отдельных модулях и встраивание подобной функциональности в требуемые участки системы.

Пример кода графического редактора без использования языка AspectJ:

class Line implements FigureElement

{

  private Point p1, p2;

  Point getP1() { return p1; }

  Point getP2() { return p2; }

  void setP1(Point p1)

  {

    this.p1 = p1;

    Display.update(this);

  }

  void setP2(Point p2)

  {

    this.p2 = p2;

    Display.update(this);

  }

}

 

class Point implements FigureElement

{

  private int x = 0, y = 0;

  int getX() { return x; }

  int getY() { return y; }

  void setX(int x)

  { 

    this.x = x;

    Display.update(this);

  }

  void setY(int y)

  { 

  this.y = y;

  Display.update(this);

  }

}

 

Пример кода графического редактора с использованием языка

AspectJ:

class Line implements FigureElement

{

  private Point p1, p2;

  Point getP1() { return p1; }

  Point getP2() { return p2; }

  void setP1(Point p1)

  {

    this.p1 = p1;

  }

  void setP2(Point p2)

  {

    this.p2 = p2;

  }

}

class Point implements FigureElement

{

  private int x = 0, y = 0;

  int getX() { return x; }

  int getY() { return y; }

  void setX(int x) {this.x = x; }

  void setY(int y) {this.y = y; }

}

aspect DisplayUpdating

{

  pointcut move(FigureElement figElt):

    target(figElt) &&

    (call(void FigureElement.moveBy(int, int) ||

    call(void Line.setP1(Point))       ||

    call(void Line.setP2(Point))       ||

    call(void Point.setX(int))        ||

    call(void Point.setY(int)));

  after(FigureElement fe) returning: move(fe)

  {

  Display.update(fe);

  }

}

 

 

Рисунок 5. Аспект DisplayUpdating на срезе системы.

 

При разработке программных систем с использованием средств языка AspectJ можно следовать трем принципам разработки аспектного подхода: выделять в отдельные модули сквозную функциональность — провести аспектную декомпозицию; реализовать каждое требование отдельно; интегрировать аспекты в программный код. В примере с графическим редактором на этапе аспектной декомпозиции была выявлена сквозная функциональность — обновление дисплея. Данное требование было реализовано в аспектном модуле DisplayUpdating. В этом аспекте определяется срез точек move(..), которые включают в себя точки выполнения программы, после которых будет встроена требуемая сквозная функциональность. На рисунке 5 схематично изображен аспект, находящийся на срезе модели графического редактора.

Интеграция аспектов (weaving) происходит в момент компиляции. Модель построения готовой программной системы при использовании компилятора ajc изображена на рисунке 6.

 

Рисунок 6. Интеграция аспектов.

 

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

 

 

 

 

 

 

 

 

 

 

1.4 Другие релизации АОП

 

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

      ANGIE Generation Now! Предоставляет новый структурированный язык для реализации различных генераторов, в том числе интеграторов аспектов.

      AspectC++. Аспектно-ориентированное расширение языка С++.

      AspectR. Система аспектно-ориентированного программирования на основе языка Ruby, которая позволяет в классах оборачивать код вокруг существующих методов.

      AspectS. Это один из первых прототипов, который дает возможность аспектно-ориентированного программирования в среде Squeak/Smalltalk.

      Apostle – система, близкая к AspectJ, АОП-расширение языка Smalltalk.

      AspectC. Простое АОП-расширение языка С, похожее на AspectJ.

      AspectC# реализация, добавляющая поддержку аспектов к языку C#.

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

      DemeterJ и DJ. Делаются шаги в сторону структурной инкапсуляции сквозной функциональности.

      Hyper/J. Предоставляет поддержку "многомерного" разделения и интеграции концепций для стандартной Java-платформы.

      JAC. Представляет собой основу, написанную на языке Java, для создания распределенных аспектно-ориентированных программных систем.

      JMangler. Представляет собой каркас на языке Java для преобразования программ на этапе загрузки, с поддержкой бесконфликтной композиции из независимо друг от друга разработанных аспектов (реализуемых в виде преобразующих компонентов системы JMangler). Также есть возможность интеграции аспектов в базовые классы Java.

      MixJuice – расширение языка Java, базирующееся на механизме поиска различий в модулях.

      MozartProgramming System – платформа для разработки "разумных и интеллектуальных" распределенных приложений.

      PROSE — аспектно-ориентированная платформа, базирующаяся на виртуальной машине Java, и позволяющая динамическое встраивание и вычленение аспектного кода.

      Pythius – проект с открытым исходным кодом, добавляющий принципы АОП к языку Python.

      SmartTools — аспектно-ориентированный генератор семантических каркасов (XML).

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

      Weave.NET – проект, направленный на исследование механизма поддержки АОП без привязки к конкретному языку программирования внутри компонентной модели .NET Framework.

 

 

 

 

 

 

 

 

 

 

Глава 2. Перспективы развития аспектно – ориентированного программирования

 

2.1 Преимущества и недостатки использования АОП

 

Перспективы развития аспектно-ориентированного программирования