Menu
CoddyTech

Layanan Penyewaan Kendaraan

Termasuk bagian Pemrograman Berorientasi Objek dalam perjalanan PHP di Coddy. Pelajaran 91 dari 91.

challenge icon

Tantangan

Mudah

Mari kita bangun sistem Layanan Penyewaan Kendaraan yang mengelola armada kendaraan, melacak penyewaan pelanggan, dan menghitung harga berdasarkan jenis kendaraan. Tantangan menyeluruh ini menggabungkan inheritance, interface, enkapsulasi, dan pola State untuk membuat aplikasi bisnis penyewaan yang realistis.

Kamu akan mengatur kodemu dalam tujuh file:

  • VehicleState.php: Definisikan interface VehicleState yang mewakili berbagai state yang dapat dimiliki kendaraan. Sertakan dua method: getStatus(): string dan canRent(): bool. Lalu buat tiga class yang mengimplementasikan interface ini:
    • AvailableState: mengembalikan "Available" dan true
    • RentedState: mengembalikan "Rented" dan false
    • MaintenanceState: mengembalikan "Maintenance" dan false
  • Vehicle.php: Sertakan file VehicleState. Buat class abstrak Vehicle dengan promosi constructor untuk licensePlate (string, public readonly), brand (string, public readonly), dan dailyRate (float, protected). Simpan state saat ini dalam property private, dengan nilai awal AvailableState. Implementasikan:
    • getState(): VehicleState: mengembalikan state saat ini
    • setState(VehicleState $state): void: mengubah state
    • getStatus(): string: meneruskan pemanggilan ke getStatus() milik state
    • canRent(): bool: meneruskan pemanggilan ke canRent() milik state
    • abstract calculateCost(int $days): float: setiap jenis kendaraan menghitung biaya dengan cara berbeda
    • getType(): string: mengembalikan nama class menggunakan static::class
  • Vehicles.php: Sertakan file Vehicle. Buat tiga class kendaraan konkret:
    • Car: mewarisi Vehicle; calculateCost() mengembalikan dailyRate * days
    • Motorcycle: mewarisi Vehicle; calculateCost() mengembalikan dailyRate * days * 0.8 (diskon 20%)
    • Van: mewarisi Vehicle dengan parameter tambahan $mileageRate (float); calculateCost(int $days, int $miles = 0) mengembalikan (dailyRate * days) + (mileageRate * miles)
  • Customer.php: Buat class Customer dengan promosi constructor untuk id (int, public readonly) dan name (string, public readonly). Lacak riwayat penyewaan dalam array private. Implementasikan:
    • addRental(string $vehiclePlate, float $cost): void: menambahkan data ke riwayat
    • getRentalCount(): int: mengembalikan jumlah penyewaan
    • getTotalSpent(): float: mengembalikan jumlah semua biaya penyewaan
  • Rental.php: Sertakan file Vehicle dan Customer. Buat class Rental yang menghubungkan pelanggan dengan kendaraan. Gunakan promosi constructor untuk customer (Customer, public readonly), vehicle (Vehicle, public readonly), days (int, private), dan miles opsional (int, private, nilai awal 0). Implementasikan:
    • calculateTotal(): float: jika kendaraan adalah Van, teruskan miles ke calculateCost(); jika tidak, teruskan days saja
    • complete(): string: menghitung total, menambahkan data ke riwayat pelanggan, mengatur state kendaraan ke AvailableState, lalu mengembalikan "Rental completed: $[total]" (2 angka desimal)
  • RentalService.php: Sertakan file Rental dan Vehicles. Buat class RentalService yang mengelola armada. Simpan kendaraan dalam array private yang diindeks berdasarkan nomor pelat. Implementasikan:
    • addVehicle(Vehicle $vehicle): void: menambahkan kendaraan ke armada
    • findVehicle(string $plate): ?Vehicle: mengembalikan kendaraan atau null
    • getAvailableVehicles(): array: mengembalikan kendaraan yang memiliki nilai canRent() true
    • rentVehicle(Customer $customer, string $plate, int $days, int $miles = 0): string|Rental: jika kendaraan tidak ditemukan, kembalikan "Vehicle not found"; jika tidak tersedia, kembalikan "Vehicle is not available"; jika tidak, atur state kendaraan ke RentedState dan kembalikan object Rental baru
    • setMaintenance(string $plate): string: mengatur state kendaraan ke MaintenanceState; kembalikan "[plate] set to maintenance" atau "Vehicle not found"
  • main.php: Sertakan file RentalService dan Customer. Kamu akan menerima tiga input: data armada (JSON), data pelanggan (JSON), dan operasi (JSON).

    Format JSON armada:

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

    Format JSON pelanggan:

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

    Format JSON operasi:

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

    Buat layanan penyewaan, tambahkan semua kendaraan ke armada, dan buat pelanggan. Lacak penyewaan aktif berdasarkan nomor pelat. Proses setiap operasi:

    • "available": Cetak "Available vehicles: [count]"
    • "rent": Sewa kendaraan; jika berhasil, simpan Rental dan cetak "Rented [plate] for [days] days"; jika kendaraannya Van, sertakan miles dari operasi; jika tidak, cetak pesan error
    • "complete": Selesaikan penyewaan tersimpan untuk nomor pelat tersebut; cetak hasilnya
    • "maintenance": Cetak hasil dari setMaintenance()
    • "status": Cetak "[plate]: [status]" untuk nomor pelat yang diberikan
    • "customer_stats": Cetak "[name]: [count] rentals, $[total] spent" (2 angka desimal)

    Cetak setiap hasil pada baris baru.

Sistem ini menunjukkan bagaimana pola State menangani ketersediaan kendaraan dengan rapi tanpa percabangan yang rumit, bagaimana inheritance membentuk hierarki kendaraan yang jelas dengan penetapan harga polimorfik, serta bagaimana enkapsulasi melindungi integritas data penyewaan selama seluruh alur kerja.

Coba sendiri

<?php

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

// Baca input
$fleetJson = trim(fgets(STDIN));
$customerJson = trim(fgets(STDIN));
$operationsJson = trim(fgets(STDIN));

// Uraikan data JSON
$fleetData = (array)json_decode($fleetJson, true);
$customerData = (array)json_decode($customerJson, true);
$operations = (array)json_decode($operationsJson, true);

// TODO: Buat instance RentalService

// TODO: Tambahkan semua kendaraan ke armada berdasarkan jenisnya:
// - "car" -> new Car(plate, brand, rate)
// - "motorcycle" -> new Motorcycle(plate, brand, rate)
// - "van" -> new Van(plate, brand, rate, mileage_rate)

// TODO: Buat instance Customer dari customerData

// TODO: Buat array untuk melacak penyewaan aktif berdasarkan plate
$activeRentals = [];

// TODO: Proses setiap operasi dan cetak hasilnya:
// - "available": Cetak "Available vehicles: [count]"
// - "rent": Sewakan kendaraan, simpan Rental jika berhasil, lalu cetak hasilnya
// - "complete": Selesaikan penyewaan, lalu cetak hasilnya
// - "maintenance": Atur status perawatan, lalu cetak hasilnya
// - "status": Cetak "[plate]: [status]"
// - "customer_stats": Cetak "[name]: [count] rentals, $[total] spent"

foreach ($operations as $op) {
    $operation = (array)$op;
    $opType = $operation['op'];
    
    // TODO: Tangani setiap jenis operasi
    switch ($opType) {
        case 'available':
            // TODO: Cetak jumlah kendaraan yang tersedia
            break;
        case 'rent':
            // TODO: Sewakan kendaraan dan cetak hasilnya
            break;
        case 'complete':
            // TODO: Selesaikan penyewaan dan cetak hasilnya
            break;
        case 'maintenance':
            // TODO: Atur status perawatan dan cetak hasilnya
            break;
        case 'status':
            // TODO: Cetak status kendaraan
            break;
        case 'customer_stats':
            // TODO: Cetak statistik pelanggan
            break;
    }
}

?>

Semua pelajaran di Pemrograman Berorientasi Objek

Latihan sendiri: Compiler PHP online