Search
Write a publication
Pull to refresh

Comments 40

имхо, АОП это одна из самых мутных, неинтуитивных да и просто пугающих своей нелинейностью фич современных ЯП. Даже ФП не требует такого выворота мозгов.
АОП сильно помогает в реализации сквозного функционала и позволяет избавиться от кучи лишнего кода. Самый яркий пример — кеширование.
А как еще вы предлагаете просто и понятно реализовывать общие для всей системы (или ее частей) функции, расположенные, грубо говоря, перпендикулярно бизнес-процессу? Авторизацию, логирование, кэширование? Униформную валидацию? Контракты кода?
Как-то обходился до сих пор… Можете порекомендовать доступное изложение идеи?
Гм, то есть вы критикуете «фичу», про которую даже не читали еще?

Порекомендовать не могу, могу сам изложить. Вот у вас есть какой-то cross-cutting aspect, например, безопасность, и требование сводится к тому, что каждый entry point в системе (например, контроллер в MVC) должен проверять подлинность пользователя. Вы, конечно, можете все эти точки найти руками и проставить там вызовы IsAuthenticated. Но согласитесь, что это, скажем так, неэффективно?

А можно взять (какую-нибудь) систему для построения этих самых животных, и сказать в ней: «найди все entry points в системе и оберни их вызовы в проверку подлинности». Разница в эффективности гигантская.
Не то чтобы я критикую. Я скорее поделился своей фрустрацией по поводу данной технологии и знаю, что я по меньшей мере не одинок в этом.

Вещь вне всякого сомнения полезная. Меня смущает именно нелинейность.

Когда я учился программировать на бейсике и паскале, мир был прост и прекрасен. Затем, с переходом на C++, он стал сложнее, но пожалуй ещё прекраснее — теперь можно было играться с объектной моделью до бесконечности, оттачивая её адекватность задаче. Следующим серьёзным вызовом явился XSLT, который выворачивал мозги наизнанку и это тоже было интересно.

Теперь аспекты, которые вызывают непонятно что непонятно когда. Я просто чувствую, что моим способностям понимать код приходит конец. А может быть просто текст как способ изложения программы уже подошёл к границе своих возможностей в силу своей строгой линейности.
«Я скорее поделился своей фрустрацией по поводу данной технологии и знаю, что я по меньшей мере не одинок в этом.»
А что вас в ней фрустрирует.

«Меня смущает именно нелинейность. „
У вас задача “нелинейна». Неудивительно, что средства ее эффективного решения «нелинейны».

«А может быть просто текст как способ изложения программы уже подошёл к границе своих возможностей в силу своей строгой линейности. „
Это случилось тогда, когда бизнес-требования перестали помещаться в один связный текст без перекрестных ссылок.
Закончим, пожалуй, на этом. Больше мне сказать по теме нечего.
У меня, например, эта информация лежит в конфигах модуля. Вроде: для экшна view не нужны никакие права, а для экшна create — нужно быть аутентифицированным и состоять в группе редакторов. Сам код экшна при этом остается чистым и ничего не знает о политике, которую можно в любой момент поменять.
Это и есть аспекты, поздравляю вас. Реализованные через конфиги.
Мне подход конфигов больше нравится — при изменении политики безопаснос
ти, не нужно трогать код. Только поправить конфиг и сбросить кэш конфигов.
Это уже вопрос философский, и с АОП никак не связанный. Можно то же самое (с той же гибкостью) сделать, например, через DSL. А можно сделать вообще без аспектов, но на конфигах. Ну и так далее.

Вопрос исключительно в том, нужна вам такая гибкость (которая неизбежно делает систему более хрупкой), или нет.
Декораторы — это техническая реализация аспекта. Вопрос в том, как вы эти декораторы будете к соответствующим точкам системы привязывать.
Мягко говоря очень спорная реализация. Добавлять все функции в глобальную область видимости — это дорога на тёмную сторону силы. Ещё момент о котором многие забывают — в JS многие функции работают с асинхронным вводом/выводом и тайматуами. Такая модель становится практически бесполезна в асинхронной реализации, разве что before будет работать. Оператор try не поймает ошибку внутри, например, таймаута, а то что функция завершилась ещё не значит что результат готов, т.к. он возвращается в callback. Сделал вот такую обёртку (использую в node.js):

module.exports.wrap = function(that, target, aspect) {
	var params = Array.prototype.slice.call(arguments, 3);
	var wrapper = function() { aspect.apply(that, [target, arguments].concat(params)); }
	return wrapper;
};
.

Она покрывает практически все необходимые ситуации, с которыми приходилось сталкиваться.
Но для обертки функции придется писать wrap(that, target, aspect); где-нибудь в коде (впринципе можно сразу перед функцией написать). А за то, что это хорошее решение я и не борюсь, просто псевдо-декларативный синтаксис выглядит заманчиво, это и хотел показать
Да, писать нужно будет, перед функцией как раз нельзя, т.к. нужно её переопределить. А перед функцией ещё нечего переопределять. Выглядит это примерно так:

module.exports.findOneById = function(id, cb) {
	collection.findOne({_id: id}, cb) ;
};

module.exports.findOneById = aop.wrap(module.exports.findOneById, module.exports.findOneById, aspects.cache, 'message');


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

Без передачи дополнительной ссылки на this контекст он просто потеряется, что собственно и происходит в Вашей реализации.

По поводу того что не боретесь за хорошее решение, а тогда зачем вообще эта публикация? Я вижу код содержащий грубые ошибки. В таком виде он не применим в сколь-либо серьёзном проекте. А в мелких, где можно обойтись списком функций в глобальной области видимости — АОП не нужно совсем. Если знаете об этом — надо писать это жирным шрифтом в самом начале в духе «не повторять этого дома». Т.к. кто-то придёт из гугла и примет такое решение на веру.
Но ведь и статья не звучит как «АОП в JavaScript». Идея синтаксиса только важна, да и на крупном проекте тут применять нечего, изложена основания идея, не предложена никакая библиотека и тем более ссылок на сорсы.

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


поэтому и ошибки вы видите те, которые возникнут при применении на вашем проекте, а для моей задачи их не возникнет.


Ну и смысл от вашего коммента, если вы только, что признали безсмысленность вашего поста? Вообще, пошла такая тенденция — перенеси паттерн из другово языка и сделай вид, что знаешь JavaScript.
В чем действительно нет смысла, так это в развитии данной темы (бессмысленность поста искать в том что код не везде будет работать, я повторюсь — я не представлял здесь какой-то библиотеки, которую можно где-то юзать, я представлял здесь идею внесения нетипичного для js синтаксиса).
Прочитайте еще раз тему топика и проследите как развивалась мысль. Я не признавал бессмысленность, я признал, что не сохранял контекст, т.к. без него код выглядел нагляднее, не нужно подменять слова.
Может, человек не знает, что можно писать window[name] = arg?
Знает, просто изначально передавалось имя функции в дополнительном атрибуте, и объяление могло иметь вид, поэтому таким способом было проще(все объекты были доступны), но да… неправильно сделал

AOP(

	[FunctionName("Something.protype.method")],
	function something$method() {
		...
	}

);

Согласен с критикой…
По этому имени искать/создавать обеък- владельца метода было бы привильно. Спасибо
Кстати, имя функции Вы тоже очень странно получаете. У функции есть атрибут name который хранит имя.
Только в ие не работает. *Не избивайте, за то, что в ие проверил*
Возможно. Сталкивался с этим только в node.js. Т.к. очень специфичный механизм, его вообще не стоит использовать, т.к. у функции может и не быть имени. Причём его нет у большинства функций объявленных такими способами:

var fn1 = function(name) {
    return name;
};

var obj = {
    sum: function(a, b) {
        return a + b;
    }
};


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

А зачем, собственно проверять тип каждого аргумента? Разве не очевидно, что «атрибутами» будут все аргументы, кроме последнего?
В примере же даже написано несколько функций, помеченных атрибутам. Т.е. можно объявлять не одну функцию, так что может быть и в середине
А.
Вот это мне не кажется хорошей идеей, если честно.
Почему? Неужели неудобно объявлять получается?
Ну это вкусовщина, конечно, но мне кажется, что нехорошо абсолютно все объявления в одну кучу складывать. Труднее редактировать код, труднее его дебажить и т.п.
Но сам сахар мне нравится:)
Например в YUI 3 добавили элементы аспектного программирования, эту библиотеку разрабатывают не школьники, так что поверьте оно там не просто так оказалось, это для скептиков использования AOP. Вот пример из новой книги (только только вышла) «YUI 3 Cookbook».
В jQuery и dojo тоже есть АОП. Просто АОП нужно когда нужно, а когда не нужно… оно как бы и не нужно. как-то так (и не капитан вовсе). Знать все равно полезно, так хоть можно увидеть где применить можно
Бывает оно нужно, но ввиду не знания о его существовании придумывают горы кода и глупые велосипеды, хотя используя AOP все можно было сделать гораздо проще. Так что хотя бы иметь представление и понимать возможность AOP нужно, использовать или нет дело другое.
Не обязательно применимость видеть только по примерам, можно просто внимательнее посмотреть на свой проект, и поискать куда можно всунуть, но конечно не ради того чтобы просто всунуть :) Самые распространенные применения: логирование, кеширование, сикюрность, то есть как бы паутина поверх работающего кода, дополнительный слой. В целом любые однотипные действия которые часто происходят в системе и которые не слишком относятся к бизнес логике, и которые могут быть отключаемыми, можно сказать служебные/сервисные. Конечно можно и сильную логику завязывать на этом, но я бы не стал сильно увлекаться потому что работа с AOP не слишком прозрачна.
Sign up to leave a comment.

Articles