Soyutlamalar (abstraction), nesne yönelimli dillerin üç temel taşından biri. Diğer ikisi kalıtım (inheritance) ve kapsülleme (encapsulation) ama onlardan bu yazıda bahsetmeyeceğiz.

Soyutlama yaparken çoğu zaman nasıl bir somutlama (concretion) yapacağımızı da biliriz. Örneğin telefon için bir soyut sınıf (abstract class) ya da arayüz (interface) yazacaksak:

<?php

interface Phone // Telefon
{
}

Bu arayüzü oluştururken aklımızda nasıl somutlamalar kullanacağımız da vardır:

<?php

class HomePhone implements Phone // Ev telefonu
{
}

class OfficePhone implements Phone // Ofis telefonu
{
}

Bu nedenle arayüzü, yani soyut sınıfımızı oluştururken, sadece somut sınıflarımızda kullanmamız gereken isimleri kullanma hatasına düşebiliriz. Halbuki bu hata, soyutlamanın esnekliğinin kaybolmasına yol açar.

Örnek

Başladığımız örnekten devam edelim. Ev ve ofis telefonlarını düşünerek aşağıdaki gibi bir telefon arayüzü tasarlayalım:

<?php

interface Phone
{
   public function getNumber(): int; // Numarayı al
   public function cableConnected(): bool; // Kablo bağlı mı?
   public function hasDialTone(): bool; // Çevir sesi var mı?
}

Yukarıdaki arayüz, ev de ofis telefonlarını düşündüğümüzde oldukça mantıklı. İki somutlama da birer telefon numarasına sahip. İkisinin de çalışıp çalışmadığını anlamak için kablolarının bağlı olup olmadığını öğrenmemiz gerek. İkisinde de arama yapmadan önce çevir sesi olup olmadığını bilmemiz önemli.

Peki ya üçüncü bir somutlama işin içine girerse ne olacak? Mesela cep telefonu. Telefon numarası dışındaki fonksiyonlar cep telefonuna uygulanabilecek şeyler değil. Cep telefonunun çalışıp çalışmadığını anlamak için kablonun takılı olmasına değil, şarjına bakmamız gerek. Arama yapabildiğini görmek içinse, bir baz istasyonuna bağlı mı onu bilmemiz gerekiyor.

Temizlik zamanı

Cep telefonu somutlamasını düşündüğümüz zaman, telefon arayüzündeki isimlendirmelerin doğru olmadığını görüyoruz. Arayüzdeki isimlendirmeler, başka somutlamalardan izler taşıyor; yani gerçekte soyut isimler kullanmıyor.

Gördüğümüz gibi, bir soyutlama üzerinde soyut isim kullanmadığımız zaman, bu soyutlama esnekliğini kaybediyor. Daha katı terimlerle konuşacak olursak, cep telefonunu kodumuza dahil edemiyoruz.

Peki soyutlamamızı, yani örneğimizdeki arayüzü düzeltseydik ve soyut isimler kullansaydık nasıl görünürdü?

<?php

interface Phone
{
   public function getNumber(): int; // Numarayı al
   public function isOn(): bool; // Açık mı?
   public function hasLine(): bool; // Hat var mı?
}

Telefon arayüzünün fonksiyonlarından getNumber‘ı değiştirmemize gerek kalmadı; çünkü tüm telefonların bir numarası olmak zorunda.

Öte yandan, cableConnected adlı fonksiyonumuzun adını isOn şeklinde düzelttik. Kablo, aslen bir somutlamaya işaret ediyor. Yalnızca kablolu telefonların bir kablosu olur. Öte yandan, telefonun açık olup olmaması daha soyut bir kavram. Bir ev veya ofis telefonu kablosu bağlıyken açık olabilecekken, bir cep telefonu eğer şarjı varsa açıktır.

Son olarak da, hasDialTone adlı fonksiyonumuzu hasLine olarak güncelledik. Çevir sesi, yalnızca kablolu telefonlarda olan bir özellik. Cep telefonlarında çevir sesi aramadan, istediğimiz numarayı tuşlayarak arama yapabiliyoruz. Fakat cep telefonlarının arama yapabilmesi için bir baz istasyonuyla iletişim kurabiliyor olması gerekiyor. Tüm telefonları düşünerek bir soyut kavram çıkaracak olursak, bunu telefonun hat alıp alamamasına bağlayabiliriz.

Telefon arayüzümüz şimdi gerçekten soyut bir hâle kavuştu. Sadece cep telefonu değil, uydu telefonu ya da aklınıza gelebilecek herhangi başka bir tip telefonu da bu arayüzü kullanarak kodlamamız artık mümkün.

Yorum Gönderin

Bir Cevap Yazın

%d blogcu bunu beğendi: