Pull to refresh
52
0
Лисаченко Александр @NightTiger

Пользователь

Send message
Это уже задача разработчиков IDE — научиться понимать такие конструкции нормально. Потому что мы код документируем корректно.
Хотя у меня, вроде, и так все хорошо (phpStorm 127.100): построил сейчас цепочку из 10 методов с конструкцией @return self — все подхватывает правильно.
Спасибо за уточнение, внес его в статью.
Насчет анализа возвращаемого значения — это делать необходимо, иначе можно случайно сломать существующий метод, который возвращает другое значение (например, экземпляр другого класса). Без проверки результата совет подменит результат и вернет его вместо оригинального без зазрения совести )
Спасибо за ваш комментарий, очень правильные замечания.
1. На текущий момент автокомплит для таких методов работать точно не будет, что очень неудобно. Но ваш комментарий подтолкнул меня к идее и я только что нашел способ обойти и эту проблему: надо позволить аспектам работать и с док-блоками. В этом случае в phpDoc-блоках можно будет с помощью совета добавить return self и в этом случае phpStorm радостно включает автокомплит на основе полученного класса в кэше.
2. Если у вас есть инструмент кодогенерации для Doctrine — это хорошо, но вот нет у меня уверенности, что весь vendor-код оборудован такими полезными утилитами. Да и ваш пулл-реквест в ядро большого фреймворка с проставленными сеттерами могут и не взять. А вот АОП это легко сделает, потому что это одна из полезных особенностей АОП — возможность дотягиваться до любого кода, внося в него свои правки на уровне приложения.
Да, как вы уже поняли, это синтаксис, описывающий точки во всем коде, аналог SQL для данных. Синтаксис пришел из аннотаций Spring и AspectJ, поэтому с ними лучше ознакомиться отдельно. Если есть интерес — могу в отдельной статье рассмотреть этот синтаксис и как он применяется относительно к PHP. Хотя сейчас Go! поддерживает довольно небольшое количество срезов из того, что предлагает AspectJ.
Я предлагаю это сделать только для публичных сеттеров, оверхед при их использовании будет настолько мал, что вы даже его не увидите на общем фоне приложения. Вряд ли у вас в коде сеттеры вызываются несколько тысяч раз за запрос, ведь так?
Тоже долго думал над тем, как лучше перевести на русский язык этот шаблон, но так и не нашел корректного перевода, поэтому остановился на «текучем», хоть это название меня и раздражает. Я бы его переименовал в ChainInterface и тогда бы он прекрасно сочетался с MethodChaining и переводился бы просто «цепочечным интерфейсом».
Приходится отдавать дань дядюшке Фаулеру )
Эта статья как раз один из примеров управляемого «АОП»: вы в любой момент можете посмотреть на класс и понять, что он использует реализацию FluentInterface-а. А потом можно зайти в сам интерфейс FluentInterface, нажать «иерархия» и получить отчет о всех классах, которые его реализуют.
Только вчера был там у этого потрясающего сооружения. Когда стоишь рядом — ощущаешь всю палитру эмоций: восторг, страх, восхищение, радость, удивление, боязнь… Колоссальное архитектурное творение просто бросает всем вызов своим могуществом.
Как это все было просчитано — для меня останется загадкой.
Вижу, вы уловили и понимаете суть вещей в АОП. Это хорошо! Потому что пример в статье действительно не является рекомендацией делать так, как там описано. Пример был выбран специально для упрощения понимания того, как и что происходит в аспектной парадигме, как это описывается и что получается. Уровень — начальный, ознакомительный.
В реальной же жизни — все проще и банальнее, выносим в аспекты только то, что мусорит в коде — логирование, кэширование, авторизацию. Для этих вещей лучше ничего не придумаешь.
Если пойти еще дальше, то на верхнем уровне будут такие вещи как Autowire, когда все классы сами укладываются при статической инициализации в контейнер и инжектятся в виде сервисов в другие сервисы (пример Google.Guice), реализация паттернов в АОП (те же события можно генерировать в заданной точке и обрабатывать в традиционном понимании с помощью диспетчеров) и много-много всего интересного.
Тут как говорится: «терпение и труд — все перетрут» ) Спасибо за оценку, это меня очень вдохновляет.
Как раз в текущую минуту рождается еще одна часть, которая очень нужна, но которую непросто сделать — лексер и грамматика для срезов. Это позволит разбирать любые правильные конструкции в деревья и проверять их, подсказывая пользователю ошибки в синтаксисе при разборе, а также позволит использовать логические объединения срезов с помощью AND, OR, NOT.
Еще нащупал почву, как делать runtimе-проверки (сейчас только статические на этапе вплетения аспектов). Это позволит определять замыкание, которое будет само принимать решение, выполнять совет или нет в зависимости от свойств объекта, или переданных ему параметров.
Да, можно, заранее делая программу сложнее, потому что вам придется рефакторить ваш код, добавляя логику обработки события. Более того, события будут работать медленней АОП )
В прошлой своей статье я как раз приводил сравнение с событиями, почитайте на хабре.
Отличный аргумент, однозначно в список собственных рекомендаций!
Отличное завершение этой ветки ) Очень приятно видеть, что моя работа может пригодиться в реальных проектах. Если будут вопросы — связывайтесь со мной, с удовольствием помогу.
Очень интересно было бы получить фидбек, если вы будете это использовать. Пока у меня несколько положительных отзывов о реальном использовании: в одном случае добавлено кэширование в проекте с упрощением кода сервисов, в другом — сделано логирование всех действий в админке Symfony2 на базе SonataAdmin.
Аспект позволяет сейчас изменить только те значения, которые были переданы по ссылке. Но можно добавить и возможность менять все аргументы, это дело одного сеттера ) Но нужно ли это сейчас? Думаю, что пока рано. А вот результат вызова метода изменять можно, так работает самый мощный тип совета — Around, с помощью которого делается кэширование и многое другое. Если советов несколько, они будут применяться в определенном порядке.
И да, советы имеют сортировку, которой можно управлять, в документации есть пример.
Может, есть у кого идеи, как это сделать понятно? Что мне нужно дать разработчику, чтобы он знал о содержимом? В принципе, при отладке доступны объекты точки доступа, в них видны сами советы.
Не совсем согласен. Часто ли вы отлаживаете код кэширования внутри метода, или логирования? Как правило, отладка начинается с установки точки останова внутри метода, отсеивая вызовы кэширования, логирования и прочие как ненужные. Когда отлаживается код — отлаживается работа конкретного метода, а потом уже всей системы в целом. Читать код с аспектами значительно проще, потому что весь мусор из методов и классов вычищается в отдельный класс-аспект и применяется по всему коду. Достаточно знать, как вплетаются аспекты в конечный код, после этого наступает озарение и понимание сути всех вещей.
Но без озарения для новичков это будет довольно весело и интересно ) Сумерки. Кодинг. Рассвет.
Я такие штуки нахожу постоянно в любом коде, включая и свой. Хороший показатель — не больше пары WTF/10000 строк кода.
Ах, вы про это. Да, здесь помощи от IDE не получишь, как и в регулярных выражениях. А срез, по-сути, это и есть регулярное выражение для кода. Но внутри можно спокойно задавать срезы ручками с помощью кода, связывая с замыканиями в нужных точках. Это для advanced-пользователей. Позже будет конфиг аспектов в виде xml с валидной схемой, а также yml.

Information

Rating
Does not participate
Location
Москва, Москва и Московская обл., Россия
Date of birth
Registered
Activity