“Dekoratörler” nedir ve nasıl kullanılır?


148

AngularJS'de dekoratörlerin tam olarak ne olduğunu merak ediyorum. Dekoratörler için AngularJS belgelerinde bir bulanıklık ve bir youtube videosunda kısa (ilginç de olsa) bir söz için tasarruf için çevrimiçi çok fazla bilgi yok .

Açısal adamların dediği gibi bir dekoratör:

Hizmetin dekorasyonu, dekoratörün hizmet örneği oluşturulmasını durdurmasına izin verir. Döndürülen örnek, orijinal örnek veya orijinal örneğe yetki veren yeni bir örnek olabilir.

Gerçekten ne anlama bilmiyorum araçları , ve emin hizmete kendisinden bu mantığı ayırmak neden değilim. Örneğin, farklı koşullar altında farklı bir şey döndürmek istersem, ilgili işlevlere farklı argümanlar iletirim veya o özel durumu paylaşan başka bir işlev kullanırdım.

Hala bir AngularJS çaylakıyım, bu yüzden aldım sadece cehalet ve / veya kötü alışkanlıklar.

Yanıtlar:


219

İyi bir kullanım durumu, $provide.decoratormodülün bağlı olduğu bazı üçüncü taraf / yukarı akış hizmetlerinde küçük bir değişiklik yapmanız gerektiğinde, hizmetin bozulmadan kalmasıdır (çünkü hizmetin sahibi / bakımcısı değilseniz). İşte plunkr hakkında bir gösteri.


6
Harika bir örnek. Aslında üçüncü taraf modüllerin işlevselliğini onlarla karşılaşmadan nasıl genişleteceğimizi merak ediyordum
Arthur Kovacs

5
Dekoratörler aslında bir hizmetin tüm örneklerini kullanıyor mu yoksa yalnızca onları süsleyen modüle mi dahil ediliyorlar? Başka bir deyişle, modül B'den bir hizmet süsleyen modül A'ya sahip olduğumu varsayalım. Sonra modül A ve modül B'ye bağlı modül C var. Modül C'nin içinde, modül B'den gelen hizmet orijinal mi yoksa süslü versiyon mu?
Jon Jaques

3
@JonJaques - Bu harika bir soru. Ben böyle bir durumla karşılaşmadım. Tahmin edersem, modül C'nin gördüğü hizmetin versiyonu modül A'dan dekore edilmiş olmalı ama kendim denemeden bunu kesin olarak söyleyemem. Neden basit bir plunkr / jsffidle yazıp bunu denemiyorsunuz. Bulgunuzu bizimle paylaşmanız harika olurdu. Şerefe.
tamakisquare

6
@JonJaques - Merakımı tutamadı, bu yüzden sorunuzun cevabını bulmak için orijinal örneğime birkaç satır ekledim, bağlantı . Kısacası, önceki yorumumdaki tahmin doğru.
tamakisquare

17
Fabrikalar, Hizmetler vb. (Sağlandıkları gibi) singletonlardır, bu yüzden bir kez dekore edilmiş, her zaman dekore edilmiştir.
FlavorScape

66

Dekoratörler, kesişen endişeleri ayırmamıza ve hizmetlerin "altyapı" kodu hakkında endişelenmeden tek sorumluluk ilkesini korumasına izin veriyor.

Dekoratörlerin pratik kullanımları:

  • Önbellekleme: Potansiyel olarak pahalı HTTP çağrıları yapan bir hizmetimiz varsa, hizmeti harici çağrı yapmadan önce yerel depolamayı kontrol eden bir önbellek dekoratörüne sarabiliriz.
  • Hata Ayıklama / İzleme: geliştirme / üretim yapılandırmanıza bağlı olarak, hizmetlerinizi hata ayıklama veya izleme sarmalayıcılarıyla süsleyen bir anahtar bulundurun.
  • Kısma: sık tetiklenen çağrıları bir açıcı sarma paketine sarın. Örneğin, hız sınırlı hizmetlerle kolayca etkileşim kurmamızı sağlar.

Tüm bu durumlarda, hizmetteki kodu ana sorumluluğu ile sınırlandırıyoruz.



3

Basit bir deyişle, bunun bir uzantı yöntemi gibi olduğunu söyleyebiliriz. Örn. Bir sınıfımız var ve iki yöntemi var ve çalışma zamanında daha fazla yöntem eklemek istiyoruz, o zaman Dekoratör kullanıyoruz.

$ Offer.decorator öğesini sabitlerle kullanamayız, çünkü salt okunur özelliği kullandıkları sabitleri değiştiremeyiz.


1

Kısacası dekoratörler aşağıdaki gibi tanımlanabilir: -

Dekoratör işlevi, hizmetin oluşturulmasını engeller ve hizmetin davranışını geçersiz kılmasına veya değiştirmesine izin verir.

$provideHizmeti açısal olarak kullanır ve başka bir hizmetin uygulanmasını değiştirir veya değiştirir

$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;
}]);

Misal:

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

Uygulamalar

@JBland yanıtı yanı sıra.

  • Uygulama çapında yerel ayarlar: -

    Burada bir örnek bulabilirsiniz

  • Bir hizmetin varsayılan davranışını ve var olan hizmetini açısal hizmetle değiştirme: -

    Burada bir karınca bulabilirsin

  • Bir fonksiyonun farklı ortamlarda anahtarlama davranışı.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.