Menu
Coddy logo textTech

Kompozisyon vs Kalıtım

Coddy'nin PHP Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası — ders 56 / 91.

Önceki bölümde, kalıtım bir "is-a" ilişkisi kurarken trait'lerin bir "has-a" yeteneği sağladığını öğrendiniz. Kompozisyon, karmaşık nesneleri daha basit olanlardan inşa ederek ve onları kalıtım almak yerine özellikler olarak saklayarak "has-a" kavramını daha ileriye taşır.

Kalıtım ile bir Car, Vehicle sınıfını genişletebilir. Kompozisyon ile bir Car, bir Engine nesnesi içerir:

<?php
class Engine {
    public function start(): string {
        return "Engine started";
    }
}

class Car {
    private Engine $engine;
    
    public function __construct() {
        $this->engine = new Engine();
    }
    
    public function start(): string {
        return $this->engine->start();
    }
}

$car = new Car();
echo $car->start();

Çıktı:

Engine started

Car sınıfı Engine sınıfından miras almaz; ona sahiptir. Bu yaklaşım önemli avantajlar sunar: motoru farklı bir uygulama ile değiştirebilirsiniz, sınıflar gevşek bağlı kalır ve derin miras almanın yarattığı katı hiyerarşilerden kaçınırsınız.

OOP'de yaygın bir kural "kalıtım yerine kompozisyonu tercih et" ilkesidir. Kalıtım, gerçek tür hiyerarşileri için iyi çalışır (bir Dog gerçekten bir Animal'dır), ancak kompozisyon, bağımsız parçalardan işlevsellik birleştirirken öne çıkar. Birden fazla nesneyi birleştirebilir, bunları çalışma zamanında değiştirebilir ve bileşenleri yalıtılmış olarak test edebilirsiniz.

Bir sonraki ders, nesnelerin bağımlılıklarını nasıl aldığını kontrol ederek doğrudan kompozisyon (composition) üzerine inşa edilen bağımlılık enjeksiyonunu (dependency injection) ele almaktadır.

challenge icon

Görev

Kolay

Bir Computer nesnesinin diğer sınıflardan miras almak yerine ayrı bileşen nesnelerinden birleştirildiği kompozisyon (composition) yöntemini kullanarak bir bilgisayar sistemi oluşturalım. Bu, kompozisyonun daha basit ve bağımsız parçalardan nasıl karmaşık nesneler oluşturmanıza olanak tanıdığını gösterir.

Kodunuzu üç dosya halinde düzenleyeceksiniz:

  • Processor.php — Bir CPU'yu temsil eden bir Processor sınıfı oluşturun. Özel bir $model (string) ve özel bir $cores (integer) tanımlamak için constructor promotion kullanın. "[model] ([cores] cores)" döndüren bir getSpecs() metodu ekleyin.
  • Memory.php — RAM'i temsil eden bir Memory sınıfı oluşturun. GB cinsinden özel bir $size (integer) tanımlamak için constructor promotion kullanın. "[size]GB RAM" döndüren bir getCapacity() metodu ekleyin.
  • main.php — Her iki bileşen dosyasını dahil edin ve kompozisyon kullanan bir Computer sınıfı oluşturun. Computer şunları yapmalıdır:
    • Bir Processor nesnesini ve bir Memory nesnesini özel özellikler (private properties) olarak saklamalıdır
    • Yapıcısında (constructor) bir işlemci modeli, çekirdek sayısı ve bellek boyutu kabul etmelidir
    • Yapılandırma sırasında bileşen nesnelerini dahili olarak oluşturmalıdır
    • "Computer with [processor specs] and [memory capacity]" döndüren bir describe() metoduna sahip olmalıdır

    Üç girdi alacaksınız: bir işlemci modeli, çekirdek sayısı ve GB cinsinden bellek boyutu. Bu özelliklere sahip bir Computer oluşturun ve describe() metodunu çağırmanın sonucunu yazdırın.

Computer sınıfının Processor veya Memory sınıflarını genişletmediğine (extend), aksine onları içerdiğine dikkat edin. Kompozisyon yoluyla kurulan bu "has-a" (sahip olma) ilişkisi, her bileşeni bağımsız ve yeniden kullanılabilir tutarken, Computer sınıfının gerektiğinde parçalarına görev devretmesine (delegate) olanak tanır.

Kopya kağıdı

Kompozisyon (Bileşim), karmaşık nesneleri onlardan miras almak yerine onları özellik olarak saklayarak daha basit olanlardan oluşturur. Bu, bir sınıfın diğer sınıfların örneklerini içerdiği bir "has-a" (sahip olma) ilişkisi oluşturur.

Temel kompozisyon örneği:

<?php
class Engine {
    public function start(): string {
        return "Engine started";
    }
}

class Car {
    private Engine $engine;
    
    public function __construct() {
        $this->engine = new Engine();
    }
    
    public function start(): string {
        return $this->engine->start();
    }
}

Car sınıfı Engine sınıfından miras almaz; ona sahiptir. Bu, sınıfları gevşek bağlı (loosely coupled) tutar ve katı miras hiyerarşilerinden kaçınır.

Miras yerine kompozisyonu tercih edin: Miras, gerçek tür hiyerarşileri için (bir Dog bir Animal'dır) iyi çalışır, ancak kompozisyon, bağımsız parçalardan işlevsellik birleştirirken öne çıkar. Birden fazla nesneyi birleştirebilir, çalışma zamanında değiştirebilir ve bileşenleri yalıtılmış olarak test edebilirsiniz.

Kendin dene

<?php
require_once 'Processor.php';
require_once 'Memory.php';

class Computer
{
    // TODO: Processor ve Memory nesnelerini saklamak için özel (private) özellikleri tanımlayın

    // TODO: Kurucu metod (constructor) işlemci modelini, çekirdek sayısını ve bellek boyutunu kabul etmeli
    // ve bileşen nesnelerini dahili olarak oluşturmalıdır
    public function __construct()
    {
        // TODO: Processor ve Memory nesnelerini oluşturun ve saklayın
    }

    // TODO: "Computer with [processor specs] and [memory capacity]" döndüren
    // describe() metodunu uygulayın
    public function describe(): string
    {
        // TODO: Bileşen nesnelerine delege edin ve formatlanmış dizeyi döndürün
    }
}

// Girdiyi oku
$processorModel = trim(fgets(STDIN));
$cores = intval(fgets(STDIN));
$memorySize = intval(fgets(STDIN));

// TODO: Verilen özelliklerle bir Computer oluşturun ve describe() sonucunu yazdırın

?>
quiz iconKendini test et

Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.

Nesne Yönelimli Programlama bölümündeki tüm dersler