خدمة تأجير المركبات
جزء من قسم Object Oriented Programming في رحلة Dart على Coddy — الدرس 110 من 110.
التحدي
سهلتهانينا على وصولك إلى التحدي النهائي في دورة البرمجة كائنية التوجه (OOP)! لنقم ببناء خدمة تأجير مركبات (Vehicle Rental Service) شاملة تجمع كل ما تعلمته - الفئات المجردة (abstract classes)، الوراثة (inheritance)، التغليف (encapsulation)، نمط الحالة (State pattern)، نمط المصنع (Factory pattern)، والأنواع العامة (generics).
ستقوم خدمة التأجير الخاصة بك بإدارة أنواع مختلفة من المركبات، وتتبع حالات توفرها، ومعالجة عمليات التأجير، والاحتفاظ بسجلات العملاء. ستقوم بتنظيم ذلك عبر سبعة ملفات:
vehicle_state.dart: أنشئ فئة مجردة باسمVehicleStateتحدد كيف تتصرف المركبات في حالات مختلفة. قم بتضمين تابع مجردString getStatus()وbool canRent(). ثم أنشئ ثلاث حالات ملموسة (concrete states):AvailableState- تعيدAvailableوتسمح بالتأجير.RentedState- تعيدRentedولا تسمح بالتأجير.MaintenanceState- تعيدIn Maintenanceولا تسمح بالتأجير.
vehicle.dart: أنشئ فئة مجردة باسمVehicleتحتوي على معرفfinalid (String)، وطرازfinalmodel (String)، ومعدل يومي خاص_dailyRate(double) مع تابع جلب (getter)، وحالة خاصة_state(VehicleState) يتم تهيئتها بـAvailableState. قم بتضمين:- تابع جلب
statusيعيد حالة الحالة الحالية. bool isAvailable()- يتحقق مما إذا كانت الحالة الحالية تسمح بالتأجير.void setState(VehicleState state)- يغير حالة المركبة.- تابع مجرد
double calculateRentalCost(int days). - تابع مجرد
String getRequirements()- يعيد أي متطلبات خاصة.
toString()لتعيد[Type] model (id) - statusحيث Type هو نوع وقت التشغيل (runtime type).- تابع جلب
vehicles.dart: أنشئ ثلاثة أنواع من المركبات ترث منVehicle:Car- تكلفة التأجير القياسية هي المعدل اليومي مضروباً في عدد الأيام. المتطلبات:Valid driver's licenseMotorcycle- تكلفة التأجير هي المعدل اليومي مضروباً في عدد الأيام مع خصم 10%. المتطلبات:Motorcycle license, Age 21+Truck- تكلفة التأجير هي المعدل اليومي مضروباً في عدد الأيام بالإضافة إلى رسوم ثابتة قدرها 50 دولاراً. المتطلبات:Commercial license, Deposit required
vehicle_factory.dart: أنشئ فئةVehicleFactoryمع تابع ثابتVehicle create(String type, String id, String model, double dailyRate)يعيد المركبة المناسبة بناءً على النوع (car،motorcycle، أوtruck). بالنسبة للأنواع غير المعروفة، اجعل الافتراضي هو إنشاءCar.customer.dart: أنشئ فئةCustomerتحتوي على id (String)، واسم name (String)، وقائمة خاصة من سجلات التأجير (قائمة من Strings). قم بتضمين:addRental(String vehicleInfo)- يضيف سجل تأجير.getRentalCount()- يعيد عدد عمليات التأجير.bool isEligible()- يعيد true إذا كان لدى العميل أقل من 3 عمليات تأجير نشطة.
toString()لتعيدCustomer: name (id) - X rentals.rental_service.dart: أنشئ فئةRentalServiceباستخدام الأنواع العامة (generics) معList<Vehicle>للأسطول وList<Customer>للعملاء. قم بتضمين:addVehicle(Vehicle vehicle)- يضيف للمسطول، ويطبعAdded: vehicle.toString()registerCustomer(Customer customer)- يسجل العميل.rentVehicle(String customerId, String vehicleId, int days)- إذا كان العميل موجوداً، ومؤهلاً، وكانت المركبة متاحة: يغير حالة المركبة إلى Rented، ويضيف التأجير للعميل، ويطبعcustomerId rented vehicleId for X days. Cost: $Y(Y منسقة إلى منزلتين عشريتين). خلاف ذلك، اطبع الرسالة المناسبة:Customer not found،Customer not eligible،Vehicle not found، أوVehicle not availablereturnVehicle(String vehicleId)- يضبط حالة المركبة إلى Available، ويطبعvehicleId returnedsendToMaintenance(String vehicleId)- يضبط حالة المركبة إلى Maintenance، ويطبعvehicleId sent to maintenancegetAvailableVehicles()- يعيد قائمة بالمركبات المتاحة.
main.dart: استعرض خدمة التأجير الخاصة بك. أنشئRentalServiceواستخدم المصنع (factory) لإضافة ثلاث مركبات:- سيارة:
V001،Toyota Camry، $45/اليوم - دراجة نارية:
V002،Honda CBR، $35/اليوم - شاحنة:
V003،Ford F-150، $75/اليوم
C001،Alice Johnson) واطبع بيانات العميل. اطبع متطلبات الشاحنة. قم بتأجير السيارة لـ Alice لمدة 3 أيام. حاول تأجير السيارة مرة أخرى (يجب أن يفشل). أرسل الدراجة النارية للصيانة. اطبع عدد المركبات المتاحة بتنسيقAvailable vehicles: X. قم بإعادة السيارة. اطبع العدد النهائي للمركبات المتاحة.- سيارة:
المخرجات المتوقعة:
Added: [Car] Toyota Camry (V001) - Available
Added: [Motorcycle] Honda CBR (V002) - Available
Added: [Truck] Ford F-150 (V003) - Available
Customer: Alice Johnson (C001) - 0 rentals
Commercial license, Deposit required
C001 rented V001 for 3 days. Cost: $135.00
Vehicle not available
V002 sent to maintenance
Available vehicles: 1
V001 returned
Available vehicles: 2جرّب بنفسك
import 'rental_service.dart';
import 'vehicle_factory.dart';
import 'customer.dart';
void main() {
// TODO: إنشاء مثيل (instance) من RentalService
// TODO: استخدام VehicleFactory لإنشاء وإضافة ثلاث مركبات:
// - Car: V001, Toyota Camry, $45/day
// - Motorcycle: V002, Honda CBR, $35/day
// - Truck: V003, Ford F-150, $75/day
// TODO: تسجيل عميل (C001, Alice Johnson)
// TODO: طباعة بيانات العميل
// TODO: طباعة متطلبات الشاحنة (ابحث عن الشاحنة واستدعِ getRequirements())
// TODO: تأجير السيارة (V001) لـ Alice (C001) لمدة 3 أيام
// TODO: محاولة تأجير السيارة مرة أخرى (يجب أن تفشل - غير متاحة)
// TODO: إرسال الدراجة النارية (V002) للصيانة
// TODO: طباعة عدد المركبات المتاحة بصيغة 'Available vehicles: X'
// TODO: إرجاع السيارة (V001)
// TODO: طباعة العدد النهائي للمركبات المتاحة
}
جميع دروس Object Oriented Programming
1أساسيات الـ OOP
الملفات الخارجيةالمكتبات والـ Importsمقدمة في الـ OOPالـ Classes مقابل الـ Objectsالكلمة المفتاحية thisالـ Methodsمتغيرات الـ Instanceأساسيات الـ Constructorمراجعة - آلة حاسبة بسيطة4أمان الـ Null
مقدمة في أمان الـ NullNullable مقابل Non-Nullableعاملا الـ ? و !الكلمة المفتاحية Late وأمان الـ Nullالعوامل المدركة للـ Nullأمان الـ Null في الـ Classesمراجعة - نظام ملف تعريف المستخدم7الفئات المجردة والواجهات
الفئات المجردةالدوال المجردةالواجهات في Dartالواجهات الضمنيةالتنفيذ مقابل التوسيعالواجهات المتعددةمراجعة - حاسبة الأشكال10المجموعات والأنماط العامة
نظرة عامة على List و Set و Mapالمجموعات آمنة النوعالفئات العامةالدوال العامةقيود الأنماط العامةIterable و Iteratorملخص - التخزين العام13مفاهيم OOP المتقدمة
التركيب مقابل الوراثة (Composition vs Inheritance)دوال التوسعة (Extension Methods)الأصناف القابلة للاستدعاء (Callable Classes)الأصناف المختومة (Sealed Classes - Dart 3)السجلات (Records - Dart 3)الأنماط والمطابقة (Patterns & Matching - 3.0)التعدادات مع الدوال (Enums with Methods)2المنشئات في Dart
المنشئ الافتراضيالمنشئات المسماةقوائم التهيئةالمنشئات الثابتةالمنشئات المصنعيةالمنشئات الموجهةملخص - بناء الأشكال5التغليف (Encapsulation)
الأعضاء العامة مقابل الخاصةاتفاقية البادئة _الخصوصية على مستوى المكتبةتعمق في Getters و Settersإخفاء المعلوماتمراجعة - سجلات الطلاب8Mixins
مقدمة إلى Mixinsإنشاء Mixinsاستخدام Mixins متعددةالكلمة المفتاحية on في MixinsMixin مقابل الوراثة (Inheritance)Mixin مقابل الواجهة (Interface)مراجعة - نظام الحيوانات (Animal System)3خصائص الـ Class
أعضاء الـ Instance مقابل الـ Staticحقول Final و Constمتغيرات Lateالـ Static Methods والحقولدوال الـ Getters والـ Settersمراجعة - مدير الحساب البنكي6الوراثة
أساسيات الوراثةالكلمة المفتاحية superإعادة تعريف الدوال (Method Overriding)الوسم @overrideالكلمة المفتاحية final Classالدوال البانية والوراثةمراجعة - هيكلية الموظفين9تعدد الأشكال
أساسيات تعدد الأشكالتعدد الأشكال عبر الـ Interfacesالتحقق من النوع أثناء التشغيلالمعاملات is و asالكلمة المفتاحية Covariantملخص - معالج الدفع12البرمجة الكائنية غير المتزامنة (Async OOP)
Futures و async/awaitأساسيات الـ Streamsمتحكمات الـ Streamsالـ Constructors غير المتزامنةالعمليات غير المتزامنة في دوال الكلاسمراجعة - جالب البيانات (Data Fetcher)15أنماط التصميم - الجزء الثاني
نمط الأمرنمط المحولنمط المزيننمط طريقة القالبنمط الحالةنمط التركيبنمط المستودع