Swift Generics: Az Kod, Çok İş!

iOS dünyasında Generics mekanizmasının ne anlama geldiğini, ne işe yaradığını öğrenecek ve artık daha iyi kod yazacaksınız. 💻

 

Generics Nedir?

Generics (Jenerikler) veri türlerinden bağımsız olarak temiz ve çok amaçlı kod yazmamızı sağlayan önemli yapı taşlarındandır.

 

Ne İşe Yarar?

Objective C ile 2005 yılında hayatımıza giren Generics, bir şablon yapısı oluşturarak farklı veri türleri için aynı fonksiyonu kullanmamıza olanak sağlar. Böylece code duplication yapmamızı önler ve yeniden kullanılabilir kod parçaları ortaya çıkar.

Aslında generics konseptini bilmesek bile ilk Swift öğrenmeye başladığımızdan beri bunu kullanıyoruz. Örneğin, Swift’in built-in sınıflarından olan Array bir generic dir.

Generic fonksiyonlar farklı veri türleri için ayrı ayrı metodlar oluşturmamızı engeller demiştik. Peki bunu nasıl yapıyor? Bunu örnekler ile açıklayalım.

 

Örnekler

Yemek listesini tuttuğumuz bir String array olsun.

Parametre olarak verdiğimiz yemeğin indeksini bulmak istiyorsak şöyle bir metod yazabiliriz:

 

Projenin farklı bir yerinde Integer türünde bir array elemanının indeksini bulmak istediğimizde ise yukarıdakine çok benzer olarak şöyle bir metod yazardık:

 

Fakat bu yöntem DRY prensibine aykırıdır. Sırf metod parametresi String iken Integer oldu diye aynı fonksiyondan iki kere yazmanın anlamı yok.

Hadi bu fonksiyonu generic yapalım!

Normalde parametre olarak verdiğimiz verinin türünü belirtmemiz gerekir fakat generic bir fonksiyon yapıyorsak verinin türü ile işimiz yok. Yalnızca bir placeholder name belirteceğiz. Bu herhangi bir harf olabilir.

 

Dikkat etmemiz gereken iki şey var:

Birincisi, <> içinde belirtiğimiz karakter ile generic kullanacağımız parametrenin türü aynı olmalı.

İkincisi, “T” ismindeki generic operand ının türü belli değil; her şey olabilir. Örnekte Comparable protokolünü implement ettik çünkü iki değişkenin birbirine olan eşitliğini kontrol edeceksek değişkenin türlerini bilmesek bile en azından bir şey ile karşılaştırılabilir olduğunu derleyeciye söylemek gerekiyor. Eğer <T> şeklinde bıraksaydık şöyle bir hata alacaktık:

 

Class Örneği

Generic ler framework ve kütüphanelerde sıkça kullanılan yapılardır. Sebebi ise yeniden kullanılabilir sınıflar ve API istekleri yapan fonksiyonlar yaratabilmektir.

Örneğin sınıfları

şeklinde oluşturmak yerine,

şeklinde tek bir generic sınıf yazmak bazı durumlarda daha mantıklı olabilir.

Tabiki generic sınıflar sadece framework için değil; uygulama tarafında da pekala yazılabilir.

 

Framework Oluşturmak hakkında daha fazla bilgi almak için bu yazıya göz atabilirsiniz.

 

 

Bir de API çağırmak ile ilgili generic fonksiyon örneği yapalım…

 

API Örneği

Şimdi iki adet web servisine istek atan fonksiyon yazacağız ve bunları tek bir generic fonksiyona dönüştürebiliyor muyuz diye bakacağız.

 

Gördüğünüz gibi web servisine istek attık ve başarılı olursa Post türündeki listeyi doldurduk. Model mapleme işini de JSONDecoder() a yaptırdık.

 

 

JSON parse etme ile ilgili şu yazıma bakmanızı tavsiye ederim:

 

 

Başka bir fonksiyonda ise kullanıcının bilgilerini almak için istek atalım…

 

Bu iki fonksiyon da farklı endpointe istek atıyor ve callback leri farklı veri türü return ediyor olsada temelde çok benzer işi yapıyorlar. Bu nedenle bu tip bir isteği generic yapmayı düşünebiliriz.

Fonksiyonu şöyle değiştirsek nasıl olur?

İstek attığı endpoint i parametre olarak versek,

sonra da callback in return ettiği veri türünü generic yapsak…

Oldu sanki?

Evet oldu.

Farkettiyseniz örnekte “T” Decodable protokolünü implement ediyor. Eğer JSON parse işlemini JSONDecoder ile yapmak istiyorsanız kullandığınız model Codable protokolünü implement etmesi gerekir. Burada kullandığımız generic datanın ne olacağını kestiremiyoruz çünkü türü belli değil. Ama en azından JSONDecoder ın mapping işlemini yapacağı bir tür olduğunu biliyoruz. Bu nedenle <T: Decodable> ifadesini kullandık.

Generic fonksiyon yazdık. Peki nasıl kullanacağız?

veya,

şeklinde kullanabiliriz.

Callback yaptığımız verinin türünü bizim vermemiz gerekiyor. Hangi URL ye istek attığımızı biliyorsak, hangi türde bir veri beklediğimizi de biliriz herhalde değil mi? 🙂

 

Özet

Özet olarak generic ler;

  • Veri türlerinden bağımsız olarak temiz ve çok amaçlı kod yazmamızı sağlayan önemli yapı taşlarındandır.
  • Code duplication yapmamızı önler.
  • DRY prensibini uygulamamızı sağlar.
  • Sınıflar ve fonksiyonlar için kullanışlıdır.
  • Framework ve kütüphanelerde sıkça görülür.