Дополнительная обработка компонента
Предположим, вы хотите сделать лошадку из желудей. Что для этого нужно? Для начала надо взять несколько желудей. Они будут немного отличаться друг от друга: тот, что покрупнее, пойдет на тело лошадки, тонкие желуди пойдут ноги, а вот этот смешной желудь в виде конуса будет мордой нашей лошадки. Конечно же, обмажем все пластилином, чтобы оно держалось вместе.
Вы смотрите на получившуюся лошадку и понимаете: что-то не то. Желуди-то все блестящие, полированные! А вы так мечтали о теплой и матовой лошадке. Что же делать? Есть решение: желуди нужно обработать напильником, чтобы придать им приятный матовый оттенок.
Конечно же вы можете добавить нужный код по приведению желудя к матовому цвету, например, в ПриСозданииОбъекта. Но желуди-то разные, копипастить код между разными компонентами... Как-то фу. Хорошо, что "ОСень" может нам помочь.
Для дополнительной обработки объекта помимо "желудей" и "дубов" можно использовать &Напильник. Это специальный объект с методом ОбработатьЖелудь, который будет вызываться при каждом создании нового желудя.
Функция ОбработатьЖелудь(Желудь, ОпределениеЖелудя) Экспорт
ВжухнутьРазочек(Желудь);
Возврат Желудь;
КонецФункции
&Напильник
&Порядок(10)
Процедура ПриСозданииОбъекта()
КонецПроцедурыМетод обработки напильником возвращает желудь, причем не обязательно возвращать тот же самый желудь. Вам может захотеться обернуть его в объект-контейнер и накинуть на него несколько новых методов, например, с помощью decorator.
Не каждый напильник стоит применять ко всем желудям. Вспоминая замечательный пример с панками, мы можем захотеть добавить напильник для полировки заклепок на напульсниках наших музыкантов. При этом очевидно, что далеко не все носят напульсники, да еще и с заклепками. В задаче ограничения применения напильника поможет повторяемый параметр аннотации &Напильник под названием ПрименяетсяТолькоНа. В нем можно указать имена или прозвища желудей, к которым применяется данный напильник.
&Напильник(ПрименяетсяТолькоНа = "Панк")
Процедура ПриСозданииОбъекта()
КонецПроцедурыС другой стороны сам желудь может захотеть ограничить список напильников, которые могут по нему вжухнуть. Или даже вовсе отключить вжухание всех напильников. Для этого на желудь можно навесить аннотацию &ОсобоеОбращение, которая может принимать булев параметр ОтключитьВсеНапильники, повторяемый строковый параметр ПрименятьТолькоНапильник и опять же повторяемый строковый параметр НеПрименятьНапильник. Назначение первого параметра, надеемся, достаточно очевидно, поэтому вот пример работы с одним из других:
&Желудь
&ОсобоеОбращение(
ПрименятьТолькоНапильник = "ПолировщикЗаклепок"
)
Процедура ПриСозданииОбъекта()
КонецПроцедурыЗачем все это может быть нужно? Перфоманса ради, например. В случае большого количества компанейских желудей, которые не нуждаются в обработке напильником, можно отключить работу всех напильников для них. Ведь зачем тратить время на обработку, если она не нужна? При этом можно сохранить все плюшки от внедрения зависимостей и деталек через конструктор. Удобненько.
Напильник в этой удивительной осенней вселенной тоже является желудем, поэтому может иметь зависимости от других желудей. Но тут надо аккуратно - можно окончательно упороться и улететь таки на дно циклических зависимостей.
Чтобы уберечь себя ото дна, все напильники инициализируются перед запуском приложения. Как в жизни - сначала разложил рядом инструменты, а потом начинаешь творить.
"ОСень" в своем составе уже содержит два напильника: один отвечает за внедрение желудей в поля и методы установки значений, а второй - за вызовы методов &ФинальныйШтрих.
Любой порядок стремится к хаосу, а несколько напильников - к порядку. Чтобы не запутаться, кто в какой последовательности вжухает по желудю каждому Напильнику в аннотации &Порядок можно/нужно задать порядок исполнения. Напильник внедрения зависимостей имеет порядок 0, а напильник "Финального штриха" - 999999. Вы вольны занять любое значение порядка между этими границами.
