Bir olay , yakın geçmişten bir oluşumu açıklayan bir bildirimdir.
Bir olaya dayalı sistemin tipik bir uygulaması, bir olay memuru ve işleyici işlevlerini (veya aboneleri ) kullanır. Gönderici, işleyicilere olaylara (jQuery'ler bind
) bağlanmak için bir API ve abonelerine bir etkinlik yayınlamak için bir yöntem ( trigger
jQuery'de) sağlar. IO veya UI olaylarından söz ederken, genellikle fare tıklamaları gibi yeni olayları tespit edip göndericiye ileten bir olay döngüsü de vardır . JS-land'te gönderici ve olay döngüsü tarayıcı tarafından sağlanır.
Doğrudan kullanıcıyla etkileşime giren kod için - tuş basmalarına ve tıklamalarına yanıt - olaya dayalı programlama (veya işlevsel reaktif programlama gibi bir varyasyonu ) neredeyse kaçınılmazdır. Siz, programcı, kullanıcının ne zaman ve nerede tıklayacağı hakkında hiçbir fikriniz yoktur, bu nedenle kullanıcının etkinlik döngüsündeki eylemini algılamak ve kodunuzu bildirmek için GUI çerçevesine veya tarayıcıya bağlıdır. Bu tür altyapı ağ uygulamalarında da kullanılır (cf NodeJS).
Örneğinizde, doğrudan bir işlevi çağırmak yerine kodunuzdaki bir olayı ortaya çıkardığınızda, aşağıda tartışacağım daha ilginç bazı değişimler var. En büyük fark, bir olayın ( makeItSnow
) yayıncısının aramanın alıcısını belirtmemesidir; başka bir yere bağlanmış ( bind
örneğinize yapılan çağrıda ). Buna ateş ve unut denir : makeItSnow
dünyaya kar yağdığını duyurur, ama kimin dinleyeceği, sonra ne olacağını ya da ne zaman olacağını umursamıyor - sadece mesajı yayınlıyor ve ellerini siliyor.
Böylece olay odaklı yaklaşım, mesajın göndericisini alıcıdan ayırır. Bunun size sağladığı avantajlardan biri, belirli bir olayın birden fazla işleyiciye sahip olabileceğidir. gritRoads
Mevcut shovelSnow
işleyiciyi etkilemeden kar etkinliğinize bir işlev bağlayabilirsiniz . Uygulamanızın kablolu yayınlanmasında esneklik var; Bir davranışı kapatmak için davranışın bind
tüm örneklerini bulmak için kodda arama yapmak yerine aramayı kaldırmanız yeterlidir .
Etkinliğe dayalı programlamanın bir başka avantajı, enine kaygıları dile getirecek bir yer vermesidir. Etkinlik dağıtıcısı Mediator rolünü oynar ve bazı kütüphaneler ( Parlak gibi), günlük kaydı veya hizmet kalitesi gibi genel gereksinimleri kolayca ekleyebilmeniz için bir boru hattı kullanır.
Tam açıklama: Daha çok çalıştığım Huddle'da geliştiriliyor.
Alıcıdan bir olayın gönderen ayırma üçüncü avantajı size esneklik sağlamasıdır zaman etkinliği işlemek. Her olay türünü kendi iş parçacığında işleyebilir (olay memurunuz destekliyorsa) veya yükseltilmiş olayları RabbitMQ gibi bir mesaj aracısına koyabilir ve bunları asenkronize bir işlemle işleyebilir veya hatta bir gecede toplu olarak işleyebilirsiniz. Olayın alıcısı ayrı bir işlemde veya ayrı bir makinede olabilir. Bunu yapmak için olayı yükselten kodu değiştirmeniz gerekmez! Bu, "mikro hizmet" mimarilerinin arkasındaki Büyük Fikir: özerk hizmetler, olayları kullanarak, uygulamanın omurgası olan mesajlaşma yazılımı ile iletişim kurar.
Etkinlik odaklı stilin oldukça farklı bir örneği için, etki alanlarının toplamaların ayrı tutulmasına yardımcı olmak için kullanıldığı etki alanı odaklı tasarıma bakın . Örneğin, satın alma geçmişinize göre ürünler öneren bir çevrimiçi mağaza düşünün. A ödendiğinde Customer
satın alma geçmişinin güncellenmesi gerekir ShoppingCart
. ShoppingCart
Agrega bildirimler de Customer
bir yükselterek CheckoutCompleted
olayı; Customer
olaya tepki olarak ayrı bir işlemde güncellenmelerini olacaktır.
Bu olaya dayalı modelin asıl dezavantajı dolaylı. Olayı işleyen kodu bulmak artık daha zor çünkü IDE'nizi kullanarak sadece oraya gidemezsiniz; Etkinliğin konfigürasyonda nerelere bağlı olduğunu bulmak zorundasınız ve tüm işleyicileri bulmayı umuyorsunuz. Herhangi bir anda kafanda tutabilecek başka şeyler var Kod stili kuralları burada yardımcı olabilir (örneğin, tüm aramaları bind
tek bir dosyaya koymak ). Akıl sağlığınız uğruna, yalnızca bir olay göndereni kullanmak ve tutarlı bir şekilde kullanmak önemlidir.
Diğer bir dezavantaj ise olayları yeniden düzenlemenin zor olmasıdır. Bir etkinliğin biçimini değiştirmeniz gerekirse, tüm alıcıları da değiştirmeniz gerekir. Bir etkinliğin aboneleri farklı makinelerde olduğunda bu daha da kötüleşir, çünkü şimdi yazılım sürümlerini senkronize etmeniz gerekir!
Bazı durumlarda performans önemli olabilir. Bir mesajı işlerken, gönderici şunları yapmak zorundadır:
- Bazı veri yapısındaki doğru işleyicileri arayın.
- Her işleyici için bir ileti işleme hattı oluşturun. Bu, bir grup hafıza ayırmayı içerebilir.
- Dinleyicileri dinamik olarak çağırın (dil gerektiriyorsa muhtemelen yansıma kullanarak).
Bu kesinlikle sadece yeni bir kareye basmayı içeren normal bir işlev çağrısından daha yavaştır. Bununla birlikte, olaya dayalı bir mimarinin size sağladığı esneklik, yavaş kodu izole etmeyi ve optimize etmeyi çok kolaylaştırır. İşi eşzamansız bir işlemciye gönderme kabiliyetine sahip olmak burada büyük bir kazançtır, zira arka planda zor iş yapılırken derhal bir talepte bulunmanıza izin verir. Her durumda, eğer DB ile etkileşime giriyorsanız veya ekrandaki çizimleri çiziyorsanız, IO maliyetleri tamamen bir mesaj işlemenin maliyetini düşürecektir. Erken optimizasyondan kaçınmak için bir durum.
Özetle, olaylar gevşek bir şekilde birleştirilmiş bir yazılım oluşturmak için harika bir yoldur, ancak ücretsizdirler. Örneğin, uygulamanızdaki her işlev çağrısını bir olayla değiştirmek yanlış olur . Anlamlı mimari bölümler oluşturmak için olayları kullanın.
$(document).bind('snow', shovelShow)
. İsimsiz bir fonksiyona sarmaya gerek yok.