خدمة تأجير المركبات
جزء من قسم Object Oriented Programming في رحلة C# على Coddy — الدرس 70 من 70.
التحدي
سهللنقم ببناء خدمة تأجير مركبات تجمع بين الوراثة (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
1أساسيات OOP
الملفات الخارجيةNamespaces والتوجيهاتمقدمة في Classes و Objectsالكلمة المفتاحية 'this'Methods والمعاملاتFields مقابل PropertiesConstructorsObject Initializersمراجعة - آلة حاسبة بسيطة4الوراثة
صيغة الوراثة الأساسية (:)الكلمة المفتاحية 'base'الكلمات المفتاحية Virtual و Overrideالأصناف المختومة (Sealed Classes)الفئة الأساسية 'object'مراجعة - هيكلية الموظفين7ميزات متقدمة
تحميل العوامل (Operator Overloading)المفهرسات (Indexers (this[]))إعادة تعريف ()ToStringدوال التوسعة (Extension Methods)ملخص - Custom List2الخصائص والأعضاء الساكنة (Static Members)
الخصائص المطبقة تلقائيًا (Auto-Implemented Properties)خصائص القراءة فقط والكتابة فقطالحقول والدوال الساكنة (Static)الفئات الساكنة (Static Classes)الأعضاء ذات البنية التعبيرية (Expression-Bodied Members)5تعدد الأشكال والواجهات (Polymorphism & Interfaces)
تعدد الأشكال: وقت التجميع مقابل وقت التشغيلالواجهة مقابل الفئة المجردة (Abstract Class)الواجهات المتعددةالواجهات الصريحةUpcasting و Downcastingملخص - حاسبة الأشكال8مفاهيم البرمجة كائنية التوجه (OOP) المتقدمة
التركيب بدلاً من الوراثةالـ Generics (الأصناف والدوال)الـ Delegates والأحداثالـ Attributes والـ Reflectionواجهة IDisposable وجملة usingأساسيات Dependency Injection