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 startedCar 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.
Görev
KolayBir 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 birProcessorsı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 birgetSpecs()metodu ekleyin.Memory.php— RAM'i temsil eden birMemorysınıfı oluşturun. GB cinsinden özel bir$size(integer) tanımlamak için constructor promotion kullanın."[size]GB RAM"döndüren birgetCapacity()metodu ekleyin.main.php— Her iki bileşen dosyasını dahil edin ve kompozisyon kullanan birComputersınıfı oluşturun.Computerşunları yapmalıdır:- Bir
Processornesnesini ve birMemorynesnesini ö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 birdescribe()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
Computeroluşturun vedescribe()metodunu çağırmanın sonucunu yazdırın.- Bir
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
?>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
1OOP Temelleri
Harici DosyalarOOP'ye GirişSınıflar ve Nesneler$this Anahtar KelimesiMetotlarÖzelliklerYapıcı Metot (__construct)Yıkıcı Metot (__destruct)Özet - Basit Hesap Makinesi4Kalıtım
Temel Kalıtımparent:: Anahtar KelimesiMetot Geçersiz Kılmafinal Anahtar KelimesiSoyut SınıflarÖzet - Çalışan Hiyerarşisi7Kapsülleme
Public, Protected, PrivateErişim Belirleyicilere Derinlemesine BakışGetter ve Setter MetotlarıBilgi GizlemeConstructor Promotion (8.0)Özet - Öğrenci Kayıt Sistemi10İleri Düzey OOP Kavramları
Kompozisyon vs KalıtımDependency InjectionAnonim SınıflarEnum'lar (PHP 8.1)Fiber'lar (PHP 8.1)Nesne Klonlama: Derinlemesine İncelemeGenerator'lar ve Iterator'lar13Tasarım Kalıpları Bölüm 2
Komut KalıbıAdaptör KalıbıDekoratör KalıbıŞablon Metot KalıbıDurum KalıbıKompozit KalıbıRepository Kalıbı2İsim Alanları ve Autoloading
İsim Alanlarına Girişuse Anahtar KelimesiPSR-4 Autoloading StandartıComposer AutoloaderÖzet - Düzenli Proje5Arayüzler ve Sözleşmeler
Arayüzlere GirişArayüzleri UygulamaBirden Fazla Arayüz UygulamaArayüz vs Soyut SınıfArayüzler ile Tip BelirlemeÖzet - Şekil Hesaplayıcı8Sihirli Metotlar
Sihirli Metotlara Giriş__toString & __debugInfo__get, __set, __isset, __unset__call & __callStatic__clone & Nesne Klonlama__serialize & __unserializeÖzet - Özel Koleksiyon3Sınıf Özellikleri
Örnek ve Statik ÖzelliklerSınıflarda SabitlerStatik Metotlar ve ÖzelliklerPrivate ve Protected ÖzelliklerReadonly Özellikler (PHP 8.1)Özet - Banka Hesabı Yöneticisi6Çok Biçimlilik
Metot Geçersiz Kılmaya Yeniden BakışArayüzler ile Çok BiçimlilikType Hinting ve Union TypesLate Static BindingÖzet - Ödeme İşlemcisi9Trait'ler
Trait'lere GirişÇoklu Trait KullanımıTrait Çakışma ÇözümüTrait'lerde Soyut MetotlarTrait'ler ve Kalıtım12Tasarım Kalıpları Bölüm 1
Tasarım Kalıplarına GirişSingleton KalıbıFactory KalıbıObserver KalıbıStrategy Kalıbı15Final Meydan Okumaları
E-Öğrenme PlatformuBankacılık SistemiOyun Karakteri GeliştirmeAraç Kiralama Servisi