Menu
Coddy logo textTech
flag Ar iconالعربيةdown icon

خدمة تأجير المركبات

جزء من قسم Object Oriented Programming في رحلة C# على Coddy — الدرس 70 من 70.

challenge icon

التحدي

سهل

لنقم ببناء خدمة تأجير مركبات تجمع بين الوراثة (Inheritance)، والواجهات (Interfaces)، ونمط الاستراتيجية (Strategy pattern)! ستقوم بإنشاء نظام حيث يمكن استئجار أنواع مختلفة من المركبات باستخدام استراتيجيات تسعير مرنة - مما يوضح كيف تمكن البرمجة كائنية التوجه (OOP) من بناء منطق أعمال قابل للصيانة والتوسع.

ستقوم بتنظيم الكود الخاص بك عبر ستة ملفات:

  • Vehicle.cs: أنشئ هيكل المركبات الخاص بك في مساحة الأسماء Rental.Models. يجب أن تحتوي الفئة الأساسية Vehicle على خصائص للقراءة فقط وهي LicensePlate و Brand، و DailyRate (decimal)، وخاصية IsAvailable مع تعيين خاص (private setter) يتم التحكم فيه من خلال طريقتي MarkAsRented() و MarkAsReturned(). ثم أنشئ ثلاث فئات مشتقة: Car مع خاصية Seats، و Motorcycle مع خاصية EngineCC، و Truck مع خاصية CargoCapacity (decimal). يجب أن تستدعي كل فئة مشتقة منشئ الفئة الأساسية وتعين خاصيتها الفريدة.
  • IPricingStrategy.cs: حدد واجهة IPricingStrategy في مساحة الأسماء Rental.Pricing مع طريقة واحدة CalculatePrice(Vehicle vehicle, int days) تعيد قيمة من نوع decimal.
  • PricingStrategies.cs: قم بتنفيذ استراتيجيتين للتسعير في مساحة الأسماء Rental.Pricing. تقوم StandardPricing ببساطة بضرب السعر اليومي للمركبة في عدد الأيام. أما WeekendDiscountPricing فتطبق خصمًا بنسبة 10% (الضرب في 0.9) إذا كان الإيجار لمدة يومين أو أكثر، وإلا فإنها تستخدم الحساب القياسي.
  • RentalRecord.cs: أنشئ فئة Rental في مساحة الأسماء Rental.Models لتتبع عمليات التأجير. يجب أن تحتوي على خصائص للقراءة فقط لـ CustomerName (string)، و Vehicle (Vehicle)، و Days (int)، و TotalPrice (decimal)، ويتم تعيينها جميعًا من خلال المنشئ.
  • RentalService.cs: أنشئ فئة RentalService في مساحة الأسماء Rental.Services التي تدير الأسطول وتعالج عمليات التأجير. تستقبل هذه الفئة IPricingStrategy من خلال منشئها (حقن التبعية - dependency injection). قم بتنفيذ ما يلي:
    • AddVehicle(Vehicle vehicle) - يضيف مركبة إلى الأسطول.
    • RentVehicle(string customerName, string licensePlate, int days) - يعيد كائن Rental إذا كانت المركبة موجودة ومتاحة، وإلا يعيد null. تذكر أن تضع علامة على المركبة كمؤجرة وتحسب السعر باستخدام الاستراتيجية المحقونة.
    • ReturnVehicle(string licensePlate) - يضع علامة على المركبة كمتاحة، ويعيد true إذا نجحت العملية.
    • GetAvailableVehicles() - يعيد قائمة بجميع المركبات المتاحة.
  • Program.cs: اجمع كل شيء معًا عن طريق إنشاء المركبات، وإعداد الخدمة باستراتيجية تسعير، ومعالجة عمليات التأجير بناءً على المدخلات.

ستتلقى المدخلات التالية:

  • استراتيجية التسعير المراد استخدامها (standard أو weekend)
  • عدد المركبات المراد إضافتها
  • لكل مركبة: النوع (car، أو motorcycle، أو truck)، ورقم اللوحة، والعلامة التجارية، والسعر اليومي، والقيمة الخاصة بالنوع (المقاعد، أو سعة المحرك، أو سعة الشحن)
  • عدد العمليات المراد تنفيذها
  • لكل عملية: الإجراء متبوعًا بالبيانات ذات الصلة

تنسيقات العمليات:

rent
{customerName}
{licensePlate}
{days}

return
{licensePlate}

available

تنسيقات المخرجات:

  • نجاح التأجير: Rented: {Brand} ({LicensePlate}) to {CustomerName} for {Days} days - Total: {TotalPrice}
  • فشل التأجير: Rental failed: {licensePlate}
  • نجاح الإرجاع: Returned: {licensePlate}
  • فشل الإرجاع: Return failed: {licensePlate}
  • المتاحة: اطبع كل مركبة متاحة كـ {Type}: {Brand} ({LicensePlate}) - {DailyRate}/day حيث يكون النوع "Car" أو "Motorcycle" أو "Truck"

على سبيل المثال، إذا كانت المدخلات هي:

weekend
3
car
ABC-123
Toyota
50
5
motorcycle
XYZ-789
Honda
30
600
truck
TRK-001
Ford
80
2000
5
available
rent
Alice
ABC-123
3
rent
Bob
ABC-123
2
available
return
ABC-123

يجب أن تكون المخرجات:

Car: Toyota (ABC-123) - 50/day
Motorcycle: Honda (XYZ-789) - 30/day
Truck: Ford (TRK-001) - 80/day
Rented: Toyota (ABC-123) to Alice for 3 days - Total: 135
Rental failed: ABC-123
Motorcycle: Honda (XYZ-789) - 30/day
Truck: Ford (TRK-001) - 80/day
Returned: ABC-123

لاحظ كيف يتم حقن استراتيجية التسعير في الخدمة - يمكنك بسهولة استبدال StandardPricing بـ WeekendDiscountPricing دون تغيير كود RentalService على الإطلاق. هذه هي قوة نمط الاستراتيجية مدمجًا مع حقن التبعية!

جرّب بنفسك

using System;
using System.Collections.Generic;
using Rental.Models;
using Rental.Pricing;
using Rental.Services;

class Program
{
    public static void Main(string[] args)
    {
        // قراءة نوع استراتيجية التسعير
        string strategyType = Console.ReadLine();
        
        // TODO: إنشاء استراتيجية التسعير المناسبة بناءً على المدخلات
        // "standard" -> StandardPricing
        // "weekend" -> WeekendDiscountPricing
        IPricingStrategy strategy = null; // TODO: التهيئة بناءً على strategyType
        
        // TODO: إنشاء RentalService مع استراتيجية التسعير
        
        // قراءة عدد المركبات
        int vehicleCount = Convert.ToInt32(Console.ReadLine());
        
        // TODO: قراءة وإضافة كل مركبة إلى الخدمة
        // لكل مركبة، اقرأ:
        // - النوع (car، motorcycle، truck)
        // - رقم اللوحة (license plate)
        // - العلامة التجارية (brand)
        // - السعر اليومي (daily rate)
        // - القيمة الخاصة بالنوع (seats، engineCC، أو cargo capacity)
        
        // قراءة عدد العمليات
        int operationCount = Convert.ToInt32(Console.ReadLine());
        
        // TODO: معالجة كل عملية
        // العمليات: rent، return، available
        // 
        // بالنسبة لـ "rent":
        //   قراءة customerName، licensePlate، days
        //   المخرجات: "Rented: {Brand} ({LicensePlate}) to {CustomerName} for {Days} days - Total: {TotalPrice}"
        //   أو: "Rental failed: {licensePlate}"
        //
        // بالنسبة لـ "return":
        //   قراءة licensePlate
        //   المخرجات: "Returned: {licensePlate}" أو "Return failed: {licensePlate}"
        //
        // بالنسبة لـ "available":
        //   إخراج كل مركبة متاحة كـ:
        //   "{Type}: {Brand} ({LicensePlate}) - {DailyRate}/day"
    }
}

جميع دروس Object Oriented Programming