Menu
Coddy logo textTech

Kompozisyon

Coddy'nin Rust Journey'sinin Object Oriented Programming bölümünün bir parçası — ders 55 / 61.

Pek çok nesne yönelimli dil, türler arasında işlevselliği paylaşmak için büyük ölçüde kalıtıma dayanır. Rust farklı bir yaklaşım benimser: bileşim. Bir ebeveynden davranış devralmak yerine, diğer türleri alanlar olarak dahil ederek karmaşık türler oluşturursunuz.

Bir arabayı modellediğinizi düşünün. Temel bir Vehicle sınıfı oluşturup ondan miras almak yerine, bir Car nesnesini daha küçük, odaklanmış bileşenlerden oluşturursunuz:

struct Engine {
    horsepower: u32,
}

struct Wheels {
    count: u8,
    diameter: f32,
}

struct Car {
    engine: Engine,
    wheels: Wheels,
    brand: String,
}

Car, Engine veya Wheels sınıflarından miras almaz; onlara sahiptir. Bu "has-a" (sahip olma) ilişkisi kompozisyondur (composition). İç bileşenlere alanları (fields) üzerinden erişirsiniz ve metotlarını doğrudan çağırabilirsiniz:

impl Engine {
    fn start(&self) {
        println!("Engine with {} HP started!", self.horsepower);
    }
}

impl Car {
    fn start(&self) {
        self.engine.start();  // İç bileşene devret (Delegate)
    }
}

Bu desen, her bir struct'ın tek bir sorumluluğa odaklanmasını sağlar. Motorların çalışma şeklini mi değiştirmeniz gerekiyor? Sadece Engine struct'ını değiştirin. Wheels'ı bir motosiklet için yeniden mi kullanmak istiyorsunuz? Onu yeni bir struct'a dahil etmeniz yeterli. Kompozisyon (Composition), kalıtımın (inheritance) genellikle oluşturduğu sıkı bağlılık (tight coupling) olmadan size esneklik sağlar.

challenge icon

Görev

Kolay

Kompozisyon kullanarak bir bilgisayar sistemi inşa edelim! Tek bir devasa struct oluşturmak yerine, bir Computer yapısını daha küçük ve odaklanmış bileşenlerden —bir CPU ve Memory— oluşturacaksınız. Her bileşen kendini nasıl tanımlayacağını bilecek ve Computer bu görevi kendi parçalarına devredecek.

Kodunuzu üç dosya halinde düzenleyeceksiniz:

  • cpu.rs: İki genel (public) alana sahip bir genel CPU struct'ı tanımlayın: çekirdek sayısı için cores (u32) ve saat hızı için speed_ghz (f32). CPU'yu {cores}-core @ {speed_ghz}GHz formatında tanımlayan bir String döndüren specs metodunu ekleyin.
  • memory.rs: Bellek boyutu için genel bir size_gb (u32) alanına sahip genel bir Memory struct'ı tanımlayın. {size_gb}GB RAM formatında bir String döndüren bir specs metodu ekleyin.
  • main.rs: Her iki modülü de dahil edin ve CPU tipinde bir cpu alanına ve Memory tipinde bir memory alanına sahip olan genel bir Computer struct'ı oluşturun. Computer üzerinde, bileşenlerine delege eden ve tam sistem özelliklerini yazdıran bir system_info metodu uygulayın. Bir Computer oluşturmak ve bilgilerini görüntülemek için sağlanan girdileri kullanın.

system_info metodu şunu yazdırmalıdır:

System: {cpu_specs} | {memory_specs}

Örneğin, 8, 3.5 ve 16 girdileriyle:

System: 8-core @ 3.5GHz | 16GB RAM

Ve 4, 2.8 ve 32 girdileriyle:

System: 4-core @ 2.8GHz | 32GB RAM

Üç girdi alacaksınız: CPU çekirdekleri (u32 olarak ayrıştırın), CPU hızı (f32 olarak ayrıştırın) ve bellek boyutu (u32 olarak ayrıştırın).

Kopya kağıdı

Rust, türler arasında işlevselliği paylaşmak için kalıtım yerine kompozisyon kullanır. Karmaşık türleri, diğer türleri alanlar (fields) olarak dahil ederek oluşturur ve bir "sahip olma" (has-a) ilişkisi kurarsınız.

Temel Kompozisyon

Daha küçük, odaklanmış struct'lar tanımlayın ve bunları daha büyük olanlarda birleştirin:

struct Engine {
    horsepower: u32,
}

struct Wheels {
    count: u8,
    diameter: f32,
}

struct Car {
    engine: Engine,
    wheels: Wheels,
    brand: String,
}

Bileşenlere Delege Etme

İç bileşenlere alanları üzerinden erişin ve metotlarını çağırın:

impl Engine {
    fn start(&self) {
        println!("Engine with {} HP started!", self.horsepower);
    }
}

impl Car {
    fn start(&self) {
        self.engine.start();  // İç bileşene delege et
    }
}

Kompozisyon, her struct'ın tek bir sorumluluğa odaklanmasını sağlayarak, sıkı bağlılık (tight coupling) olmadan esneklik sağlar.

Kendin dene

mod cpu;
mod memory;

use cpu::CPU;
use memory::Memory;

// TODO: İki genel (public) alana sahip genel bir Computer yapısı (struct) tanımlayın:
// - cpu: CPU
// - memory: Memory

// TODO: Computer üzerinde şunları yapan bir system_info metodu uygulayın:
// - cpu.specs() ve memory.specs() metodlarına yönlendirme yapan
// - Şunu yazdıran: System: {cpu_specs} | {memory_specs}

fn main() {
    let mut input = String::new();
    std::io::stdin().read_line(&mut input).expect("Failed to read line");
    let cores: u32 = input.trim().parse().expect("Invalid number");
    
    input.clear();
    std::io::stdin().read_line(&mut input).expect("Failed to read line");
    let speed_ghz: f32 = input.trim().parse().expect("Invalid number");
    
    input.clear();
    std::io::stdin().read_line(&mut input).expect("Failed to read line");
    let size_gb: u32 = input.trim().parse().expect("Invalid number");
    
    // TODO: Ayrıştırılmış girdileri kullanarak CPU ve Memory örnekleri (instances) oluşturun
    
    // TODO: CPU ve Memory ile bir Computer örneği (instance) oluşturun
    
    // TODO: Sonucu yazdırmak için bilgisayar üzerinde system_info() metodunu çağı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.

Object Oriented Programming bölümündeki tüm dersler