İçeriğe geç
academia.sh

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.

Aramak için yazmaya başlayın.

↑↓ Esc gezin · aç · kapat