Yayınlama-abone olma paterninin gotos'tan farkı nedir?


11

Anladığım kadarıyla, Goto ifadeleri genellikle kaşlarını çattı . Ancak yayınlama-abone olma modeli , bir kod parçası bir mesaj yayınladığında, tek yönlü bir kontrol aktarımı gerçekleştirmesi bakımından kavramsal olarak benzer görünmektedir. Programcı, programın hangi bölümlerinin bu mesaja abone olduğunu bilmiyor olabilir.

Bir çok JavaScript programında benzer bir şey gördüm, burada olaylar modüller arasında rahatça "hoplamak" için kullanılır. Yayınlama-abone olma veya etkinlik odaklı kalıplar hakkında bir şey mi eksik?


5
return, try/catch, break, continue, switch- olanlardır tüm goto . Goto inşa kısıtlamanın çeşitli düzeylerde zararlı nasıl kod çalıştığı hakkında düşünme zararlıdır düşündü.

@MichaelT: Vakaların ezici bir çoğunluğu için, goto'ya kod hakkında akıl yürütmeyi kolaylaştıran alternatifler var. Bu gerçeği anlamanın hiçbir zararı yok. Zarar sadece garanti edildiğinde goto kullanmazsanız (genellikle değil) veya dikkatsizce goto kullanırsanız yapılır. Apple'ın bize ikincisine iyi bir örnek gösterdiğine inanıyorum .
back2dos

... programın parçaları abone ne hiçbir fikri ... : ilk önemli fark gotoiçinde yalanlar s sonundaki parçaları . İkinci büyük fark hiçbir fikrim yok . Üçüncü büyük fark, kavramsal olarak a gosubdeğil a goto.
mouviciel

1
INTERCAL'in "geldiği yer" e daha yakındır.
CodesInChaos

@ back2dos ayrıca, 1 satırlık kod blokları için bile neden kıvırcık parantez kullanmayı tercih ettiğimin iyi bir örneğidir.
MetaFight

Yanıtlar:


19

Evet, kesinlikle bir şey eksik . Gotos, tipik olarak, dediğin gibi, tek yönlü kontrol transferi yapmak için kullanılır.

Ancak, olaylar bunu yapmaz. Kod olayı tetiklediğinde, olay yayınlandığında (veya işlendiğinde, kuyruğa alındığında, tetiklendiğinde vb.) Kod yürütmesinin, olayı oluşturan kodun bir sonraki satırında devam edeceğini tam olarak bilir.

Goto kullanımı bu ifadeyi çağıran kod ile alıcı uçtaki kod arasında çok sıkı bir bağlantı oluşturur. Geliştirici, goto kullanmak için her iki yer hakkında da samimi bilgiye sahip olmalıdır.

Öte yandan, olayları tetikleyen kod genellikle o olayı kimin dinlemekle ilgilendiğini bilemez veya umursamaz. Orada olabilir bir dinleyici olmak. Ya da 100 dinleyici veya 0 olabilir. Bu dinleyiciler, etkinliğin tetiklendiği aynı programda olabilirler veya tamamen farklı bir uygulamada olabilirler veya farklı bir makinede olabilirler. Yayıncı söz konusu olduğunda, işini gerçekleştirdiği olayı ürettiği anda.

Şimdiye kadar benimle iseniz, yukarıda tarif ettiğim şey pub / sub modelinin ideal örneğidir. Ne yazık ki gerçek dünyada işler her zaman ideal değildir ve yayıncıların bir etkinlik oluşturduğu, bir abonenin çağrıldığı, bir grup devleti değiştirdiği ve zaman kodunun yayıncıya geri döndüğü durumlarda "dünya" baş aşağı çevrildi. Ve eminim geçmişte bu durumla karşılaştınız, çünkü bu durum genellikle pub / alt deseni çok basit bir şekilde uygulandığında ortaya çıkar (örneğin, C #'daki delegelerin veya olayların veya C'deki işlev / arabirim işaretlerinin kullanılmasıyla) / C ++).

Ancak bu sorun zorunlu olarak pub / alt kalıp değil, bunun uygulanmasından ibarettir. Bu yüzden birçok sistem kuyruklara güvenir, böylece bir olay yayınlandığında, daha sonra çağrılmak için sıraya alınır, daha sonra yayıncıya dünya hala bozulmamışken yürütmeyi bitirme şansı verir. Yayıncı işini bitirdiğinde, bir olay döngüsü (gönderme döngüsü olarak da bilinir) olayları çıkarır ve aboneleri çağırır.


+1 yayınlama / abone olma gevşek bağlantıya izin verir; gitmiyor
Fuhrmanator

6

Birkaç fark var. Birincisi, bir kod GOTO yürüttüğünde kontrolü bırakır ve kontrolü yeniden kazanacağının garantisi yoktur. Ancak pub / sub'daki bir yayıncı, uygun şekilde mesaj göndererek mantığını çalıştırmaya ve gerçekleştirmeye devam eder. Davranışı anlaşılabilir ve öngörülebilir.

İkincisi, abone mesaj alacak ve GOTO'dan farklı olarak mesajın kendisi bağlam taşıyor. Hem mesaj türü hem de taşıdığı özellikler aboneye rolünü yerine getirmesini söylemeye yardımcı olur. Ve bir iletiyi işledikten sonra abone hala yeni iletiler alabilir. Bu yüzden davranışı da anlaşılabilir ve öngörülebilir.

Büyük fark, yayıncının ve abonenin iyi tanımlanmış bir yürütme akışına sahip olması ve özünde, mesaj gönderirken ve alırken döngüsel olarak ve işlerini yapmaya devam etmeleridir. GOTOs ile Kod olabilir iyi yazılmış ve düzenli olmak, ama aynı zamanda düşürebilir ve açıkça anlaşılır davranış aynı garanti yoktur.

Yine de haklısın. Birisi, çok fazla mesaj ve işleme akışını takip eden çok küçük sıçramalarla bir pub / alt sistemi yazabilir, bir kabus haline gelebilir. Öte yandan, GOTO'larla son derece düzenli davranan ve kolayca anlaşılabilen bir sistem yazabilirsiniz. (Sembolik diller ele geçirilmeden önce çok karmaşık sistemler için montaj kodunu düşünüyorum.)

Ancak genellikle, pub / sub'den elde ettiğiniz ayırma, dağıtılmış işleme sorununu ve sisteminizdeki ayırma mantığını basitleştirir. Ayrıca tipik olarak, düz GOTO'lar, kontrol akışının anlaşılmasının sorunlu hale geldiği karmaşık sistemler oluşturma eğilimindedir.

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.