Olaylar sadece GUI programlama için kullanılıyor mu?


57

Olaylar sadece GUI programlama için kullanılıyor mu?

Diğer bir şeye bir şey olduğunda normal arka uç programlamayı nasıl ele alırsınız?


6
Bu arada, Event Source, Event-Programming için tamamen ortogonal bir konsepttir. Olay Kaynağı'nın temel konsepti, sisteminizin "durumunu" depolamak yerine "olayları" veya "değişiklikleri" sisteminize kaydetmenizdir. Örneğin, banka hesabınızı a) Bakiyeniz (STATE) veya b) Bir İşlemler (EVENTSOURCE) olarak modelleyebilirsiniz.
ArTs

4
Kullanıma bağlı olarak, bir "olay" genellikle şekerle sarılmış bir tür geri arama şeklidir. Geri aramalar her yerde kullanılır - ilgileniyorsanız, aramaya başlamak için muhtemelen iyi bir anahtar kelimedir.
J ...

10
Ayrıca, bir mikrodenetleyici kadar düşük bir seviyeye gidseniz bile, donanımın yararlı ve dengesiz bir şekilde gerekli bir özelliği kestiğini göreceksiniz. Kontrol sistemleri veya kahve makinesi gibi temel IO için idealdir. Bu donanım kesintileri aslında olaylardan esasen farklı değildir.
Dan

Hayır! Pratik örnek: Nodejs olayları
sampathsris

2
Windows'da mısın? Olay Görüntüleyicisini inceleyin. İyi eğlenceler.
Marc.2377

Yanıtlar:


106

Hayır! Gözlemcileri uygulamak ve sınıfların değişime kapalı olduğundan emin olmak için gerçekten kullanışlıdırlar.

Diyelim ki yeni kullanıcıları kaydeden bir yöntemimiz var.

public void Register(user) {
    db.Save(user);
}

Sonra birisi bir e-postanın gönderilmesi gerektiğine karar verir. Bunu yapabiliriz:

public void Register(user) {
    db.Save(user);
    emailClient.Send(new RegistrationEmail(user));
}

Ama biz sadece değişime kapalı olması gereken bir sınıfı değiştirdik. Muhtemelen bu basit sözde kod için gayet iyi, ancak üretim kodunda deliliğin yolu. Bu yöntemin ne kadar zamandır yeni bir kullanıcı oluşturmanın asıl amacı ile zorlukla bağlantılı olmayan 30 satır kod vardır?

Sınıfın çekirdek işlevini yerine getirmesine izin vermek ve bir kullanıcının kayıtlı olduğunu kim dinleyeceğini söyleyen bir etkinlik geliştirmek ve hangi işlemi yapmaları gerekiyorsa yapmaları (örneğin bir e-posta göndermek gibi) daha iyidir.

public void Register(user) {
    db.Save(user);

    RaiseUserRegisteredEvent(user);
}

Bu kodumuzu temiz ve esnek tutar. Göz ardı edilen OOP parçalarından biri, sınıfların birbirlerine mesaj göndermesidir . Olaylar bu mesajlardır.


37
Bunu okudum ve "rezervasyon oluştur" kodumuzu düşünüyorum ve bir süredir ve daha iyi bir yer için uzun süre ağlıyorum: '(
sara

1
+1, harika cevap. Sadece somut bir soru (bu beni biraz rahatsız etti): yöntem isimlerinizi (Kayıt, Kaydet ve Gönder) büyük harflerle başlatmanız için özel bir neden var mı? Tabi bu olsa da, bu cevabın faydası etkilenmez.
Pedro A

14
@Hamsteriffic Ben çoğunlukla bir C # dev ve genel kabul görmüş bir kongre. Başka sebep yok.
RubberDuck

6
@Hamsterifficas, alt boşluk olarak adlandırdığınız ancak ortada bir büyük harf içeren, genellikle camelCase olarak adlandırılır, çünkü orta kısımda humps vardır. Bu, küçük harfli kelimelerin python ve çoğu kabuk diline aşina olan alt çizgilerle ayrıldığı, snake_case'den ayırt eder.
Aaron,

5
Olaylar bu mesajlardan sadece bir tanesidir . Metod çağrıları da mesaj geçiyor sayılır.
jpmc26

53

Hayır!

GUI olmayan mantıkta kullanılan klasik olay örnekleri veritabanı tetikleyicileridir.

Tetikleyiciler, belirli bir olay gerçekleştiğinde yürütülen koddur (INSERT, DELETE, vb.). Bana bir olay gibi geliyor.

Bu, Wikipedia'nın etkinlik tanımıdır:

Hesaplamada olay, yazılım tarafından ele alınabilecek bir yazılım tarafından tanınan bir eylem veya olaydır. Bilgisayar olayları sistem tarafından, kullanıcı tarafından veya başka yollarla üretilebilir veya tetiklenebilir. Tipik olarak, olaylar program akışıyla eşzamanlı olarak gerçekleştirilir, yani yazılım, olayların işlendiği bir veya daha fazla özel yere, sıklıkla bir olay döngüsüne sahip olabilir. Bir olay kaynağı, örneğin, klavyedeki tuş vuruşları yoluyla yazılımla etkileşime girebilen kullanıcıyı içerir. Başka bir kaynak, zamanlayıcı gibi bir donanım cihazıdır. Yazılım ayrıca, örneğin bir görevin tamamlandığını bildirmek için kendi olay setini olay döngüsüne tetikleyebilir. Olaylara cevaben davranışını değiştiren yazılımın, çoğu zaman etkileşimli olmak amacıyla olaya yönelik olduğu söylenir.

Tüm olaylar kullanıcı tarafından oluşturulmaz. Bazıları daha önce de bahsettiğim gibi INSERT veri tabanının crontabı gibi bir zamanlayıcı tarafından üretilir.

Bu tanım aynı zamanda bazı programlardan veya sistemlerden "olay odaklı, çoğu zaman etkileşimli olma hedefiyle" ifade edildiğini ifade eder, ki bunlardan biri olayların amacının ya da kullanışlılığının yalnızca etkileşimi sağlamak için değil, sık sık etkileşimi sağlamaktır (GUI'ler gibi). her ne kadar mutlaka GUI olmasa da, CLI programları da etkileşimli olabilir).


2
Veri tabanı tetikleyicilerini duyduğumda hep bunu düşünüyorum: thecodelesscode.com/case/42
Almo

Eski bir DBA geliştiricisi olarak, insanların daha geniş DB performansını göz önünde bulundurmadan tetikleyicileri kullanmaktan bahsettiğini duyduğum her seferde cringe ediyorum.
Üç Değerli Mantık

28

Olay tabanlı programlama aslında yüksek performanslı sunucu programlaması için de kullanılıyor.

Tipik bir sunucu iş yükünde, bir sonucu işleyen zamanın çoğu aslında G / Ç'den gelir. Örneğin, bir (7200 RPM) sabit disk sürücüsünden veri çekmek 8,3 ms'ye kadar sürebilir. Modern bir GHz işlemci için bu, ~ 1 milyon saat döngüsüne eşittir. Bir CPU her seferinde veriyi bekleyecek olsaydı (hiçbir şey yapmadan), LOT saat döngüsü kaybederdik.

Geleneksel programlama teknikleri, çoklu ipliklerle bu sorunu çözer . CPU aynı anda yüzlerce iplik çalıştırmaya çalışıyor. Bununla birlikte, bu modelin problemi, bir CPU her iş parçacığı değiştirdiğinde, bağlam anahtarına yüzlerce saat döngüsü gerektirmesidir . Bağlamsal anahtar, CPU iş parçacığı yerel belleği CPU'nun kayıt defterlerine kopyaladığında ve aynı zamanda eski iş parçacığının kayıt / durumunu RAM'de sakladığında ortaya çıkar.

Ek olarak, her iş parçacığı durumunu depolamak için belirli miktarda bellek kullanmalıdır.

Bugün, tek bir iş parçacığı olan, bir döngü içinde çalışan sunucular için bir itme olmuştur. Ardından iş parçaları , tek bir iplik için bir sıra görevi gören (bir UI ipliğinde olduğu gibi) bir mesaj pompasına itilir . İşlemin bitmesini beklemek yerine, CPU sabit disk sürücüsü erişimi gibi şeyler için bir geri çağrı olayı ayarlar. Hangi bağlam anahtarlamasını azaltır.

Böyle bir sunucunun en iyi örneği, mütevazı bir donanım ile 1 milyon eşzamanlı bağlantıyı idare edebileceği gösterilen Node.js'dir. Java / Tomcat sunucusu ise birkaç bin kişiyle mücadele eder.


2
"Mütevazı donanım" biraz yanıltıcıdır. İşletim sisteminin kullandığı her şeye ek olarak, Node için 8GB + 'ya ihtiyacınız olacaktır. Çok fazla hafızanız varsa, Tomcat birkaç bin bağlantıyı kolayca yönetebilir. Verilmiş, büyük bir fark var, ama 1000x değil.
Paul Draper

@PaulDraper hayır olamaz. Ve hayır değil. 8000 iş parçacığı için sadece yığın için 8GB + gerekir. Bu büyük fark.
ArTs

3
@PaulDraper 8GB dışında sunucu standartlarına göre çok mütevazı. 128GB koçluk makinelerde çalıştım ve bunlar tam olarak yüklenmedi. Tokmaklar tüm makinenizden daha pahalı.
ArTs

yığın boyutunuzun ne olduğuna bağlıdır. Oracle / OpenJDK, 64-bit için çoğu platformda varsayılan olarak 1 MB, 32-bit için 512K'dır. Sadece varsayılanları alırsanız, doğru olurdu. Ancak varsayılanlar 1M Düğüm bağlantılarına nasıl ulaşacağınız değildir;) Her neyse, 128K çoktur; daha azıyla kurtulabilirsin. 8000 iş parçacığı için 1GB yığın alanı olurdu.
Paul Draper

6
Yanılıyorsun. Varsayılan yığın boyutunda bile, yalnızca 8 GiB sanal belleğe ihtiyacınız vardır . Hafıza anında gerekli olduğu gibi işlenir. Genellikle, fazladan bellek kullanmıyorsanız , yığın başına yalnızca bir sayfaya ihtiyacınız vardır . Ve pratikte, böyle bir sistemdeki çoğu diş sadece (genellikle) 64-kiB yığınlarına sahiptir. Sanal bellek kullanımı 32-bit işletim sisteminde çok büyük, ancak 64-bit'de çok fazla değil. Diğer sınırlara çok daha erken koşuyorsunuz - örneğin TCP bağlantı noktası tükenmesi, örneğin :) Ve neden düğümün bu "sözde yığınlarının" depolandığını düşünüyorsunuz? Doğru, yığında.
Luaan

10

Olaylar ayrıca pahalı meşgul bekleme döngülerinden kaçınmak için ağ programlamasında (örneğin Nginx) yoğun olarak kullanılır ve bunun yerine tam olarak belirli bir işlemin ne zaman mümkün olduğunu (I / O, acil veriler vb.) Bilmek için temiz bir arayüz sağlar . Bu aynı zamanda C10k problemine de bir çözümdür .

Temel fikir, İşletim Sistemine olayları, hepsini veya yalnızca özellikle ilgilendiğiniz bazılarını izlemek için bir dizi soket (yani ağ bağlantıları) sağlamaktır (örneğin, okuma için kullanılabilir veriler); Bu tür bir etkinlik işletim sistemi tarafından listedeki soketlerden birinde algılandığında, API tarafından aradığınız olayı size bildirir ve ardından nereden geldiğini çözmeniz ve ona göre davranmanız gerekir. .

Şimdi, bu düşük seviyeli ve soyut bir görünüm, dahası iyi ölçeklendirmek için zor. Bununla birlikte, bununla bile çapraz platformda başa çıkacak çok sayıda üst düzey çerçeve var: Python için Twisted, C ++ için Boost.Asio veya C için libevent aklıma geldi.


+1 "pahalı meşgul bekle döngüler": başka bir deyişle, bazı hareketsizlik (bekleme) işlemlerinin yanı sıra bu işlemler (mesajlar veya olaylar) arasında senkronizasyon içeren paralel işlemlerde kullanışlıdır. Gerçek dünyanın çoğu çalışıyor.
fr13d

Ağların kurulmasından önce soketlerin orijinal olarak tek bir makinede bir IPC formu olarak tasarlandığını bilmek ilginçtir.

5

Gömülü sistemler, açık bir şekilde programlanmamış olsalar bile, neredeyse her zaman doğal olarak olaya bağlıdır.

Bu olaylar donanım kesintileri, düğme presleri, analog-dijital okumalar, zamanlayıcı süreleri vb.

Düşük güçlü gömülü sistemlerin olay odaklı olması daha da muhtemeldir; zamanlarının çoğunu uyuyarak geçiriyorlar (CPU düşük güç modunda uyuyor), bir şeyin olmasını bekleyerek ("bir şey" bir olaydır).

Olay odaklı gömülü sistemler için en yaygın ve popüler çerçevelerden biri olan Kuantum Platformu (QP) (QP ayrıca Linux, Windows ve herhangi bir unix benzeri işletim sistemi altında da çalışıyor.) Durum makineleri, olay odaklı programlamaya uygun Program tipik anlamda "sıralı" olmadığından, sistem durumuna ve mevcut olaya bağlı olarak çağrılan bir "geri çağırma" kümesidir.


3

Olay Mesajları Gregor Hohpe.

Etkinlik Odaklı Mimariler Gregor Hohpe.

SEDA mimarisi , Galce, Culler, Brewer.

Başka bir şey olduğunda bir şey olduğunda normal arka uç programlamasında nasıl baş edersiniz?

Sonlu Durum Makinesi , ortak bir yaklaşımdır

Given(State.A)
When(Event.B)
Then(State.C)
    .and(Consequences.D)

2
1, bu gerçekten tutarlı bir cevap değildir ve 2, FSM olay kullanımına iyi bir örnek değildir.
whatsisname

1
FSM. Pastafarian dininin bir dizi olayı gözlemlediğinden eminim ;-)
fr13d

0

Gömülü sistemlerde, kesintiler sırasında olaylar meydana gelir. Zamanlayıcılardan G / Ç'ye kadar birçok kesinti kaynağı vardır.

Ayrıca, RTOS'da da olaylar olabilir. Bir örnek başka bir görevden mesaj bekliyor.


0

Gömülü olmayan sistem için ama C # ile yaptığım bir şey SCADA sistemi idi. Yük boşaltılırken sistem tarafından üretilen olayın bir kısmı boşaltılırken, diğer kısım veritabanına yeni durum yazarken depoda olanlarla ilgili birçok olay vardı. Elbette bazı GUI istemcilerimiz vardı, fakat sadece depo durumunu yansıtan veri tabanının durumunu göstermekti. Bu yüzden olaylara ve iş parçacığına dayanan arka uç sunucu yazılımıydı. Geliştirilmesi oldukça zor.

https://en.wikipedia.org/wiki/SCADA

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.