Data-Oriented Programming(DOP) — 3-Temel Veri Manipülasyonu

İbrahim Kürce
5 min readAug 20, 2023

--

Yazının ikinci bölümünü buradan okuyabilirsiniz.

DOP’da veri modellerimiz, map ve dizilerin(veya listelerin) dinamik bir kombinasyonu ile gösterilir. Sınıflardan nesneler oluşturmak yerine String map’leri kullanmaya başladığımızda, sistem esnekliğini artırırız. Ayrıca, sistemimizi sınıf-tabanlı sistemin kırılganlığından bizi uzaklaştırır.

Veri modelimizi tekrar hatırlarsak, şöyleydi:

Örneğin, OOP'de Book ve Author sınıfları arasında çoktan-çoka(many-to-many) association ilişkisini göstermek istediğimizi düşünelim. Book varlığında, author ID listesini tutarız ve Author varlığında book ID listesini tutarız. Book ID’sini ISBN global kitap numarası olarak düşünebiliriz.

Bunu DOP’da Catalog varlığımızda tutacağımız 2 hashMap olarak göstermek istersek;

  • booksByIsbn ile anahtarların(keys) ISBN’ler olduğu ve değerlerin(values) Book varlıkları olduğu bir hashMap,
  • authorsById ile anahtarların author ID’leri olduğu ve değerlerin Author varlıkları olduğu bir hashMap olarak gösterebiliriz.

Bunu detaylandıralım.

Record’ları Map Olarak Gösterme

Kod ve veri arasındaki ayrımdan ve her birinin kısıtından bahsetmiştik. Şimdiye kadar şunları söyledik:

  • Kod, statik fonksiyonlardan oluşur ve belirgin olarak ihtiyacı olan argümanları alır.
  • Veri varlıkları, record’lar olarak tutulur. Aralarındaki ilişki de map veya dizi şeklinde tutulur.

İşi bir adım daha ileriye götürüp, Record’ları da map olarak tutabiliriz.

Record’lar da ayrıca, map gibi genel veri yapılarıyla gösterilir. Bunun için heterojen map kullanılır. Heterojen map, farklı tipte veri tutarken; homojen map ise aynı tipte veri tutar.

Örneğin, JavaScript’te kitap örneğini şu şekilde rahatlıkla tutabiliriz.

Java’da biraz daha zor olsa da, benzer olarak şu şekilde yazabiliriz.

Bu durumda, nesne yaratmak için sınıfları kullanmak ve onların yapılandırıcılarını(constructor) kullanmak daha iyi diye düşünebilirsiniz. Record’ları map olarak tutmak, esneklik ve genelleştirebilirlik getirir ama güvenlikten biraz ödün veririz.

Örneğin, kitap listesini dönebileceğimiz, authorId’leri yerine yazar isimlerini döneceğimiz bir servisimiz olsun. İlk yapacağımız işlerden bir tanesi, BookInSearchResults gibi bir sınıf yaratmak olur. DOP’da ise verinin her farklı varyasyonu için yeni bir sınıf oluşturulmasına gerek duyulmaz.

Sonuç olarak elimizde şu tarz bir pazarlık durumu söz konusu olur. OOP’de güvenlik konusu daha önem arzederken, DOP’da diğer konular daha fazla önem arz eder.

Jenerik Fonksiyonlar ile Veri Manipülasyonu

Şu şekilde genel bir catalog verimizin olduğunu düşünelim.

Daha önce bahsettiğimiz, booksByIsbn ve authorsById map verilerimiz burada bulunuyor.

JavaScript’te bulunan(diğer dillerde de benzer alternatifler var) lodash kütüphanesi ile şu şekilde veri sorgulayabiliriz.

İlk parametremiz catalogData ile üzerinde sorgulama yapacağımız argümanı veririz, ikinci parametrede ise bilgi yoludur(information path). Bilgi yolu ile veriye, hangi ağaç dallarından ulaşabileceğimizi söyleriz.

get metodunu kendimiz de gerçekleyebiliriz. Çok karmaşık değil.

Java gibi statik-tipli bir dilde bu veriyi almak istediğimiz de, son aşamada casting(tip çevrimi) işleminden bunu geçirmemiz gerekir. Çünkü, veri olarak Map<String, Object> gibi heterojen bir map kullanmamız gerekirdi.

Performans bakımından düşünürsek, bir nesnenin altındaki veriye getTitle() gibi erişim, map üzerinden get('title') gibi erişimden daha hızlı olur ama map veri yapıları, yeteri kadar hızlı olduğundan, bu fark hissedilmez.

DOP’da, her türlü bilgi parçasını, bilgi yolu(information path) ve jenerik bir fonksiyonla alabilirsiniz.

Arama Sonuçlarını Hesaplamak

Daha önce bahsettiğimiz gibi, kitapla ilgili yapılan bir aramada şu bilgileri istiyoruz: isbn , title ve authorNames . Bunun için yeni BookInfo diye yeni bir record tanımlamış olsaydık, verisi şuna benzer olurdu.

Ama bunu Lodash._map fonksiyonu ile authorNames kısmını şöyle oluşturabiliriz.

Ve daha sonra bookInfo veri yapısını şöyle tamamlarız.

BookInfo recordumuz, title, isbn ve authorNames adında 3 tane alana sahiptir. Peki bunu koda bakmadan anlamanın bir yolu var mıdır? Maalesef, bunu ancak, data entity(veri varlığı) diagramına yazarak veya bookInfo fonksiyonuna dökümante ederek anlayabiliriz.

searchBooksByTitle fonksiyonunun geri kalanını yazarak arama işlevini tamamlayalım.

_.values fonksiyonu ile bir map veri yapısının değerleri liste haline getirilir. Örneğimizde, kitaplar düz liste haline getirilir. Daha sonra _.filter ile koşulumuza uyan veriler ile liste daraltılır. En sonunda _.map ile bookInfo verisi oluşturulur.

Bu fonksiyonu kullanarak sorguladığımız zaman, aşağıdaki sonucu elde ederiz.

Bahsettiğimiz konuları özetlersek,

  • DOP’da veri varlıklarını, jenerik veri yapıları(map veya list/dizi) ile göster.
  • Record’ları string map’ler olarak göster.
  • Map anahtarı olarak her zaman String kullan.
  • Homojen map’in değer alanları aynı tiptir.
  • Heterojen map’in değer alanları farklı tiptedir.
  • DOP’da, record’ları heterojen string map olarak tutarız.
  • Veri modelleri gösterirken, esneklik ve güvenlik arasında bir pazarlık olur.
  • DOP’da, her türlü veriyi, bilgi yolu(information path) ve jenerik bir fonksiyon ile alınabilir.

Bölüm 4: Durum(State) Yönetimi

--

--