Eklentiler ne kullanmalı: kancalar, olaylar ya da başka bir şey?


24

Eklentilerin program akışına tepki vermesini sağlayan bir uygulama düşünün.

Bunu başarmanın 2 yolunu biliyorum: kancalar ve olaylar

1. Kancalar

Ana program akışı içindeki işlevleri boşaltmak için çağrıları kullanın. Bu fonksiyonlar eklentiler tarafından geçersiz kılınabilir.

Örneğin, Drupal CMS, modüller ve temalar için mevcut olan kancaları uygular. Hook'un bir file_copy işlevinde nasıl uygulandığına bir örnek .

function file_copy(stdClass $source, $destination = NULL, $replace = FILE_EXISTS_RENAME) {
    // ... [File copying routine]

    // Inform modules that the file has been copied.
    module_invoke_all('file_copy', $file, $source);

    return $file;
    // ...
}

Bir modül modulename_file_copy($file, $source), module_invoke_allin tarafından çağrılacak bir işlevi yerine getirebilir file_copy. Bu işlev bittikten sonra file_copyyürütme devam edecektir.

2. Etkinlikler

Uygulamaya, eklentiler tarafından dinlenebilecek olayları gönderin. Abone olunan bir etkinliği aldıktan sonra, bir eklenti program akışını durdurur ve gerekli işlemleri gerçekleştirir.

Örneğin, bir jQuery galeri eklentisi Fotorama birkaç etkinlik uygular . Örnek olarak, olayı showbaşlatan yönteminin bir parçası fotorama:show.

  that.show = function (options) {
    // ... [show the new frame]

    // [fire the event]
    options.reset || triggerEvent('show', {
      user: options.user,
      time: time
    });

    // ... [do lots of other stuff with navigation bars, etc.]
  };

Bir komut dosyası bu olayı dinleyebilir ve ateş ettiğinde bir şeyler yapabilir:

$('.fotorama').on(
  'fotorama:show',
  function (e, fotorama, extra) {
    console.log(e.type + (extra.user ? ' after user’s touch' : ''));
    console.log('transition duration: ' + extra.time);
  }
);

SORU

  1. Bu tür eklenti davranışını uygulamak için başka ana yollar var mı?

  2. Olmazsa, ne zaman kanca kullanılmalı ve ne zaman etkinlik kullanılmalı? Nihai hedef göz önüne alındığında, kodun hem uygulama hem de eklenti geliştiricisinin bakış açısından daha kolay anlaşılabilir ve okunabilir hale getirilmesidir ?

Yanıtlar:


17

Bir kanca ile olay arasındaki temel fark gevşek bağlantıya karşı sıkı bağlantıya bağlıdır.

Kanca, bir şey olduğunu yayınlamanın genel bir yoludur. Eklentileri yeniden derlemek zorunda kalmadan yeni kancalar ekleyebilirsiniz ve tüm kancalar genel bir tasarım deseni izler. Kanca API'si tanımlandıktan sonra değişmez, bu nedenle uygulama ile eklenti arasındaki bağlantı kopmaz.

Olaylar uygulamaya daha sıkı bağlandı. Olaylar, olaya eklenmiş parametreleri tanımlayabilir ve bu parametreleri değiştirirseniz API'yi mevcut eklentilerle kırarsınız.

Her ikisi de aynı sonuçları elde eder. Bu, eklentiyi uygulamaya nasıl bağlayacağınıza bağlıdır.

Hooks, uygulamanızın yeni sürümleri piyasaya sürüldüğü için kırılması muhtemel olmayan daha dinamik bir bağlantı sunabilir, ancak dezavantajı, eklentilerin artık uyumlu olmadığı konusunda herhangi bir derleme zamanı uyarısı almamanızdır.

Olaylar, bazı olay imzalarının değiştiği için eklentinin değiştirilmesi gereken derleme zamanı hatalarını almanızı sağlar.

Alternatif yaklaşımlar istediniz.

Komutlar:

Eklentilerin yerine tetiklenmiş olaylara cevap vermek. Eklentiler, komut nesnelerini uygulamaya yönlendirir. Her komut nesnesi, komutlar tarafından kullanılan bir arayüz uygular. Uygulamanın bir özelliği yürütmesi gerektiğinde, bu özellik için tüm komutları çalıştırır. Bu, geri çağırma işlevleri yerine nesneler olarak uygulanması dışında, olaylara çok benzer.

Makrolar:

Eklentiler yerine, olayların ne zaman gerçekleştiğine cevap veriyor. Eklentiler proaktif olarak olaylara neden olur. Bir makro, uygulamanın üzerinde çalışan ve ne yapılacağını söyleyen küçük bir üst düzey dildir.

Devlet Değişikliği Dinleyicileri:

Olaylar geliştirici tarafından öngörülen uygulama ile tetiklenir. Geliştiricinin, olayı açıklayan kodunu bilerek yazması gerekir. Bunun yerine, alternatif bir yaklaşım, iç durumları değiştiğinde nesnelerin otomatik olarak yayınlanmasını sağlamaktır. Bir mülkün değiştirilmesi veya diğer göstergeler. Eklentiler daha sonra bu spesifik durum değişikliklerini dinleyebilir ve buna göre tepki verebilir. Bu yaklaşımın avantajı, programcının olayları yayınlamayı hatırlaması gerekmemesidir. Örneğin, bir Belge nesnesi olabilir ve programlayıcı belgenin kaydedilmesi gerektiğini işaretlemek için bir bayrak belirler. Bu durum değişikliği, dinleme eklentilerine yayınlanır ve belge başlığını yıldız işareti içerecek şekilde değiştiren bir eklenti olabilir.


2
Alternatifler 1, -1 tanımları ve (kavrama argüman için yaptığı mevcut ancak kavrama size eklenti sistemine vermek hangisi isim tasarım seçenekleri sonucudur;)

5
Ayrıca bir olayın jeneratörden gözlemciye / dinleyiciye nasıl geçtiği hakkında varsayımlarda bulunduğunuzu düşünüyorum. Aslına bakılırsa tersidir, olaylar sıkı değilken kancalar sıkıca bağlanır.
Ahmed Mesud

3

Kesinlikle olaylar, zaten mimari düzeyde gerekli soyutlama sağlar.

Eklenti yazan hiç kimsenin belgelendiği veya herhangi bir şekilde doğru şekilde yapmasını beklemeyin. Milyonlarca kullanıcıyla iyi belgelenmiş bir API’yi sürdürüyorum ve temelde kimsenin belgeleri okumaması ve neredeyse hiç kimsenin API’yı doğru kullanmamasının çok acı verici bir deneyim olduğunu söyleyebilirim.

Kanca ile aşağıdaki örneği alın: 20 eklentinin çalıştığı bir sisteminiz var. Bu eklentilerden biri file_copyyöntemi belgelenen şekilde çağırır ve belgelendiği gibi bir sonuç bekler. Ancak başka bir eklenti de bu işlevi yerine getirmiştir ve bu nedenle aşağıdaki sorunlardan biri çökmeye veya arızaya neden olabilir:

  • Kanca işlevi basitçe çöküyor. Artık diğer tüm eklentiler de işin içine giriyor, çünkü artık file_copy yapamıyorlar ya da işlev beklenenden farklı çalışıyor.
  • Giriş belgelere göre doğrudur, ancak diğer eklenti beklemiyor ve garip sonuçlar veya çökmelere neden oluyor.
  • Arama iyi sonuç veriyor, ancak sonuç artık belgelere göre beklenenden fazla değil, böylece eklenti başarısız oluyor veya çöküyor.

Yukarıdakileri aynısını, bu eklentiler içinde aynı sorunlara sahip olaylarla yaparsanız, aşağıdakiler gerçekleşir:

  • Eklenti X'in olay işlevi çöküyor, ancak diğerleri iyi çalışıyor. Ancak, bu eklentiler ilişkili olmadığından, diğerleri iyi çalışmaya devam ederken kilitlenme eklentisini devre dışı bırakabilirsiniz.
  • Garip giriş, işleviniz tarafından düzgün bir şekilde işlenebilir ve her bir eklenti için olası tüm şeyleri ayrı ayrı kontrol edebilirsiniz. Eklenti geliştiricisinin artık eklentisini test etmenin kararlı ve güvenilir bir yolu var; bu onun için çalışırsa herkes için çalışacağından emin olmasını sağlıyor. Bir eklenti yanlış giriş sağlıyorsa, o eklentiye izole edilebilir.
  • Sonuç her koşulda eşit bir şekilde kontrol edilebilir ve tanımlanabilir, böylece eklenti geliştiricisi test edebileceği fonksiyondan kararlı ve güvenilir bir cevap alır.

1

Kalıtım bir seçenek olabilir.

Kancalardan başka, kalıtımın ekstra yöntem tanımlarına ihtiyacı yoktur ve bağlı hiçbir şey olmaması durumunda boş yöntemi çağırmak için performans kaybı olmaz.

Olaylar dışında, miras, olay çağrısı için fazladan bir kod gerektirmez.

Bununla birlikte, kalıtım en iyi sonucu, bir davranış türünü değiştiren yalnızca bir eklenti varsa çalışır. Çok sayıda eklentiye ihtiyacınız olursa, ikincisinin ilk vs.'den türetilmesi gerekir, ki bu uygun değildir.


-1 Eğer Inheritance kullanmak ve sonra ... yeni davranış ana uygulama olarak farklı bir amacı vardır gibi şartname ve kötüye miras kullanmayı başlatmasını kodunu değiştirmek için
Spark

0

Kesinlikle olaylar. Mimarinizin daha geniş ölçeklenebilir olmasını sağlar.

Eklentinizi örneğin ayrı bir makineye yerleştirmeniz gerektiğinde ne olacağını hayal edin. Olayları kullanma - etkinliklerinizi ağ tabanlı yapmak için yalnızca küçük bir kod rahatlığını değiştirmeniz gerekecektir.

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.