Data-Oriented Programming(DOP) — 3-Temel Veri Manipülasyonu
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ğerlerinAuthor
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
…