Аспектно-ориентированное программирование обещает решить сквозные проблемы, но я еще не полностью продан. Были ли другие попытки решить эту проблему?
Аспектно-ориентированное программирование обещает решить сквозные проблемы, но я еще не полностью продан. Были ли другие попытки решить эту проблему?
Ответы:
Когда это возможно, вы можете инкапсулировать сквозные вопросы в отдельные модули, которые затем используются в приложении через внедрение зависимостей. Это позволяет несколько отделить реализацию сквозной задачи от ее использования во всем коде.
Это не всегда работает элегантно, хотя. Вот почему люди пытаются решить проблему с такими вещами, как АОП.
Два других варианта, которые я еще не видел, изучены:
Функциональное программирование с помощью монад и стрелок
В FP вы представляете сквозную задачу, как и все остальное: как нечто, переданное при вызове функции. Поскольку делать это явно утомительно, вы можете использовать монады (или, возможно, стрелки), чтобы скрыть дополнительную передаваемую информацию.
Наиболее распространенный пример АОП - ведение журнала. С Monads вы бы создали монаду "Logger", которая хранит список сообщений. Любые функции, которые вы выполняете через LoggerMonad, имеют возможность публиковать сообщения журнала. С помощью стрелок вы смоделируете весь поток данных приложения и в случае необходимости добавите подпрограмму регистрации в модель. Я думаю. Стрелки довольно сложные.
Entity / Компонентное программирование
Что-то, что я исследовал и экспериментировал для игрового движка. Вместо «объектов», как в ООП, вы разбиваете все на пакеты данных (компоненты) и сервисы, которые работают над типом компонента. Компоненты сгруппированы по общим идентификаторам, как в реляционной базе данных, а группы связанных компонентов являются сущностями. Чтобы добавить регистрацию в такой системе, вы должны добавить новую службу регистрации триггеров, основанную на том, какие компоненты передаются через нее.
Оба метода позволяют легко легко выполнять сквозные изменения, но оба являются высокоуровневыми архитектурными моделями. Таким образом, вы, вероятно, должны использовать их с самого начала. Модель компонентов теоретически может быть преобразована в существующую систему ООП. Я думаю, монады тоже могут быть, если ваш язык достаточно мощный.
Есть несколько способов решения проблем сквозного характера:
Используйте улучшенные шаблоны проектирования, идиомы или механизмы абстракции : код может быть перерезан, даже если он может быть модульным. Чтобы поддерживать код, вам необходимо провести рефакторинг, чтобы использовать технику проектирования, которая может его модульно модифицировать. Такой рефакторинг может привести к перекрестному разрезанию другого вида, но, надеюсь, что перекрестные переходы стабильны и вряд ли изменятся.
Разработка более богатых языковых возможностей . Многие проявления перекрестного подхода могут быть решены с помощью более совершенных механизмов абстракции, и иногда необходимы новые языковые возможности. Например, более продвинутые языки, которые включают функциональные и объектно-ориентированные функции, часто не используют столько шаблонов проектирования, потому что они не нужны. Обратите внимание, что сами шаблоны проектирования могут быть перекрестными по своей природе , потому что они описывают роли нескольких различных объектов и классов. В Java отражение часто может использоваться вместо аспекта, хотя и с более высокими затратами времени выполнения. Например, используя отражение, вы можете поддерживать шаблон посетителя для сотен классов с помощью всего лишь нескольких строк кода. DJ-библиотекаиз северо-востока это одно рефлексивное решение, которое делает именно это. Миксины - это мощный метод, доступный в C ++ (но не в Java), и может дать вам некоторые из тех же вариантов использования в качестве аспекта.
Обеспечьте лучшую поддержку инструментов : такие методы, как использование grep
и выполнение операций рефакторинга, могут иметь дело с проблемами, связанными с пересекающимся кодом. Например, имя метода, объявленного в интерфейсе, может быть использовано во всей программе. (Обратите внимание на техническое различие: это имя метода, а не его реализация, которое пересекает.) Обычно это не проблема в IDE, такой как Eclipse, где вы можете использовать «переименование рефакторинга», чтобы изменить все места в вашем коде, которые используют имя. Таким образом, возможно, вам не понадобятся языковые функции, когда среда программирования достаточно выразительна для вас.
Используйте доменные языки : ранние языки аспектов, которые были до AspectJ, были специфичными для домена и применялись только к определенным проблемам, таким как синхронизация потоков или анализ потока данных для эффективного объединения композиций функций. Эти языки были экспериментальными, но казались весьма успешными в модульных задачах, которые в противном случае были сквозными.
Используйте методы генеративного программирования . Переход на метауровень можно рассматривать как метод реализации аспектно-ориентированного программирования, но это достаточно большая область, в которой выходят за рамки простых аспектов. Методы генерации (когда программа генерирует исходный код для другой программы) также связаны с предметно-ориентированными языками.
Я считаю, что для всего этого целесообразно изучать АОП. АОП может помочь вам расширить ваши концепции кода, даже если вы не используете язык АОП.
В общем, тегирование элементов кода с декларативной функцией, но, в частности, система атрибутов в мире C # /. NET / Mono.
Я не специалист по AOP, но, читая об этом на протяжении многих лет, он всегда казался более слабой формой метапрограммирования, предлагаемой Lisp , особенно такими частями, как протокол метаобъектов.
Полагаю, это не должно вызывать удивления: Грегор Кичалес был одним из авторов AMOP, а позже написал AspectJ для Java!