Ders 06 / 22
Durum Türleri
Durumun türlerine ayrılması; yerel, paylaşılan, URL ve sunucu durumu ile türetilmiş değer, her türü yerleştiren karar yordamı, tek doğru kaynak ilkesi ve yanlış yerleştirmenin maliyeti.
İçindekiler
Yönlendirme tamamlandı: adres hangi ekranın görüneceğini, kime açık olduğunu ve hangi kodun ineceğini belirliyor. Adresin taşıdığı bir durum türü de tanımlandı — süzgeç, sıralama, sayfa. Kuzey Yamaç Ölçüm İstasyonu uygulamasının geri kalan durumu ise dağınık: oturum bilgisi koruyucularda, istasyon listesi bir yerde, açık paneller bileşenlerin içinde, sunucudan gelen ölçümler bir başka yerde.
Bunların hepsine “durum” demek, aralarındaki en önemli farkı gizler. Bazıları uygulamanın kendi ürettiği ve tek sahibi olduğu değerlerdir; bazıları uzaktaki bir kaynağın kopyasıdır. Bu ders durumu türlerine ayırır, her türün nereye konacağını belirleyen ölçütü verir ve yanlış yerleştirmenin maliyetini gösterir.
Beş Tür
Yerel durum tek bir bileşenin okuduğu ve yazdığı değerdir: açılır listenin açık olup olmadığı, bir metin kutusunun o anki içeriği. Bileşenle birlikte doğar, onunla birlikte ölür.
Paylaşılan durum birden çok bileşenin okuduğu, uygulamanın kendi ürettiği değerdir: arayüz teması, yan gezinmenin açıklığı, seçili birim sistemi. Sahibi uygulamadır; başka kimse değiştirmez.
URL durumu adreste taşınan durumdur. Bir önceki konu bunu tanımladı: paylaşıldığında, yer imine eklendiğinde ve geri düğmesiyle dönüldüğünde geri gelmesi beklenen durum.
Sunucu durumu uzaktaki bir kaynağın istemcideki kopyasıdır: istasyon listesi, ölçüm kayıtları, oturum açmış kullanıcının bilgileri. Diğer dördünden ayıran özelliği sahipliğin istemcide olmamasıdır.
Türetilmiş değer ise aslında durum değildir. Başka durumlardan hesaplanabilen her şey bu sınıfa girer: süzülmüş listenin uzunluğu, seçili ögelerin toplamı, bir isteğin devam edip etmediğini gösteren bayrak.
Bu beşli, bir karar yordamına çevrilebilir.
// durum-turleri.mjs — durumu yerlestiren karar yordami ve turetilmis degerin saklanma maliyeti function sinifla(k) { if (k.turetilebilir) return ["turetilmis", `${k.turetilebilir} degerinden hesaplanir`]; if (k.kaynak === "sunucu") return ["sunucu", "sahibi uzakta, kopyasi tutulur"]; if (k.adreste) return ["URL", "paylasildiginda geri gelmeli"]; if (k.tuketici > 1) return ["paylasilan", `${k.tuketici} ayri tuketici okuyor`]; return ["yerel", "tek bilesen okuyor"]; } const OGELER = [ { ad: "istasyon listesi", kaynak: "sunucu", tuketici: 2 }, { ad: "olcum gecmisi sayfa no", adreste: true, tuketici: 2 }, { ad: "secili olcum turu suzgeci", adreste: true, tuketici: 3 }, { ad: "oturum acmis kullanici", kaynak: "sunucu", tuketici: 6 }, { ad: "yan gezinme acik mi", tuketici: 2 }, { ad: "arayuz temasi", tuketici: 5 }, { ad: "form alaninin o anki degeri", tuketici: 1 }, { ad: "suruklenen kaydiricinin anlik degeri", tuketici: 1 }, { ad: "suzulmus olcum sayisi", turetilebilir: "olcumler + suzgec" }, { ad: "yukleniyor gostergesi", turetilebilir: "sunucu durumu" }, ]; console.log("-- yerlestirme --"); for (const o of OGELER) { const [sinif, gerekce] = sinifla(o); console.log(o.ad.padEnd(38), sinif.padEnd(12), gerekce); } // Turetilmis degeri saklamak ile her okumada hesaplamak. const suz = (olcumler, tur) => olcumler.filter((o) => tur === "hepsi" || o.tur === tur); let durum = { olcumler: [{ tur: "sicaklik", d: -4.2 }, { tur: "nem", d: 71 }, { tur: "sicaklik", d: -3.8 }], suzgec: "sicaklik", saklananSayi: 2, // el ile guncellenen turetilmis deger }; const bas = (etiket) => console.log( etiket.padEnd(30), "saklanan:", String(durum.saklananSayi).padEnd(3), "hesaplanan:", suz(durum.olcumler, durum.suzgec).length); console.log("-- turetilmis deger --"); bas("baslangic"); durum = { ...durum, olcumler: [...durum.olcumler, { tur: "sicaklik", d: -5.1 }] }; bas("yeni sicaklik olcumu eklendi"); durum = { ...durum, suzgec: "nem" }; bas("suzgec neme cevrildi"); durum = { ...durum, saklananSayi: suz(durum.olcumler, durum.suzgec).length }; bas("saklanan el ile duzeltildi"); durum = { ...durum, olcumler: durum.olcumler.filter((o) => o.tur !== "nem") }; bas("nem olcumleri silindi");
-- yerlestirme -- istasyon listesi sunucu sahibi uzakta, kopyasi tutulur olcum gecmisi sayfa no URL paylasildiginda geri gelmeli secili olcum turu suzgeci URL paylasildiginda geri gelmeli oturum acmis kullanici sunucu sahibi uzakta, kopyasi tutulur yan gezinme acik mi paylasilan 2 ayri tuketici okuyor arayuz temasi paylasilan 5 ayri tuketici okuyor form alaninin o anki degeri yerel tek bilesen okuyor suruklenen kaydiricinin anlik degeri yerel tek bilesen okuyor suzulmus olcum sayisi turetilmis olcumler + suzgec degerinden hesaplanir yukleniyor gostergesi turetilmis sunucu durumu degerinden hesaplanir -- turetilmis deger -- baslangic saklanan: 2 hesaplanan: 2 yeni sicaklik olcumu eklendi saklanan: 2 hesaplanan: 3 suzgec neme cevrildi saklanan: 2 hesaplanan: 1 saklanan el ile duzeltildi saklanan: 1 hesaplanan: 1 nem olcumleri silindi saklanan: 1 hesaplanan: 0
Yordamın sıralaması rastgele değildir. Türetilebilirlik en başta sınanır, çünkü türetilmiş bir değer hiçbir yere konmaz. Sunucu kaynağı ikinci sıradadır: sahiplik sorusu, kaç bileşenin okuduğu sorusundan önce gelir. Adres sınaması paylaşımdan önce gelir, çünkü adrese yazılan durum zaten uygulama genelinde okunabilir hâle gelir.
Türetilmiş Değeri Saklamanın Maliyeti
Çıktının ikinci bölümü tek bir kusuru adım adım gösterir. Süzülmüş ölçüm sayısı bir durum alanında saklanıyor ve elle güncelleniyor.
Yeni ölçüm eklendiğinde saklanan değer ikide kalır, hesaplanan üçe çıkar. Süzgeç neme çevrildiğinde ikisi arasındaki fark yön değiştirir. Saklanan değer elle düzeltildiğinde ikisi bir an için uyuşur — ama bir sonraki değişiklikte yeniden ayrışır. Her yeni yazma noktası, güncellenmesi unutulabilecek yeni bir yerdir.
Bu, tek bir kuralın örneğidir: aynı bilgi iki yerde tutulmaz. Türetilmiş değer saklandığında iki doğru kaynak ortaya çıkar ve hangisinin doğru olduğu belirsizleşir. Hesaplama maliyetinden endişe ediliyorsa çözüm saklamak değil, hesabı bellemektir; bu Bileşen Tabanlı Arayüz Geliştirme kursundaki türetilmiş değerler dersinin konusudur ve sonuç yine tek doğru kaynaktır.
Yükleniyor göstergesinin türetilmiş sayılması aynı gerekçeye dayanır. Ayrı bir bayrak tutulduğunda istek bitip bayrağın kapatılmadığı durum kaçınılmazdır; hata yolunda, iptalde, eşzamanlı ikinci istekte. Göstergenin doğru kaynağı isteğin kendi durumudur.
Sunucu Durumunun Ayrılığı
Diğer dördü uygulamanın kendi ürettiği değerlerdir: yazılan değer doğrudur, çünkü yazan uygulamadır. Sunucu durumu için bu geçerli değildir. İstemcideki istasyon listesi, uzaktaki listenin geçmiş bir andaki kopyasıdır. Başka bir kullanıcı yeni istasyon eklemiş, biri bir ölçümü düzeltmiş olabilir.
Bu farktan dört soru doğar ve dördü de diğer durum türlerinde sorulmaz. Kopya ne kadar süre güncel sayılır? Eskidiğinde ne zaman yenilenir? Aynı veriyi iki bileşen isterse kaç istek yapılır? Yerel bir değişiklik sunucuya yazılırken ekranda ne görünür?
Sunucu durumunu paylaşılan durumla aynı yere koymak bu dört soruyu kaybettirir. Uygulama kopyayı gerçek sanır: veri bir kez alınır, bellekte tutulur ve hiç tazelenmez. Kullanıcı başka bir sekmede eklediği istasyonu listede göremez. Bu nedenle sunucu durumu ayrı bir katmanda, kendi tazelik kurallarıyla tutulur; o katman bu konunun dördüncü dersinin konusudur.
Yerleştirme İlkesi
Durumun nereye konacağını belirleyen ilke, olabildiğince aşağıda tutmaktır: yalnız tek bir bileşenin ilgilendiği değer yukarı çıkarılmaz.
Bunun gerekçesi Bileşen Tabanlı Arayüz Geliştirme kursundaki tek yönlü akışın doğal sonucudur. Yukarı çıkarılan her değer, aradaki bileşenlerin görmek zorunda olduğu bir bağımlılık yaratır; ayrıca değişimi ondan etkilenmeyen bileşenlere de duyurur. Aşağıda tutulan durum yalnız kendi bileşenini ilgilendirir.
Karşı yönde bir tuzak vardır: durumu gerekenden aşağıda tutmak. İki kardeş bileşen aynı değeri kendi içlerinde tuttuğunda iki kopya oluşur ve ayrışırlar. Ölçüt sabittir: değeri okuyan bileşenlerin en yakın ortak atası. Ondan aşağıda tutulamaz, ondan yukarıda tutulması ise gereksizdir.
Bu ilke iki türde uygulanmaz. URL durumunun yeri zaten bellidir; sunucu durumu ise bileşen ağacının hiçbir düğümüne ait değildir, çünkü aynı veriyi ağacın farklı yerlerindeki bileşenler ister ve kopyanın tek olması gerekir.
Özet
- Durum beş sınıfa ayrılır: yerel, paylaşılan, URL, sunucu ve türetilmiş; ilk dördü saklanır, beşincisi hesaplanır.
- Karar yordamı önce türetilebilirliği, sonra sahipliği, sonra adresi, en son tüketici sayısını sorar.
- Türetilmiş değer saklandığında iki doğru kaynak oluşur ve her yazma noktasında yeniden ayrışma riski doğar; çözüm saklamak değil, gerektiğinde hesabı bellemektir.
- Sunucu durumunun sahibi istemci değildir; tazelik, yenileme, istek tekrarı ve yazma sırasında görünen durum soruları yalnız bu türde sorulur.
- İstemci durumu, onu okuyan bileşenlerin en yakın ortak atasında tutulur — daha aşağıda tutmak kopya üretir, daha yukarıda tutmak gereksiz bağımlılık yaratır.
Sonraki Adım
Türler ayrıldı ama paylaşılan durumun nasıl tutulacağı henüz açık değil. Ortak atada tutulan bir değer, ağaç derinleştikçe onu kullanmayan onlarca bileşenin arasından geçirilir; üstelik bu değeri kimin, hangi olayda değiştirdiği kodun içine dağılır. İstasyon listesinde bir satırın seçilmesi, bir ölçümün silinmesi, oturumun kapatılması — üçü de aynı durumu farklı yerlerden değiştirir ve bir hata çıktığında değişikliği kimin yaptığı izlenemez. Sonraki ders durumu tek bir yerde toplayan, değişimi yalnız adlandırılmış eylemlerle kabul eden ve geçişleri saf bir işlevle tanımlayan merkezî depo kalıbını ele alır.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.