Backend geliştirmede, bir işlem tamamlandığında birden fazla yan işlemi tetiklemek yaygın bir ihtiyaçtır. Örneğin, bir sipariş onaylandığında e-posta göndermek, envanteri güncellemek ve analitik kaydı tutmak gerekebilir. Bu yan işlemleri ana iş akışına doğrudan eklemek, zamanla kodun bakımını zorlaştırır ve bağımlılıkları artırır. İşte bu noktada Observer Pattern devreye girer. Bu yazıda, Node.js'in doğal desteği olan EventEmitter kullanarak Observer Pattern'i nasıl uygulayacağınızı adım adım göreceğiz.
Observer Pattern, bir nesnenin (Subject) durumu değiştiğinde, ona bağlı olan diğer nesnelerin (Observer) otomatik olarak bilgilendirilmesini sağlar. Bu, yayıncı-abone (Pub/Sub) modeli olarak da bilinir. Ana işlem, olayları yayınlar; dinleyiciler ise bu olaylara tepki verir. Bu sayede, ana işlem yan işlemlerin detaylarından habersizdir ve gevşek bağlı bir yapı elde edilir. Örneğin, bir radyo istasyonu yayın yapar, dinleyiciler ise istedikleri zaman bu yayını alır. İstasyon, kimin dinlediğini bilmez.
Node.js'te Observer Pattern'in en yaygın uygulaması, events modülündeki EventEmitter sınıfıdır. EventEmitter, olayları dinlemek ve yayınlamak için on() ve emit() metodlarını sunar. Bir sınıf EventEmitter'dan türetilerek yayıncı haline getirilebilir. Dinleyiciler ise on() metodu ile olaylara abone olur. Bu yapı, Node.js'in olay döngüsüyle doğal olarak uyumludur ve asenkron işlemleri kolayca yönetir.
Teknik Analiz
Şimdi, bir sipariş işleme senaryosu üzerinden Observer Pattern'i uygulayalım. Öncelikle, OrderService sınıfını EventEmitter'dan türetiyoruz. placeOrder metodu, siparişi işledikten sonra 'orderPlaced' olayını emit eder. Bu olay, sipariş verisini taşır. Ardından, ayrı dosyalarda NotificationListener ve LogisticsListener gibi dinleyiciler tanımlıyoruz. Her dinleyici, orderEmitter.on('orderPlaced', callback) ile olaya abone olur. Bu sayede, OrderService hiçbir yan hizmete doğrudan bağlı değildir.
Nasıl Önlem Alınmalı?
Uygulamanın başlangıç noktasında (composition root), OrderService örneği oluşturulur ve dinleyiciler bu örneğe bağlanır. Böylece, yeni bir yan işlem eklemek istediğimizde, sadece yeni bir dinleyici dosyası oluşturup başlangıç noktasında abone yapmamız yeterlidir. Ana işlem kodu değişmez. Örneğin, bir denetim kaydı eklemek için setupAuditListener fonksiyonu yazılır ve app.js'de çağrılır. Bu, Open/Closed prensibine uygundur: sistem genişlemeye açık, değişikliğe kapalıdır.
Uzmanların Görüşleri
Observer Pattern, başta bildirim, loglama, önbellek temizleme ve üçüncü parti servis entegrasyonları olmak üzere birçok senaryoda kullanışlıdır. Ancak dikkat edilmesi gereken noktalar vardır: Olayların sırası garanti edilmez; her dinleyi eşzamanlı çalışır. Ayrıca, dinleyici sayısı arttıkça hata ayıklama zorlaşabilir. Bu nedenle, olay isimlendirmeleri net olmalı ve her dinleyici kendi hata yönetimini yapmalıdır. Son olarak, Observer Pattern'i uygularken EventEmitter'ın memory leak riskine karşı dinleyicileri gerektiğinde removeListener ile temizlemek önemlidir.
Sonuç olarak, Observer Pattern Node.js ekosisteminde olay odaklı, gevşek bağlı ve ölçeklenebilir sistemler kurmanın temel taşıdır. EventEmitter sayesinde, bu deseni uygulamak son derece kolaydır. Ana iş akışınızı yan etkilerden arındırarak daha temiz, bakımı kolay ve genişletilebilir bir kod tabanına sahip olabilirsiniz. Bir sonraki projenizde bu deseni kullanarak, bağımlılıkları azaltın ve sisteminizi gelecekteki değişikliklere hazır hale getirin.
Kaynak: dev.to