Araç Kiralama Servisi
Coddy'nin PHP Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası — ders 91 / 91.
Görev
KolayBir 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 birVehicleStatearayüzü tanımlayın. İki yöntem ekleyin:getStatus(): stringvecanRent(): bool. Ardından bu arayüzü uygulayan üç sınıf oluşturun:AvailableState—"Available"vetruedeğerlerini döndürürRentedState—"Rented"vefalsedeğerlerini döndürürMaintenanceState—"Maintenance"vefalsedeğerlerini döndürür
Vehicle.php— VehicleState dosyasını dahil edin.licensePlate(string, public readonly),brand(string, public readonly) vedailyRate(float, protected) için constructor promotion kullanan soyut birVehiclesınıfı oluşturun. Mevcut durumu, varsayılan olarakAvailableStateolacak şekilde özel (private) bir özellikte saklayın. Şunları uygulayın:getState(): VehicleState— mevcut durumu döndürürsetState(VehicleState $state): void— durumu değiştirirgetStatus(): string— durumungetStatus()yöntemine delege edercanRent(): bool— durumuncanRent()yöntemine delege ederabstract calculateCost(int $days): float— her araç tipi farklı şekilde hesaplama yapargetType(): string—static::classkullanarak 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öntemidailyRate * daysdöndürürMotorcycle— Vehicle sınıfını genişletir;calculateCost()yöntemidailyRate * days * 0.8(%20 indirim) döndürürVan— 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.php—id(int, public readonly) vename(string, public readonly) için constructor promotion kullanan birCustomersı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 yapargetRentalCount(): int— kiralama sayısını döndürürgetTotalSpent(): 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 birRentalsınıfı oluşturun.customer(Customer, public readonly),vehicle(Vehicle, public readonly),days(int, private) ve isteğe bağlı olarakmiles(int, private, varsayılan 0) için constructor promotion kullanın. Şunları uygulayın:calculateTotal(): float— eğer araç bir Van ise, millericalculateCost()yöntemine geçirin; aksi takdirde sadece günleri geçirincomplete(): 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 birRentalServicesınıfı oluşturun. Araçları, plaka ile indekslenmiş özel (private) bir dizide saklayın. Şunları uygulayın:addVehicle(Vehicle $vehicle): void— filoya ekleme yaparfindVehicle(string $plate): ?Vehicle— aracı veya null döndürürgetAvailableVehicles(): array—canRent()değeri true olan araçları döndürürrentVehicle(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ürsetMaintenance(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
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