Swift’te Protocols Nedir?
Protocols, genel mantığı itibari ile kodunuzu daha organize ve esnek hale getirmenize yardımcı olur. Yani bir işlevselliği veya davranışı tanımlayan bir tür kılavuz veya sözleşmedir. Başka bir deyişle, bir protokol, belirli bir davranışı veya özelliği içeren bir çerçevedir ve bu çerçeveyi uygulayan türler belirli davranışları veya özellikleri sunmalıdır. Protocols polimorfizmi destekler ve yeniden kullanılabilirlik ve kodun daha moduler ve değişime adapte olmasını sağlar. Protocoller bir class veya bir struct değildir. İçlerine verilen değişkenler ileride oluşturulacak bir class veya struct içinde olacağını söylüyoruz ama bu değişkenin asıl tutulduğu yer class ve struct içleridir.
Apple’ın Swift dökümantasyonunda Protocols için verdiği kısaca açıklama “Bir protokol, belirli bir göreve veya işlevsellik parçasına uyan yöntemlerin, özelliklerin ve diğer gereksinimlerin bir planını tanımlar. Protokol daha sonra bu gereksinimlerin gerçek bir uygulamasını sağlamak için bir class, struct veya enum tarafından benimsenebilir. Bir protokolün gereksinimlerini karşılayan herhangi bir türün o protokole uygun olduğu söylenir.
Uygun türlerin uygulaması gereken gereksinimleri belirlemeye ek olarak, bu gereksinimlerden bazılarını uygulamak veya uygun türlerin yararlanabileceği ek işlevleri uygulamak için bir protokolü genişletebilirsiniz.”
Swift protocol içinde { get set } gibi anahtar kelimeler almaktadır. get değeri okuma gibi işlemlerde, set ise değeri değiştirme gibi işlemlerde kullanılmaktadır. Bunların ikisini birlikte de kullanıp hem okuyup, yazabilir hemde değiştirebiliriz. Sadece get metodu kullanılan basit bir örnek ile anlatalım.
protocol Person {
var name: String { get }
var age: Int { get }
}
struct Student: Person {
var name: String
var age: Int
}
struct Teacher: Person {
var name: String
var age: Int
}
var student1 = Student(name: "Şükrü", age: 24)
var teacher1 = Teacher(name: "Ali", age: 45)
print("Öğrenci Bilgileri \(student1.name) \(student1.age)")
print("Öğretmen Bilgileri \(teacher1.name) \(teacher1.age)")
//Çıktısı
//Öğrenci Bilgileri Şükrü 24
//Öğretmen Bilgileri Ali 45
Farkındaysanız class yerine struct yapısını kullandık sebebi ise Apple bizim inheritance yapacaksak bunu class ile değil struct kullanmamızı istiyor. Ayrıca struct yapılarında inheritance yapısı yok. Bu nedenle struct yapısında direk protocol kullanıyoruz.
Ne demek istiyoruz bir örnekle anlatalım. Emekli diye bir class oluşturalım ve classı bir structan inherit etmeyi deneyelim ama tabii ki olmayacağını bilelim. Önceki örneğimize eklemedir.
class Retired: Person{
var name: String
var age: Int
init(name: String,age: Int) {
self.name = name
self.age = age
}
}
struct Teacher: Person, Retired{//Struct ın Emekli classını inherit edemeyeceği hatayı vermektedir.
var name: String
var age: Int
}
Eğer Emeklilik bilgisini eklemek istiyorsak altta verdiğimiz gibi eklemek mümkündür. Emekli olma bilgisini ayrı bir protocol ile ekleyebiliriz.
protocol Person {
var name: String { get }
var age: Int { get }
}
struct Student: Person {
var name: String
var age: Int
}
protocol Retired: Person{
var retired: Bool { get }
}
struct Teacher: Person, Retired{//Burada Retired ı da ekleyerek her öğretmenin emekli mi değil mi bilgisini de talep etmiş olduk.
var retired: Bool
var name: String
var age: Int
}
var student1 = Student(name: "Şükrü", age: 24)
var teacher1 = Teacher(retired: false, name: "Ali", age: 45)
var teacher2 = Teacher(retired: true, name: "Mehmet", age: 58)
print("Öğrenci Bilgileri \(student1.name) \(student1.age)")
print("Öğretmen Bilgileri \(teacher1.name) \(teacher1.age) Emekli: \(teacher1.retired)")
print("Öğretmen Bilgileri \(teacher2.name) \(teacher2.age) Emekli: \(teacher2.retired)")
//Çıktısı
//Öğrenci Bilgileri Şükrü 24
//Öğretmen Bilgileri Ali 45 Emekli: false
//Öğretmen Bilgileri Mehmet 58 Emekli: true
Peki öğretmenlerimizin Emeklilik durumlarında değişiklik olacak olursa bunu nasıl yapabiliriz? Bunu da eklediğimiz protocole set metodunu da ekleyerek değişiklik yapabiliriz.
protocol Person {
var name: String { get }
var age: Int { get }
}
struct Student: Person {
var name: String
var age: Int
}
protocol Retired: Person{
var retired: Bool { get set }//Burada set metodu ekleyerek düzenlenebilir hale getirdik.
}
struct Teacher: Person, Retired{
var retired: Bool
var name: String
var age: Int
}
var student1 = Student(name: "Şükrü", age: 24)
var teacher1 = Teacher(retired: false, name: "Ali", age: 45)
var teacher2 = Teacher(retired: true, name: "Mehmet", age: 58)
print("Öğrenci Bilgileri \(student1.name) \(student1.age)")
print("Öğretmen Bilgileri \(teacher1.name) \(teacher1.age) Emekli: \(teacher1.retired)")
print("Öğretmen Bilgileri \(teacher2.name) \(teacher2.age) Emekli: \(teacher2.retired)")
print("***********")
//Burada da retired durumunu true yaptık.
teacher1.retired = true
//Öğretmeni artık emekli ettik :)
print("Öğretmen Bilgileri \(teacher1.name) \(teacher1.age) Emekli: \(teacher1.retired)")
//Çıktısı
//Öğrenci Bilgileri Şükrü 24
//Öğretmen Bilgileri Ali 45 Emekli: false
//Öğretmen Bilgileri Mehmet 58 Emekli: true
//***********
//Öğretmen Bilgileri Ali 45 Emekli: true
Umarım anlaşılmıştır. Muhtemelen kafalarda ufak karışıklıklar olması çok normal anlamayanlar için söylüyorum. Rahat olun direk bir okuyuşta anlamamız zor zaten. Denemeniz ve protocols için projeler geliştirmeniz gerekmektedir. Bu projeler illa ki tam olarak kullanılacak aktif projeler amaçlı değil. Sadece öğreniminizi pekiştirmek için basit projeler. (Taşıtlar-Arabalar-Uçaklar, Hayvanlar gibi mesela)
Anlamanız için daha basit bir örnekte veriyorum. Bu örnekte Araba, Tank, Motor gibi taşıtları alıp protocol ile oluşturduk.
protocol Driveable {
func drive(speed: Int, model:String, whellsCount: Any)
}
struct Car: Driveable {
func drive(speed: Int, model: String, whellsCount: Any) {
print("Car Info:\n Hız:\(speed) Model:\(model) Teker Bilgisi:\(whellsCount)")
}
}
struct Tank: Driveable {
func drive(speed: Int, model: String, whellsCount: Any) {
print("Tank Info:\n Hız:\(speed) Model:\(model) Teker Bilgisi:\(whellsCount)")
}
}
struct Motorcycle: Driveable {
func drive(speed: Int, model: String, whellsCount: Any) {
print("Motorcycle Info:\n Hız:\(speed) Model:\(model) Teker Bilgisi:\(whellsCount)")
}
}
let car1 = Car()
car1.drive(speed: 100, model: "Togg", whellsCount: 4)
let tank1 = Tank()
tank1.drive(speed: 30, model: "Altay", whellsCount: "Paletli")
let motorcycle1 = Motorcycle()
motorcycle1.drive(speed: 80, model: "Yamaha", whellsCount: 2)
//Çıktısı
/* Car Info:
Hız:100 Model:Togg Teker Bilgisi:4
Tank Info:
Hız:30 Model:Altay Teker Bilgisi:Paletli
Motorcycle Info:
Hız:80 Model:Yamaha Teker Bilgisi:2 */
Umarım Protocols konusu anlaşılmıştır. Üst düzey bir bilgiye sahip değilim bu yüzden herhangi bir hatam veya yanlışım var ise düzenleyebilirim. İletişim : LinkedIn
Şimdiden herkese iyi çalışmalar.. Şimdilik görüşmek üzere..👋🏻👋🏻