Что такое «декораторы» и как они используются?

148

Мне интересно, какие именно декораторы есть в AngularJS. В Интернете не так много информации для декораторов, за исключением рекламы в документации AngularJS и краткого (хотя и интересного) упоминания в видео на YouTube .

Как говорят ребята из Angular, декоратор это:

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

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

Я все еще своего рода AngularJS noob, так что я уверен, что это просто невежество и / или вредные привычки, которые я подхватил.

Кевин Бил
источник

Ответы:

219

Хорошим примером использования является случай, $provide.decoratorкогда вам нужно выполнить незначительную «настройку» какой-либо сторонней / восходящей службы, от которой зависит ваш модуль, при этом оставив службу без изменений (поскольку вы не являетесь владельцем / сопровождающим службы). Вот демонстрация на планкр.

tamakisquare
источник
6
Потрясающий пример. Мне действительно было интересно, как расширить функциональность сторонних модулей, не вмешиваясь в них
Артур Ковач
5
Действительно ли декораторы набирают типы всех экземпляров службы, или они ограничены только модулем, который их украшает? Другими словами, скажем, у меня есть модуль A, который украшает сервис из модуля B. У меня тогда есть модуль C, который зависит от модуля A и модуля B. Является ли сервис из модуля B оригинальной или оформленной версией?
Джон Жак
3
@JonJaques - это отличный вопрос. Я не сталкивался с такой ситуацией. Если бы я догадался, версия сервиса, которую видит модуль C, должна быть оформленной из модуля A, но я не могу сказать этого точно, пока не попробую сам. Почему бы вам не написать простой plunkr / jsffidle и не поэкспериментировать с этим. Было бы здорово, если бы вы могли поделиться с нами своими находками. Приветствия.
tamakisquare
6
@JonJaques - Не смог сдержать свое любопытство, поэтому я добавил несколько строк в свой исходный пример, чтобы найти ответ на свой вопрос, ссылку . Короче, предположение в моем предыдущем комментарии верно.
tamakisquare
17
Фабрики, Услуги и т. Д. Являются одиночными (как они предоставляются), поэтому когда-то украшенные, всегда украшенные.
FlavorScape
66

Декораторы позволяют нам выделять сквозные проблемы и позволяют сервисам сохранять принцип единой ответственности, не беспокоясь об «инфраструктурном» коде.

Практическое использование декораторов:

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

Во всех этих случаях мы ограничиваем код в сервисе своей основной ответственностью.

JBland
источник
10

decoratorможет перехватывать экземпляр службы, созданный factory, service, value, provider, и дает опции для изменения некоторых, instance(service)которые иначе не конфигурируются / с опциями.

Например, он также может предоставить макеты для тестирования $http.

Daiwei
источник
1
Стоит отметить, что вы также можете переопределить directiveопределения, представленные Беном Наделем
Дэвидом Саламоном
Вот ссылка в официальных документах Angular: https://docs.angularjs.org/guide/decorators
Дэвид Саламон,
3

Проще говоря, мы можем сказать, что это как метод расширения. Например У нас есть класс, и у него есть два метода, и во время выполнения мы хотим добавить в него больше методов, чем используем Decorator.

Мы не можем использовать $ provide.decorator с константами, потому что мы не можем изменить константы, для которых они имеют свойство только для чтения.

Gurupreet
источник
1

Вкратце декораторы можно описать следующим образом:

Функция декоратора перехватывает создание сервиса, позволяя ему переопределить или изменить поведение сервиса.

Он использует $provideсервис под углом и изменяет или заменяет реализацию другого сервиса

$provide.decorator('service to decorate',['$delegate', function($delegate) {
  // $delegate - The original service instance, 
  //             which can be replaced, monkey patched, 
  //             configured, decorated or delegated to. 
  //             ie here what is there in the 'service to decorate'

  //   This function will be invoked, 
  //   when the service needs to be provided 
  //   and should return the decorated service instance.
  return $delegate;
}]);

Пример:

$provide.decorator('$log', ['$delegate', function($delegate) {
  // This will change implementation of log.war to log.error
  $delegate.warn = $delegate.error; 
  return $delegate;
}]);

Приложения

В дополнение к ответу @JBland.

  • Широкие языковые настройки приложения: -

    Вы можете найти пример здесь

  • Изменение поведения по умолчанию и существующей реализации сервиса с помощью углового сервиса: -

    Вы можете найти образец здесь

  • Переключение поведения функции в разных средах.

samuelj90
источник