Menu
Coddy logo textTech

Araç Kiralama Servisi

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

challenge icon

Görev

Kolay

Bir araç filosunu yöneten, müşteri kiralamalarını takip eden ve araç tipine göre fiyatlandırma hesaplayan bir Araç Kiralama Servisi sistemi inşa edelim. Bu kapsamlı meydan okuma; kalıtım (inheritance), arayüzler (interfaces), kapsülleme (encapsulation) ve State (Durum) desenini bir araya getirerek gerçekçi bir kiralama işletmesi uygulaması oluşturmanızı sağlar.

Kodunuzu yedi dosya halinde düzenleyeceksiniz:

  • VehicleState.php — Bir aracın içinde bulunabileceği farklı durumları temsil eden bir VehicleState arayüzü tanımlayın. İki yöntem ekleyin: getStatus(): string ve canRent(): bool. Ardından bu arayüzü uygulayan üç sınıf oluşturun:
    • AvailableState"Available" ve true değerlerini döndürür
    • RentedState"Rented" ve false değerlerini döndürür
    • MaintenanceState"Maintenance" ve false değerlerini döndürür
  • Vehicle.php — VehicleState dosyasını dahil edin. licensePlate (string, public readonly), brand (string, public readonly) ve dailyRate (float, protected) için constructor promotion kullanan soyut bir Vehicle sınıfı oluşturun. Mevcut durumu, varsayılan olarak AvailableState olacak şekilde özel (private) bir özellikte saklayın. Şunları uygulayın:
    • getState(): VehicleState — mevcut durumu döndürür
    • setState(VehicleState $state): void — durumu değiştirir
    • getStatus(): string — durumun getStatus() yöntemine delege eder
    • canRent(): bool — durumun canRent() yöntemine delege eder
    • abstract calculateCost(int $days): float — her araç tipi farklı şekilde hesaplama yapar
    • getType(): stringstatic::class kullanarak sınıf adını döndürür
  • Vehicles.php — Vehicle dosyasını dahil edin. Üç somut araç sınıfı oluşturun:
    • Car — Vehicle sınıfını genişletir; calculateCost() yöntemi dailyRate * days döndürür
    • Motorcycle — Vehicle sınıfını genişletir; calculateCost() yöntemi dailyRate * days * 0.8 (%20 indirim) döndürür
    • Van — Ek bir $mileageRate (float) parametresi ile Vehicle sınıfını genişletir; calculateCost(int $days, int $miles = 0) yöntemi (dailyRate * days) + (mileageRate * miles) döndürür
  • Customer.phpid (int, public readonly) ve name (string, public readonly) için constructor promotion kullanan bir Customer sınıfı oluşturun. Kiralama geçmişini özel (private) bir dizide takip edin. Şunları uygulayın:
    • addRental(string $vehiclePlate, float $cost): void — geçmişe ekleme yapar
    • getRentalCount(): int — kiralama sayısını döndürür
    • getTotalSpent(): float — tüm kiralama maliyetlerinin toplamını döndürür
  • Rental.php — Vehicle ve Customer dosyalarını dahil edin. Bir müşteriyi bir araca bağlayan bir Rental sınıfı oluşturun. customer (Customer, public readonly), vehicle (Vehicle, public readonly), days (int, private) ve isteğe bağlı olarak miles (int, private, varsayılan 0) için constructor promotion kullanın. Şunları uygulayın:
    • calculateTotal(): float — eğer araç bir Van ise, milleri calculateCost() yöntemine geçirin; aksi takdirde sadece günleri geçirin
    • complete(): string — toplamı hesaplar, müşterinin geçmişine ekler, aracı AvailableState durumuna getirir ve "Rental completed: $[total]" (2 ondalık basamak) döndürür
  • RentalService.php — Rental ve Vehicles dosyalarını dahil edin. Filoyu yöneten bir RentalService sınıfı oluşturun. Araçları, plaka ile indekslenmiş özel (private) bir dizide saklayın. Şunları uygulayın:
    • addVehicle(Vehicle $vehicle): void — filoya ekleme yapar
    • findVehicle(string $plate): ?Vehicle — aracı veya null döndürür
    • getAvailableVehicles(): arraycanRent() değeri true olan araçları döndürür
    • rentVehicle(Customer $customer, string $plate, int $days, int $miles = 0): string|Rental — araç bulunamazsa "Vehicle not found" döndürür; müsait değilse "Vehicle is not available" döndürür; aksi takdirde aracı RentedState durumuna getirir ve yeni bir Rental nesnesi döndürür
    • setMaintenance(string $plate): string — aracı MaintenanceState durumuna getirir; "[plate] set to maintenance" veya "Vehicle not found" döndürür
  • main.php — RentalService ve Customer dosyalarını dahil edin. Üç girdi alacaksınız: filo verisi (JSON), müşteri verisi (JSON) ve işlemler (JSON).

    Filo JSON formatı:

    [{"type": "car", "plate": "CAR-001", "brand": "Toyota", "rate": 50}, {"type": "van", "plate": "VAN-001", "brand": "Ford", "rate": 80, "mileage_rate": 0.25}]

    Müşteri JSON formatı:

    {"id": 1, "name": "Alice"}

    İşlemler JSON formatı:

    [{"op": "available"}, {"op": "rent", "plate": "CAR-001", "days": 3}, {"op": "complete", "plate": "CAR-001"}, {"op": "maintenance", "plate": "VAN-001"}, {"op": "customer_stats"}]

    Kiralama servisini oluşturun, tüm araçları filoya ekleyin ve müşteriyi oluşturun. Aktif kiralamaları plaka bazında takip edin. Her işlemi işleyin:

    • "available""Available vehicles: [count]" yazdırın
    • "rent" — Aracı kiralayın; başarılı olursa Rental nesnesini saklayın ve "Rented [plate] for [days] days" yazdırın; eğer Van ise işlemdeki milleri dahil edin; aksi takdirde hata mesajını yazdırın
    • "complete" — O plaka için saklanan kiralamayı tamamlayın; sonucu yazdırın
    • "maintenance"setMaintenance() sonucunu yazdırın
    • "status" — Verilen plaka için "[plate]: [status]" yazdırın
    • "customer_stats""[name]: [count] rentals, $[total] spent" (2 ondalık basamak) yazdırın

    Her sonucu yeni bir satıra yazdırın.

Bu sistem, State deseninin karmaşık koşullu ifadeler olmadan araç müsaitliğini nasıl zarifçe yönettiğini, kalıtımın polimorfik fiyatlandırma ile nasıl temiz bir araç hiyerarşisi oluşturduğunu ve kapsüllemenin iş akışı boyunca kiralama verilerinin bütünlüğünü nasıl koruduğunu göstermektedir.

Kendin dene

<?php

require_once 'RentalService.php';
require_once 'Customer.php';

// Girdileri oku
$fleetJson = trim(fgets(STDIN));
$customerJson = trim(fgets(STDIN));
$operationsJson = trim(fgets(STDIN));

// JSON verilerini ayrıştır
$fleetData = (array)json_decode($fleetJson, true);
$customerData = (array)json_decode($customerJson, true);
$operations = (array)json_decode($operationsJson, true);

// TODO: RentalService örneği oluştur

// TODO: Türe göre tüm araçları filoya ekle:
// - "car" -> new Car(plate, brand, rate)
// - "motorcycle" -> new Motorcycle(plate, brand, rate)
// - "van" -> new Van(plate, brand, rate, mileage_rate)

// TODO: customerData'dan Customer örneği oluştur

// TODO: Aktif kiralamaları plakaya göre takip etmek için dizi oluştur
$activeRentals = [];

// TODO: Her bir işlemi işle ve sonuçları yazdır:
// - "available": "Available vehicles: [count]" yazdır
// - "rent": Aracı kirala, başarılıysa Rental nesnesini sakla, sonucu yazdır
// - "complete": Kiralamayı tamamla, sonucu yazdır
// - "maintenance": Bakıma al, sonucu yazdır
// - "status": "[plate]: [status]" yazdır
// - "customer_stats": "[name]: [count] rentals, $[total] spent" yazdır

foreach ($operations as $op) {
    $operation = (array)$op;
    $opType = $operation['op'];
    
    // TODO: Her bir işlem türünü ele al
    switch ($opType) {
        case 'available':
            // TODO: Mevcut araç sayısını yazdır
            break;
        case 'rent':
            // TODO: Aracı kirala ve sonucu yazdır
            break;
        case 'complete':
            // TODO: Kiralamayı tamamla ve sonucu yazdır
            break;
        case 'maintenance':
            // TODO: Bakıma al ve sonucu yazdır
            break;
        case 'status':
            // TODO: Araç durumunu yazdır
            break;
        case 'customer_stats':
            // TODO: Müşteri istatistiklerini yazdır
            break;
    }
}

?>

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